mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
review of services, daemon and testcode.
git-svn-id: file:///svn/unbound/trunk@70 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
74ec9e6553
commit
d8cbd99dc1
9 changed files with 85 additions and 63 deletions
|
|
@ -51,15 +51,15 @@
|
||||||
static void usage()
|
static void usage()
|
||||||
{
|
{
|
||||||
printf("usage: unbound [options]\n");
|
printf("usage: unbound [options]\n");
|
||||||
printf("\tstart unbound daemon DNS resolver.\n");
|
printf(" start unbound daemon DNS resolver.\n");
|
||||||
printf("-h this help\n");
|
printf("-h this help\n");
|
||||||
printf("-p port the port to listen on\n");
|
printf("-p port the port to listen on\n");
|
||||||
printf("-v verbose (multiple times increase verbosity)\n");
|
printf("-v verbose (multiple times increase verbosity)\n");
|
||||||
printf("-f ip set forwarder address\n");
|
printf("-f ip set forwarder address\n");
|
||||||
printf("-z port set forwarder port\n");
|
printf("-z port set forwarder port\n");
|
||||||
printf("Version %s\n", PACKAGE_VERSION);
|
printf("Version %s\n", PACKAGE_VERSION);
|
||||||
printf("BSD licensed, see LICENSE file in source package.\n");
|
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||||
printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);
|
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** getopt global, in case header files fail to declare it. */
|
/** getopt global, in case header files fail to declare it. */
|
||||||
|
|
@ -71,6 +71,7 @@ extern char* optarg;
|
||||||
* main program. Set options given commandline arguments.
|
* main program. Set options given commandline arguments.
|
||||||
* @param argc: number of commandline arguments.
|
* @param argc: number of commandline arguments.
|
||||||
* @param argv: array of commandline arguments.
|
* @param argv: array of commandline arguments.
|
||||||
|
* @return: exit status of the program.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
main(int argc, char* argv[])
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@
|
||||||
#define ID_AND_FLAGS 4
|
#define ID_AND_FLAGS 4
|
||||||
|
|
||||||
/** reply to query with given error code */
|
/** reply to query with given error code */
|
||||||
static void replyerror(int r, struct worker* worker)
|
static void
|
||||||
|
replyerror(int r, struct worker* worker)
|
||||||
{
|
{
|
||||||
LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
|
LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
|
||||||
LDNS_RCODE_SET(ldns_buffer_begin(worker->query_reply.c->buffer), r);
|
LDNS_RCODE_SET(ldns_buffer_begin(worker->query_reply.c->buffer), r);
|
||||||
|
|
@ -68,7 +69,8 @@ static void replyerror(int r, struct worker* worker)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** process incoming replies from the network */
|
/** process incoming replies from the network */
|
||||||
static int worker_handle_reply(struct comm_point* c, void* arg, int error,
|
static int
|
||||||
|
worker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply* ATTR_UNUSED(reply_info))
|
struct comm_reply* ATTR_UNUSED(reply_info))
|
||||||
{
|
{
|
||||||
struct worker* worker = (struct worker*)arg;
|
struct worker* worker = (struct worker*)arg;
|
||||||
|
|
@ -90,7 +92,8 @@ static int worker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** process incoming request */
|
/** process incoming request */
|
||||||
static void worker_process_query(struct worker* worker)
|
static void
|
||||||
|
worker_process_query(struct worker* worker)
|
||||||
{
|
{
|
||||||
/* query the forwarding address */
|
/* query the forwarding address */
|
||||||
pending_udp_query(worker->back, worker->query_reply.c->buffer,
|
pending_udp_query(worker->back, worker->query_reply.c->buffer,
|
||||||
|
|
@ -101,7 +104,8 @@ static void worker_process_query(struct worker* worker)
|
||||||
/** check request sanity. Returns error code, 0 OK, or -1 discard.
|
/** check request sanity. Returns error code, 0 OK, or -1 discard.
|
||||||
* @param pkt: the wire packet to examine for sanity.
|
* @param pkt: the wire packet to examine for sanity.
|
||||||
*/
|
*/
|
||||||
static int worker_check_request(ldns_buffer* pkt)
|
static int
|
||||||
|
worker_check_request(ldns_buffer* pkt)
|
||||||
{
|
{
|
||||||
if(ldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
|
if(ldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
|
||||||
verbose(VERB_DETAIL, "request too short, discarded");
|
verbose(VERB_DETAIL, "request too short, discarded");
|
||||||
|
|
@ -140,13 +144,14 @@ static int worker_check_request(ldns_buffer* pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** handles callbacks from listening event interface */
|
/** handles callbacks from listening event interface */
|
||||||
static int worker_handle_request(struct comm_point* c, void* arg, int error,
|
static int
|
||||||
|
worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply* repinfo)
|
struct comm_reply* repinfo)
|
||||||
{
|
{
|
||||||
struct worker* worker = (struct worker*)arg;
|
struct worker* worker = (struct worker*)arg;
|
||||||
int ret;
|
int ret;
|
||||||
log_info("worker handle request");
|
log_info("worker handle request");
|
||||||
if(error != 0) {
|
if(error != NETEVENT_NOERROR) {
|
||||||
log_err("called with err=%d", error);
|
log_err("called with err=%d", error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +176,8 @@ static int worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** worker signal callback */
|
/** worker signal callback */
|
||||||
void worker_sighandler(int sig, void* arg)
|
void
|
||||||
|
worker_sighandler(int sig, void* arg)
|
||||||
{
|
{
|
||||||
/* note that log, print, syscalls here give race conditions. */
|
/* note that log, print, syscalls here give race conditions. */
|
||||||
struct worker* worker = (struct worker*)arg;
|
struct worker* worker = (struct worker*)arg;
|
||||||
|
|
@ -194,9 +200,9 @@ void worker_sighandler(int sig, void* arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct worker* worker_init(const char* port, int do_ip4, int do_ip6,
|
struct worker*
|
||||||
int do_udp, int do_tcp, size_t buffer_size, size_t numports,
|
worker_init(const char* port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
|
||||||
int base_port)
|
size_t buffer_size, size_t numports, int base_port)
|
||||||
{
|
{
|
||||||
struct worker* worker = (struct worker*)calloc(1,
|
struct worker* worker = (struct worker*)calloc(1,
|
||||||
sizeof(struct worker));
|
sizeof(struct worker));
|
||||||
|
|
@ -221,14 +227,15 @@ struct worker* worker_init(const char* port, int do_ip4, int do_ip6,
|
||||||
do_ip4, do_ip6, do_udp, do_tcp, buffer_size,
|
do_ip4, do_ip6, do_udp, do_tcp, buffer_size,
|
||||||
worker_handle_request, worker);
|
worker_handle_request, worker);
|
||||||
if(!worker->front) {
|
if(!worker->front) {
|
||||||
worker_delete(worker);
|
|
||||||
log_err("could not create listening sockets");
|
log_err("could not create listening sockets");
|
||||||
|
worker_delete(worker);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
worker->back = outside_network_create(worker->base,
|
worker->back = outside_network_create(worker->base,
|
||||||
buffer_size, numports, NULL, 0, do_ip4, do_ip6, base_port);
|
buffer_size, numports, NULL, 0, do_ip4, do_ip6, base_port);
|
||||||
if(!worker->back) {
|
if(!worker->back) {
|
||||||
log_err("could not create outgoing sockets");
|
log_err("could not create outgoing sockets");
|
||||||
|
worker_delete(worker);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* init random(), large table size. */
|
/* init random(), large table size. */
|
||||||
|
|
@ -240,12 +247,14 @@ struct worker* worker_init(const char* port, int do_ip4, int do_ip6,
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
void worker_work(struct worker* worker)
|
void
|
||||||
|
worker_work(struct worker* worker)
|
||||||
{
|
{
|
||||||
comm_base_dispatch(worker->base);
|
comm_base_dispatch(worker->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void worker_delete(struct worker* worker)
|
void
|
||||||
|
worker_delete(struct worker* worker)
|
||||||
{
|
{
|
||||||
if(!worker)
|
if(!worker)
|
||||||
return;
|
return;
|
||||||
|
|
@ -256,7 +265,8 @@ void worker_delete(struct worker* worker)
|
||||||
free(worker);
|
free(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
int worker_set_fwd(struct worker* worker, const char* ip, const char* port)
|
int
|
||||||
|
worker_set_fwd(struct worker* worker, const char* ip, const char* port)
|
||||||
{
|
{
|
||||||
uint16_t p;
|
uint16_t p;
|
||||||
log_assert(worker && ip);
|
log_assert(worker && ip);
|
||||||
|
|
|
||||||
|
|
@ -58,30 +58,25 @@ struct outside_network;
|
||||||
struct worker {
|
struct worker {
|
||||||
/** the event base this worker works with */
|
/** the event base this worker works with */
|
||||||
struct comm_base* base;
|
struct comm_base* base;
|
||||||
|
|
||||||
/** the frontside listening interface where request events come in */
|
/** the frontside listening interface where request events come in */
|
||||||
struct listen_dnsport* front;
|
struct listen_dnsport* front;
|
||||||
|
|
||||||
/** the backside outside network interface to the auth servers */
|
/** the backside outside network interface to the auth servers */
|
||||||
struct outside_network* back;
|
struct outside_network* back;
|
||||||
|
/** the signal handler */
|
||||||
/** our one and only query, packet buffer and where to send. */
|
struct comm_signal *comsig;
|
||||||
struct comm_reply query_reply;
|
|
||||||
|
|
||||||
/** number of requests currently active */
|
/** number of requests currently active */
|
||||||
int num_requests;
|
int num_requests;
|
||||||
|
/** our one and only query, packet buffer and where to send. */
|
||||||
/** random() table for this worker. */
|
struct comm_reply query_reply;
|
||||||
char rndstate[RND_STATE_SIZE];
|
|
||||||
|
|
||||||
/** address to forward to */
|
/** address to forward to */
|
||||||
struct sockaddr_storage fwd_addr;
|
struct sockaddr_storage fwd_addr;
|
||||||
|
|
||||||
/** length of fwd_addr */
|
/** length of fwd_addr */
|
||||||
socklen_t fwd_addrlen;
|
socklen_t fwd_addrlen;
|
||||||
|
|
||||||
/** the signal handler */
|
/** random() table for this worker. */
|
||||||
struct comm_signal *comsig;
|
char rndstate[RND_STATE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
/** number of queued TCP connections for listen() */
|
/** number of queued TCP connections for listen() */
|
||||||
#define TCP_BACKLOG 5
|
#define TCP_BACKLOG 5
|
||||||
/** number of simultaneous open TCP connections */
|
/** number of simultaneous open TCP connections for queries */
|
||||||
#define TCP_COUNT 10
|
#define TCP_COUNT 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -258,6 +258,7 @@ listen_create_if(const char* ifname, struct listen_dnsport* front,
|
||||||
if(!cp_tcp) {
|
if(!cp_tcp) {
|
||||||
log_err("can't create commpoint");
|
log_err("can't create commpoint");
|
||||||
comm_point_delete(cp_udp);
|
comm_point_delete(cp_udp);
|
||||||
|
close(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -306,12 +307,10 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
|
||||||
|
|
||||||
/* getaddrinfo */
|
/* getaddrinfo */
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
/* no name lookups on our listening ports */
|
/* no name lookups on our listening ports */
|
||||||
if(num_ifs > 0)
|
if(num_ifs > 0)
|
||||||
hints.ai_flags |= AI_NUMERICHOST;
|
hints.ai_flags |= AI_NUMERICHOST;
|
||||||
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
if(!do_ip4 && !do_ip6) {
|
if(!do_ip4 && !do_ip6) {
|
||||||
listen_delete(front);
|
listen_delete(front);
|
||||||
|
|
@ -382,4 +381,3 @@ listen_delete(struct listen_dnsport* front)
|
||||||
ldns_buffer_free(front->udp_buff);
|
ldns_buffer_free(front->udp_buff);
|
||||||
free(front);
|
free(front);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,6 @@ struct listen_dnsport* listen_create(struct comm_base* base,
|
||||||
*/
|
*/
|
||||||
void listen_delete(struct listen_dnsport* listen);
|
void listen_delete(struct listen_dnsport* listen);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and bind nonblocking UDP socket
|
* Create and bind nonblocking UDP socket
|
||||||
* @param addr: address info ready to make socket.
|
* @param addr: address info ready to make socket.
|
||||||
|
|
@ -110,5 +109,4 @@ void listen_delete(struct listen_dnsport* listen);
|
||||||
*/
|
*/
|
||||||
int create_udp_sock(struct addrinfo* addr);
|
int create_udp_sock(struct addrinfo* addr);
|
||||||
|
|
||||||
|
|
||||||
#endif /* LISTEN_DNSPORT_H */
|
#endif /* LISTEN_DNSPORT_H */
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@
|
||||||
#define MAX_ID_RETRY 1000
|
#define MAX_ID_RETRY 1000
|
||||||
|
|
||||||
/** compare function of pending rbtree */
|
/** compare function of pending rbtree */
|
||||||
static int pending_cmp(const void* key1, const void* key2)
|
static int
|
||||||
|
pending_cmp(const void* key1, const void* key2)
|
||||||
{
|
{
|
||||||
struct pending *p1 = (struct pending*)key1;
|
struct pending *p1 = (struct pending*)key1;
|
||||||
struct pending *p2 = (struct pending*)key2;
|
struct pending *p2 = (struct pending*)key2;
|
||||||
|
|
@ -74,7 +75,8 @@ static int pending_cmp(const void* key1, const void* key2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** callback for incoming udp answers from the network. */
|
/** callback for incoming udp answers from the network. */
|
||||||
static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
static int
|
||||||
|
outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply *reply_info)
|
struct comm_reply *reply_info)
|
||||||
{
|
{
|
||||||
struct outside_network* outnet = (struct outside_network*)arg;
|
struct outside_network* outnet = (struct outside_network*)arg;
|
||||||
|
|
@ -82,7 +84,7 @@ static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
struct pending* p;
|
struct pending* p;
|
||||||
log_info("answer cb");
|
log_info("answer cb");
|
||||||
|
|
||||||
if(error != 0) {
|
if(error != NETEVENT_NOERROR) {
|
||||||
log_info("outnetudp got udp error %d", error);
|
log_info("outnetudp got udp error %d", error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -93,16 +95,17 @@ static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
|
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
|
||||||
key.addrlen = reply_info->addrlen;
|
key.addrlen = reply_info->addrlen;
|
||||||
|
|
||||||
/* find it, see if this thing is a valid query */
|
/* find it, see if this thing is a valid query response */
|
||||||
p = (struct pending*)rbtree_search(outnet->pending, &key);
|
p = (struct pending*)rbtree_search(outnet->pending, &key);
|
||||||
if(!p) {
|
if(!p) {
|
||||||
verbose(VERB_DETAIL, "received uncalled udp reply. dropped.");
|
verbose(VERB_DETAIL, "received unsolicited udp reply. dropped.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
verbose(VERB_ALGO, "received udp reply.");
|
verbose(VERB_ALGO, "received udp reply.");
|
||||||
if(p->c != c) {
|
if(p->c != c) {
|
||||||
verbose(VERB_DETAIL, "received answer on wrong port. dropped");
|
verbose(VERB_DETAIL, "received reply id,addr on wrong port. "
|
||||||
|
"dropped.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
comm_timer_disable(p->timer);
|
comm_timer_disable(p->timer);
|
||||||
|
|
@ -118,8 +121,8 @@ static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
* @param porthint: if not -1, it gives the port to base range on.
|
* @param porthint: if not -1, it gives the port to base range on.
|
||||||
* @return: file descriptor
|
* @return: file descriptor
|
||||||
*/
|
*/
|
||||||
static int open_udp_port_range(const char* ifname, struct addrinfo* hints,
|
static int
|
||||||
int porthint)
|
open_udp_port_range(const char* ifname, struct addrinfo* hints, int porthint)
|
||||||
{
|
{
|
||||||
struct addrinfo *res = NULL;
|
struct addrinfo *res = NULL;
|
||||||
int r, s;
|
int r, s;
|
||||||
|
|
@ -186,7 +189,8 @@ make_udp_range(struct comm_point** coms, const char* ifname,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns true is string addr is an ip6 specced address. */
|
/** returns true is string addr is an ip6 specced address. */
|
||||||
int str_is_ip6(const char* str)
|
int
|
||||||
|
str_is_ip6(const char* str)
|
||||||
{
|
{
|
||||||
if(strchr(str, ':'))
|
if(strchr(str, ':'))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -194,9 +198,9 @@ int str_is_ip6(const char* str)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** calculate number of ip4 and ip6 interfaces, times multiplier. */
|
/** calculate number of ip4 and ip6 interfaces, times multiplier. */
|
||||||
static void calc_num46(const char** ifs, int num_ifs,
|
static void
|
||||||
int do_ip4, int do_ip6, size_t multiplier,
|
calc_num46(const char** ifs, int num_ifs, int do_ip4, int do_ip6,
|
||||||
size_t* num_ip4, size_t* num_ip6)
|
size_t multiplier, size_t* num_ip4, size_t* num_ip6)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
*num_ip4 = 0;
|
*num_ip4 = 0;
|
||||||
|
|
@ -222,7 +226,8 @@ static void calc_num46(const char** ifs, int num_ifs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** callback for udp timeout */
|
/** callback for udp timeout */
|
||||||
static void pending_udp_timer_cb(void *arg)
|
static void
|
||||||
|
pending_udp_timer_cb(void *arg)
|
||||||
{
|
{
|
||||||
struct pending* p = (struct pending*)arg;
|
struct pending* p = (struct pending*)arg;
|
||||||
/* it timed out */
|
/* it timed out */
|
||||||
|
|
@ -245,6 +250,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||||
outnet->base = base;
|
outnet->base = base;
|
||||||
calc_num46(ifs, num_ifs, do_ip4, do_ip6, num_ports,
|
calc_num46(ifs, num_ifs, do_ip4, do_ip6, num_ports,
|
||||||
&outnet->num_udp4, &outnet->num_udp6);
|
&outnet->num_udp4, &outnet->num_udp6);
|
||||||
|
/* adds +1 to portnums so we do not allocate zero bytes. */
|
||||||
if( !(outnet->udp_buff = ldns_buffer_new(bufsize)) ||
|
if( !(outnet->udp_buff = ldns_buffer_new(bufsize)) ||
|
||||||
!(outnet->udp4_ports = (struct comm_point **)calloc(
|
!(outnet->udp4_ports = (struct comm_point **)calloc(
|
||||||
outnet->num_udp4+1, sizeof(struct comm_point*))) ||
|
outnet->num_udp4+1, sizeof(struct comm_point*))) ||
|
||||||
|
|
@ -297,7 +303,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||||
return outnet;
|
return outnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void outside_network_delete(struct outside_network* outnet)
|
void
|
||||||
|
outside_network_delete(struct outside_network* outnet)
|
||||||
{
|
{
|
||||||
if(!outnet)
|
if(!outnet)
|
||||||
return;
|
return;
|
||||||
|
|
@ -329,7 +336,8 @@ void outside_network_delete(struct outside_network* outnet)
|
||||||
free(outnet);
|
free(outnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pending_delete(struct outside_network* outnet, struct pending* p)
|
void
|
||||||
|
pending_delete(struct outside_network* outnet, struct pending* p)
|
||||||
{
|
{
|
||||||
if(!p)
|
if(!p)
|
||||||
return;
|
return;
|
||||||
|
|
@ -362,7 +370,9 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* set */
|
/* set */
|
||||||
pend->id = LDNS_ID_WIRE(ldns_buffer_begin(packet));
|
/* id uses lousy random() TODO use better and entropy */
|
||||||
|
pend->id = (random()>>8) & 0xffff;
|
||||||
|
LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
|
||||||
memcpy(&pend->addr, addr, addrlen);
|
memcpy(&pend->addr, addr, addrlen);
|
||||||
pend->addrlen = addrlen;
|
pend->addrlen = addrlen;
|
||||||
pend->cb = callback;
|
pend->cb = callback;
|
||||||
|
|
@ -389,7 +399,8 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
* @param addr: the sockaddr to examine.
|
* @param addr: the sockaddr to examine.
|
||||||
* return: true if sockaddr is ip6.
|
* return: true if sockaddr is ip6.
|
||||||
*/
|
*/
|
||||||
static int addr_is_ip6(struct sockaddr_storage* addr)
|
static int
|
||||||
|
addr_is_ip6(struct sockaddr_storage* addr)
|
||||||
{
|
{
|
||||||
short family = *(short*)addr;
|
short family = *(short*)addr;
|
||||||
if(family == AF_INET6)
|
if(family == AF_INET6)
|
||||||
|
|
@ -402,7 +413,8 @@ static int addr_is_ip6(struct sockaddr_storage* addr)
|
||||||
* @param outnet: network structure that has arrays of ports to choose from.
|
* @param outnet: network structure that has arrays of ports to choose from.
|
||||||
* @param pend: the message to send. c is filled in, randomly chosen.
|
* @param pend: the message to send. c is filled in, randomly chosen.
|
||||||
*/
|
*/
|
||||||
static void select_port(struct outside_network* outnet, struct pending* pend)
|
static void
|
||||||
|
select_port(struct outside_network* outnet, struct pending* pend)
|
||||||
{
|
{
|
||||||
double precho;
|
double precho;
|
||||||
int chosen, nummax;
|
int chosen, nummax;
|
||||||
|
|
@ -438,14 +450,15 @@ static void select_port(struct outside_network* outnet, struct pending* pend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
void
|
||||||
|
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||||
comm_point_callback_t* cb, void* cb_arg)
|
comm_point_callback_t* cb, void* cb_arg)
|
||||||
{
|
{
|
||||||
struct pending* pend;
|
struct pending* pend;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
/* create pending struct (and possibly change ID to be unique) */
|
/* create pending struct and change ID to be unique */
|
||||||
if(!(pend=new_pending(outnet, packet, addr, addrlen, cb, cb_arg))) {
|
if(!(pend=new_pending(outnet, packet, addr, addrlen, cb, cb_arg))) {
|
||||||
/* callback user for the error */
|
/* callback user for the error */
|
||||||
(void)(*cb)(NULL, cb_arg, NETEVENT_CLOSED, NULL);
|
(void)(*cb)(NULL, cb_arg, NETEVENT_CLOSED, NULL);
|
||||||
|
|
@ -456,10 +469,9 @@ void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
/* send it over the commlink */
|
/* send it over the commlink */
|
||||||
if(!comm_point_send_udp_msg(pend->c, packet, (struct sockaddr*)addr,
|
if(!comm_point_send_udp_msg(pend->c, packet, (struct sockaddr*)addr,
|
||||||
addrlen)) {
|
addrlen)) {
|
||||||
/* error, call error callback function */
|
|
||||||
pending_delete(outnet, pend);
|
|
||||||
/* callback user for the error */
|
/* callback user for the error */
|
||||||
(void)(*pend->cb)(pend->c, pend->cb_arg, NETEVENT_CLOSED, NULL);
|
(void)(*pend->cb)(pend->c, pend->cb_arg, NETEVENT_CLOSED, NULL);
|
||||||
|
pending_delete(outnet, pend);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,13 @@ struct pending {
|
||||||
* @param bufsize: size for network buffers.
|
* @param bufsize: size for network buffers.
|
||||||
* @param num_ports: number of udp ports to open per interface.
|
* @param num_ports: number of udp ports to open per interface.
|
||||||
* @param ifs: interface names (or NULL for default interface).
|
* @param ifs: interface names (or NULL for default interface).
|
||||||
|
* These interfaces must be able to access all authoritative servers.
|
||||||
* @param num_ifs: number of names in array ifs.
|
* @param num_ifs: number of names in array ifs.
|
||||||
* @param do_ip4: service IP4.
|
* @param do_ip4: service IP4.
|
||||||
* @param do_ip6: service IP6.
|
* @param do_ip6: service IP6.
|
||||||
* @param port_base: if -1 system assigns ports, otherwise try to get
|
* @param port_base: if -1 system assigns ports, otherwise try to get
|
||||||
* the ports numbered from this starting number.
|
* the ports numbered from this starting number.
|
||||||
* @return: the new empty structure or NULL on error.
|
* @return: the new structure (with no pending answers) or NULL on error.
|
||||||
*/
|
*/
|
||||||
struct outside_network* outside_network_create(struct comm_base* base,
|
struct outside_network* outside_network_create(struct comm_base* base,
|
||||||
size_t bufsize, size_t num_ports, const char** ifs, int num_ifs,
|
size_t bufsize, size_t num_ports, const char** ifs, int num_ifs,
|
||||||
|
|
@ -127,12 +128,15 @@ void outside_network_delete(struct outside_network* outnet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send UDP query, create pending answer.
|
* Send UDP query, create pending answer.
|
||||||
|
* Changes the ID for the query to be random and unique for that destination.
|
||||||
* @param outnet: provides the event handling
|
* @param outnet: provides the event handling
|
||||||
* @param packet: wireformat query to send to destination.
|
* @param packet: wireformat query to send to destination.
|
||||||
* @param addr: address to send to.
|
* @param addr: address to send to.
|
||||||
* @param addrlen: length of addr.
|
* @param addrlen: length of addr.
|
||||||
* @param timeout: in seconds from now.
|
* @param timeout: in seconds from now.
|
||||||
* @param callback: function to call on error, timeout or reply.
|
* @param callback: function to call on error, timeout or reply.
|
||||||
|
* The routine does not return an error, instead it calls the callback,
|
||||||
|
* with an error code if an error happens.
|
||||||
* @param callback_arg: user argument for callback function.
|
* @param callback_arg: user argument for callback function.
|
||||||
*/
|
*/
|
||||||
void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
|
|
@ -142,7 +146,7 @@ void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
/**
|
/**
|
||||||
* Delete pending answer.
|
* Delete pending answer.
|
||||||
* @param outnet: outside network the pending query is part of.
|
* @param outnet: outside network the pending query is part of.
|
||||||
* Used internal, if NULL, p is not unlinked from rbtree.
|
* Internal feature: if outnet is NULL, p is not unlinked from rbtree.
|
||||||
* @param p: deleted
|
* @param p: deleted
|
||||||
*/
|
*/
|
||||||
void pending_delete(struct outside_network* outnet, struct pending* p);
|
void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||||
|
|
@ -150,7 +154,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||||
/**
|
/**
|
||||||
* See if string is ip4 or ip6.
|
* See if string is ip4 or ip6.
|
||||||
* @param str: IP specification.
|
* @param str: IP specification.
|
||||||
* @return: true is string addr is an ip6 specced address.
|
* @return: true if string addr is an ip6 specced address.
|
||||||
*/
|
*/
|
||||||
int str_is_ip6(const char* str);
|
int str_is_ip6(const char* str);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ add_opts(char* optarg, int* pass_argc, char* pass_argv[])
|
||||||
else len = strlen(p);
|
else len = strlen(p);
|
||||||
/* allocate and copy option */
|
/* allocate and copy option */
|
||||||
if(*pass_argc >= MAXARG-1) {
|
if(*pass_argc >= MAXARG-1) {
|
||||||
|
/* printf because log_init is not yet called. */
|
||||||
printf("too many arguments: '%s'\n", p);
|
printf("too many arguments: '%s'\n", p);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +122,8 @@ echo_cmdline(int argc, char* argv[])
|
||||||
* @param argc: arg count.
|
* @param argc: arg count.
|
||||||
* @param argv: array of commandline arguments.
|
* @param argv: array of commandline arguments.
|
||||||
*/
|
*/
|
||||||
int main(int argc, char* argv[])
|
int
|
||||||
|
main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int c, res;
|
int c, res;
|
||||||
int pass_argc = 0;
|
int pass_argc = 0;
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@ int testcount = 0;
|
||||||
/** test bool x, exits on failure, increases testcount. */
|
/** test bool x, exits on failure, increases testcount. */
|
||||||
#define unit_assert(x) testcount++; log_assert(x);
|
#define unit_assert(x) testcount++; log_assert(x);
|
||||||
|
|
||||||
/** test net code */
|
|
||||||
#include "services/outside_network.h"
|
#include "services/outside_network.h"
|
||||||
static void net_test()
|
/** test net code */
|
||||||
|
static void
|
||||||
|
net_test()
|
||||||
{
|
{
|
||||||
unit_assert( str_is_ip6("::") );
|
unit_assert( str_is_ip6("::") );
|
||||||
unit_assert( str_is_ip6("::1") );
|
unit_assert( str_is_ip6("::1") );
|
||||||
|
|
@ -66,7 +67,8 @@ static void net_test()
|
||||||
* @param argc: arg count.
|
* @param argc: arg count.
|
||||||
* @param argv: array of commandline arguments.
|
* @param argv: array of commandline arguments.
|
||||||
*/
|
*/
|
||||||
int main(int argc, char* argv[])
|
int
|
||||||
|
main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc != 1) {
|
if(argc != 1) {
|
||||||
printf("usage: %s\n", argv[0]);
|
printf("usage: %s\n", argv[0]);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue