mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-19 08:03:28 +00:00
Merge pull request #4639 from opensourcerouting/c-ares-lib
make c-ares DNS resolver available as lib
This commit is contained in:
commit
c682502cd7
@ -1560,7 +1560,7 @@ if test "${NHRPD}" != ""; then
|
||||
AC_MSG_ERROR([trying to build nhrpd, but libcares not found. install c-ares and its -dev headers.])
|
||||
])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([CARES], [test "${NHRPD}" != ""])
|
||||
|
||||
dnl ------------------
|
||||
dnl check Net-SNMP library
|
||||
|
1
debian/frr.install
vendored
1
debian/frr.install
vendored
@ -2,6 +2,7 @@ etc/
|
||||
usr/bin/vtysh
|
||||
usr/bin/mtracebis
|
||||
usr/lib/*/frr/libfrr.*
|
||||
usr/lib/*/frr/libfrrcares.*
|
||||
usr/lib/*/frr/libfrrospfapiclient.*
|
||||
usr/lib/frr/*.sh
|
||||
usr/lib/frr/*d
|
||||
|
@ -85,6 +85,7 @@ const char *node_names[] = {
|
||||
"northbound debug", // NORTHBOUND_DEBUG_NODE,
|
||||
"vnc debug", // DEBUG_VNC_NODE,
|
||||
"route-map debug", /* RMAP_DEBUG_NODE */
|
||||
"resolver debug", /* RESOLVER_DEBUG_NODE */
|
||||
"aaa", // AAA_NODE,
|
||||
"keychain", // KEYCHAIN_NODE,
|
||||
"keychain key", // KEYCHAIN_KEY_NODE,
|
||||
|
@ -94,6 +94,7 @@ enum node_type {
|
||||
NORTHBOUND_DEBUG_NODE, /* Northbound Debug node. */
|
||||
DEBUG_VNC_NODE, /* Debug VNC node. */
|
||||
RMAP_DEBUG_NODE, /* Route-map debug node */
|
||||
RESOLVER_DEBUG_NODE, /* Resolver debug node */
|
||||
AAA_NODE, /* AAA node. */
|
||||
KEYCHAIN_NODE, /* Key-chain node. */
|
||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||
|
@ -356,6 +356,12 @@ static struct log_ref ferr_lib_err[] = {
|
||||
.description = "A callback used to process a configuration change has returned an error while applying the changes",
|
||||
.suggestion = "Gather log data and open an Issue.",
|
||||
},
|
||||
{
|
||||
.code = EC_LIB_RESOLVER,
|
||||
.title = "DNS Resolution",
|
||||
.description = "An error was detected while attempting to resolve a hostname",
|
||||
.suggestion = "Ensure that DNS is working properly and the hostname is configured in dns. If you are still seeing this error, open an issue"
|
||||
},
|
||||
{
|
||||
.code = END_FERR,
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ enum lib_log_refs {
|
||||
EC_LIB_GRPC_INIT,
|
||||
EC_LIB_ID_CONSISTENCY,
|
||||
EC_LIB_ID_EXHAUST,
|
||||
EC_LIB_RESOLVER,
|
||||
};
|
||||
|
||||
extern void lib_error_init(void);
|
||||
|
@ -17,17 +17,18 @@
|
||||
#include "vector.h"
|
||||
#include "thread.h"
|
||||
#include "lib_errors.h"
|
||||
|
||||
#include "nhrpd.h"
|
||||
#include "nhrp_errors.h"
|
||||
#include "resolver.h"
|
||||
#include "command.h"
|
||||
|
||||
struct resolver_state {
|
||||
ares_channel channel;
|
||||
struct thread_master *master;
|
||||
struct thread *timeout;
|
||||
vector read_threads, write_threads;
|
||||
};
|
||||
|
||||
static struct resolver_state state;
|
||||
static bool resolver_debug;
|
||||
|
||||
#define THREAD_RUNNING ((struct thread *)-1)
|
||||
|
||||
@ -54,7 +55,8 @@ static int resolver_cb_socket_readable(struct thread *t)
|
||||
ares_process_fd(r->channel, fd, ARES_SOCKET_BAD);
|
||||
if (vector_lookup(r->read_threads, fd) == THREAD_RUNNING) {
|
||||
t = NULL;
|
||||
thread_add_read(master, resolver_cb_socket_readable, r, fd, &t);
|
||||
thread_add_read(r->master, resolver_cb_socket_readable, r, fd,
|
||||
&t);
|
||||
vector_set_index(r->read_threads, fd, t);
|
||||
}
|
||||
resolver_update_timeouts(r);
|
||||
@ -71,7 +73,7 @@ static int resolver_cb_socket_writable(struct thread *t)
|
||||
ares_process_fd(r->channel, ARES_SOCKET_BAD, fd);
|
||||
if (vector_lookup(r->write_threads, fd) == THREAD_RUNNING) {
|
||||
t = NULL;
|
||||
thread_add_write(master, resolver_cb_socket_writable, r, fd,
|
||||
thread_add_write(r->master, resolver_cb_socket_writable, r, fd,
|
||||
&t);
|
||||
vector_set_index(r->write_threads, fd, t);
|
||||
}
|
||||
@ -91,8 +93,8 @@ static void resolver_update_timeouts(struct resolver_state *r)
|
||||
tv = ares_timeout(r->channel, NULL, &tvbuf);
|
||||
if (tv) {
|
||||
unsigned int timeoutms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
|
||||
thread_add_timer_msec(master, resolver_cb_timeout, r, timeoutms,
|
||||
&r->timeout);
|
||||
thread_add_timer_msec(r->master, resolver_cb_timeout, r,
|
||||
timeoutms, &r->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,8 +107,8 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
|
||||
if (readable) {
|
||||
t = vector_lookup_ensure(r->read_threads, fd);
|
||||
if (!t) {
|
||||
thread_add_read(master, resolver_cb_socket_readable, r,
|
||||
fd, &t);
|
||||
thread_add_read(r->master, resolver_cb_socket_readable,
|
||||
r, fd, &t);
|
||||
vector_set_index(r->read_threads, fd, t);
|
||||
}
|
||||
} else {
|
||||
@ -122,8 +124,8 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
|
||||
if (writable) {
|
||||
t = vector_lookup_ensure(r->write_threads, fd);
|
||||
if (!t) {
|
||||
thread_add_read(master, resolver_cb_socket_writable, r,
|
||||
fd, &t);
|
||||
thread_add_read(r->master, resolver_cb_socket_writable,
|
||||
r, fd, &t);
|
||||
vector_set_index(r->write_threads, fd, t);
|
||||
}
|
||||
} else {
|
||||
@ -137,37 +139,23 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
|
||||
}
|
||||
}
|
||||
|
||||
void resolver_init(void)
|
||||
{
|
||||
struct ares_options ares_opts;
|
||||
|
||||
state.read_threads = vector_init(1);
|
||||
state.write_threads = vector_init(1);
|
||||
|
||||
ares_opts = (struct ares_options){
|
||||
.sock_state_cb = &ares_socket_cb,
|
||||
.sock_state_cb_data = &state,
|
||||
.timeout = 2,
|
||||
.tries = 3,
|
||||
};
|
||||
|
||||
ares_init_options(&state.channel, &ares_opts,
|
||||
ARES_OPT_SOCK_STATE_CB | ARES_OPT_TIMEOUT
|
||||
| ARES_OPT_TRIES);
|
||||
}
|
||||
|
||||
|
||||
static void ares_address_cb(void *arg, int status, int timeouts,
|
||||
struct hostent *he)
|
||||
{
|
||||
struct resolver_query *query = (struct resolver_query *)arg;
|
||||
union sockunion addr[16];
|
||||
void (*callback)(struct resolver_query *, int, union sockunion *);
|
||||
size_t i;
|
||||
|
||||
callback = query->callback;
|
||||
query->callback = NULL;
|
||||
|
||||
if (status != ARES_SUCCESS) {
|
||||
debugf(NHRP_DEBUG_COMMON, "[%p] Resolving failed", query);
|
||||
query->callback(query, -1, NULL);
|
||||
query->callback = NULL;
|
||||
if (resolver_debug)
|
||||
zlog_debug("[%p] Resolving failed", query);
|
||||
|
||||
callback(query, -1, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -186,10 +174,10 @@ static void ares_address_cb(void *arg, int status, int timeouts,
|
||||
}
|
||||
}
|
||||
|
||||
debugf(NHRP_DEBUG_COMMON, "[%p] Resolved with %d results", query,
|
||||
(int)i);
|
||||
query->callback(query, i, &addr[0]);
|
||||
query->callback = NULL;
|
||||
if (resolver_debug)
|
||||
zlog_debug("[%p] Resolved with %d results", query, (int)i);
|
||||
|
||||
callback(query, i, &addr[0]);
|
||||
}
|
||||
|
||||
void resolver_resolve(struct resolver_query *query, int af,
|
||||
@ -199,15 +187,61 @@ void resolver_resolve(struct resolver_query *query, int af,
|
||||
{
|
||||
if (query->callback != NULL) {
|
||||
flog_err(
|
||||
EC_NHRP_RESOLVER,
|
||||
EC_LIB_RESOLVER,
|
||||
"Trying to resolve '%s', but previous query was not finished yet",
|
||||
hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
debugf(NHRP_DEBUG_COMMON, "[%p] Resolving '%s'", query, hostname);
|
||||
if (resolver_debug)
|
||||
zlog_debug("[%p] Resolving '%s'", query, hostname);
|
||||
|
||||
query->callback = callback;
|
||||
ares_gethostbyname(state.channel, hostname, af, ares_address_cb, query);
|
||||
resolver_update_timeouts(&state);
|
||||
}
|
||||
|
||||
DEFUN(debug_resolver,
|
||||
debug_resolver_cmd,
|
||||
"[no] debug resolver",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
"Debug DNS resolver actions\n")
|
||||
{
|
||||
resolver_debug = (argc == 2);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_node resolver_debug_node = {RESOLVER_DEBUG_NODE, "", 1};
|
||||
|
||||
static int resolver_config_write_debug(struct vty *vty)
|
||||
{
|
||||
if (resolver_debug)
|
||||
vty_out(vty, "debug resolver\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void resolver_init(struct thread_master *tm)
|
||||
{
|
||||
struct ares_options ares_opts;
|
||||
|
||||
state.master = tm;
|
||||
state.read_threads = vector_init(1);
|
||||
state.write_threads = vector_init(1);
|
||||
|
||||
ares_opts = (struct ares_options){
|
||||
.sock_state_cb = &ares_socket_cb,
|
||||
.sock_state_cb_data = &state,
|
||||
.timeout = 2,
|
||||
.tries = 3,
|
||||
};
|
||||
|
||||
ares_init_options(&state.channel, &ares_opts,
|
||||
ARES_OPT_SOCK_STATE_CB | ARES_OPT_TIMEOUT
|
||||
| ARES_OPT_TRIES);
|
||||
|
||||
install_node(&resolver_debug_node, resolver_config_write_debug);
|
||||
install_element(CONFIG_NODE, &debug_resolver_cmd);
|
||||
install_element(ENABLE_NODE, &debug_resolver_cmd);
|
||||
}
|
25
lib/resolver.h
Normal file
25
lib/resolver.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* C-Ares integration to Quagga mainloop
|
||||
* Copyright (c) 2014-2015 Timo Teräs
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _FRR_RESOLVER_H
|
||||
#define _FRR_RESOLVER_H
|
||||
|
||||
#include "thread.h"
|
||||
#include "sockunion.h"
|
||||
|
||||
struct resolver_query {
|
||||
void (*callback)(struct resolver_query *, int n, union sockunion *);
|
||||
};
|
||||
|
||||
void resolver_init(struct thread_master *tm);
|
||||
void resolver_resolve(struct resolver_query *query, int af,
|
||||
const char *hostname, void (*cb)(struct resolver_query *,
|
||||
int, union sockunion *));
|
||||
|
||||
#endif /* _FRR_RESOLVER_H */
|
@ -285,6 +285,21 @@ lib_libfrrsnmp_la_SOURCES = \
|
||||
lib/snmp.c \
|
||||
# end
|
||||
|
||||
#
|
||||
# c-ares support
|
||||
#
|
||||
if CARES
|
||||
lib_LTLIBRARIES += lib/libfrrcares.la
|
||||
pkginclude_HEADERS += lib/resolver.h
|
||||
endif
|
||||
|
||||
lib_libfrrcares_la_CFLAGS = $(WERROR) $(CARES_CFLAGS)
|
||||
lib_libfrrcares_la_LDFLAGS = -version-info 0:0:0
|
||||
lib_libfrrcares_la_LIBADD = $(CARES_LIBS)
|
||||
lib_libfrrcares_la_SOURCES = \
|
||||
lib/resolver.c \
|
||||
#end
|
||||
|
||||
#
|
||||
# ZeroMQ support
|
||||
#
|
||||
|
@ -31,12 +31,6 @@ static struct log_ref ferr_nhrp_err[] = {
|
||||
.description = "NHRP has detected a error with the Strongswan code",
|
||||
.suggestion = "Ensure that StrongSwan is configured correctly. Restart StrongSwan and FRR"
|
||||
},
|
||||
{
|
||||
.code = EC_NHRP_RESOLVER,
|
||||
.title = "NHRP DNS Resolution",
|
||||
.description = "NHRP has detected an error in an attempt to resolve a hostname",
|
||||
.suggestion = "Ensure that DNS is working properly and the hostname is configured in dns. If you are still seeing this error, open an issue"
|
||||
},
|
||||
{
|
||||
.code = END_FERR,
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
enum nhrp_log_refs {
|
||||
EC_NHRP_SWAN = NHRP_FERR_START,
|
||||
EC_NHRP_RESOLVER,
|
||||
};
|
||||
|
||||
extern void nhrp_error_init(void);
|
||||
|
@ -141,7 +141,7 @@ int main(int argc, char **argv)
|
||||
nhrp_error_init();
|
||||
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||
nhrp_interface_init();
|
||||
resolver_init();
|
||||
resolver_init(master);
|
||||
|
||||
/* Run with elevated capabilities, as for all netlink activity
|
||||
* we need privileges anyway. */
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "zclient.h"
|
||||
#include "debug.h"
|
||||
#include "memory.h"
|
||||
#include "resolver.h"
|
||||
|
||||
DECLARE_MGROUP(NHRPD)
|
||||
|
||||
@ -84,15 +85,6 @@ static inline int notifier_active(struct notifier_list *l)
|
||||
return !list_empty(&l->notifier_head);
|
||||
}
|
||||
|
||||
struct resolver_query {
|
||||
void (*callback)(struct resolver_query *, int n, union sockunion *);
|
||||
};
|
||||
|
||||
void resolver_init(void);
|
||||
void resolver_resolve(struct resolver_query *query, int af,
|
||||
const char *hostname, void (*cb)(struct resolver_query *,
|
||||
int, union sockunion *));
|
||||
|
||||
void nhrp_zebra_init(void);
|
||||
void nhrp_zebra_terminate(void);
|
||||
|
||||
|
@ -8,8 +8,7 @@ vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
|
||||
man8 += $(MANBUILD)/nhrpd.8
|
||||
endif
|
||||
|
||||
nhrpd_nhrpd_LDADD = lib/libfrr.la $(LIBCAP) $(CARES_LIBS)
|
||||
nhrpd_nhrpd_CFLAGS = $(AM_CFLAGS) $(CARES_CFLAGS)
|
||||
nhrpd_nhrpd_LDADD = lib/libfrr.la lib/libfrrcares.la $(LIBCAP)
|
||||
nhrpd_nhrpd_SOURCES = \
|
||||
nhrpd/linux.c \
|
||||
nhrpd/netlink_arp.c \
|
||||
@ -27,7 +26,6 @@ nhrpd_nhrpd_SOURCES = \
|
||||
nhrpd/nhrp_vc.c \
|
||||
nhrpd/nhrp_vty.c \
|
||||
nhrpd/reqid.c \
|
||||
nhrpd/resolver.c \
|
||||
nhrpd/vici.c \
|
||||
nhrpd/zbuf.c \
|
||||
nhrpd/znl.c \
|
||||
|
@ -377,6 +377,9 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
strlen("debug route-map"))
|
||||
== 0)
|
||||
config = config_get(RMAP_DEBUG_NODE, line);
|
||||
else if (strncmp(line, "debug resolver",
|
||||
strlen("debug resolver")) == 0)
|
||||
config = config_get(RESOLVER_DEBUG_NODE, line);
|
||||
else if (strncmp(line, "debug", strlen("debug")) == 0)
|
||||
config = config_get(DEBUG_NODE, line);
|
||||
else if (strncmp(line, "password", strlen("password")) == 0
|
||||
@ -423,7 +426,7 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
|| (I) == PREFIX_IPV6_NODE || (I) == FORWARDING_NODE \
|
||||
|| (I) == DEBUG_NODE || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE \
|
||||
|| (I) == NORTHBOUND_DEBUG_NODE || (I) == RMAP_DEBUG_NODE \
|
||||
|| (I) == MPLS_NODE)
|
||||
|| (I) == RESOLVER_DEBUG_NODE || (I) == MPLS_NODE)
|
||||
|
||||
/* Display configuration to file pointer. */
|
||||
void vtysh_config_dump(void)
|
||||
|
Loading…
Reference in New Issue
Block a user