Functioning DNS udp forwarding.

git-svn-id: file:///svn/unbound/trunk@59 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-02-02 13:44:00 +00:00
parent b968590e00
commit fe87dd7b52
4 changed files with 59 additions and 11 deletions

View file

@ -54,13 +54,47 @@
/** timeout in seconds for UDP queries to auth servers. TODO: proper rtt */ /** timeout in seconds for UDP queries to auth servers. TODO: proper rtt */
#define UDP_QUERY_TIMEOUT 5 #define UDP_QUERY_TIMEOUT 5
/** the size of ID and flags, opcode, rcode in dns packet */
#define ID_AND_FLAGS 4
/** reply to query with given error code */
static void replyerror(int r, struct worker* worker)
{
LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
LDNS_RCODE_SET(ldns_buffer_begin(worker->query_reply.c->buffer), r);
comm_point_send_reply(&worker->query_reply);
worker->num_requests --;
}
/** process incoming replies from the network */
static int worker_handle_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* ATTR_UNUSED(reply_info))
{
struct worker* worker = (struct worker*)arg;
if(error != 0) {
replyerror(LDNS_RCODE_SERVFAIL, worker);
return 0;
}
/* woohoo a reply! */
ldns_buffer_clear(worker->query_reply.c->buffer);
ldns_buffer_skip(worker->query_reply.c->buffer, ID_AND_FLAGS);
ldns_buffer_write(worker->query_reply.c->buffer,
ldns_buffer_at(c->buffer, ID_AND_FLAGS),
ldns_buffer_limit(c->buffer) - ID_AND_FLAGS);
LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
ldns_buffer_flip(worker->query_reply.c->buffer);
comm_point_send_reply(&worker->query_reply);
worker->num_requests --;
return 0;
}
/** 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,
&worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT); &worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT,
worker_handle_reply, worker);
} }
/** check request sanity. Returns error code, 0 OK, or -1 discard. /** check request sanity. Returns error code, 0 OK, or -1 discard.
@ -117,6 +151,7 @@ static int worker_handle_request(struct comm_point* c, void* arg, int error,
} }
if((ret=worker_check_request(c->buffer)) != 0) { if((ret=worker_check_request(c->buffer)) != 0) {
if(ret != -1) { if(ret != -1) {
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret); LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
return 1; return 1;
} }

View file

@ -5,6 +5,7 @@
- listens on both ip4 and ip6 ports to provide correct return address. - listens on both ip4 and ip6 ports to provide correct return address.
- worker fwder address filled correctly. - worker fwder address filled correctly.
- fixup timer code. - fixup timer code.
- forwards udp queries and sends answer.
1 February 2007: Wouter 1 February 2007: Wouter
- outside network more UDP work. - outside network more UDP work.

View file

@ -106,9 +106,8 @@ static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
return 0; return 0;
} }
comm_timer_disable(p->timer); comm_timer_disable(p->timer);
/* TODO handle it */
log_info("outnet handle udp reply"); log_info("outnet handle udp reply");
(void)(*p->cb)(p->c, p->cb_arg, 0, NULL);
return 0; return 0;
} }
@ -225,9 +224,10 @@ 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 . TODO handle it. */ /* it timed out */
log_info("timeout udp"); log_info("timeout udp");
(void)(*p->cb)(p->c, p->cb_arg, -2, NULL);
} }
struct outside_network* struct outside_network*
@ -344,7 +344,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p)
/** create a new pending item with given characteristics, false on failure */ /** create a new pending item with given characteristics, false on failure */
static struct pending* static struct pending*
new_pending(struct outside_network* outnet, ldns_buffer* packet, new_pending(struct outside_network* outnet, ldns_buffer* packet,
struct sockaddr_storage* addr, socklen_t addrlen) struct sockaddr_storage* addr, socklen_t addrlen,
comm_point_callback_t* callback, void* callback_arg)
{ {
/* alloc */ /* alloc */
int id_tries = 0; int id_tries = 0;
@ -364,6 +365,8 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
pend->id = LDNS_ID_WIRE(ldns_buffer_begin(packet)); pend->id = LDNS_ID_WIRE(ldns_buffer_begin(packet));
memcpy(&pend->addr, addr, addrlen); memcpy(&pend->addr, addr, addrlen);
pend->addrlen = addrlen; pend->addrlen = addrlen;
pend->cb = callback;
pend->cb_arg = callback_arg;
/* insert in tree */ /* insert in tree */
pend->node.key = pend; pend->node.key = pend;
@ -436,14 +439,16 @@ 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)
{ {
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 possibly change ID to be unique) */
if(!(pend=new_pending(outnet, packet, addr, addrlen))) { 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, -1, NULL);
return; return;
} }
select_port(outnet, pend); select_port(outnet, pend);
@ -454,6 +459,7 @@ void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
/* error, call error callback function */ /* error, call error callback function */
pending_delete(outnet, pend); pending_delete(outnet, pend);
/* callback user for the error */ /* callback user for the error */
(void)(*pend->cb)(pend->c, pend->cb_arg, -1, NULL);
return; return;
} }

View file

@ -45,10 +45,9 @@
#include "config.h" #include "config.h"
#include "util/rbtree.h" #include "util/rbtree.h"
#include "util/netevent.h"
struct pending; struct pending;
struct pending_timeout; struct pending_timeout;
struct comm_point;
struct comm_base;
/** /**
* Send queries to outside servers and wait for answers from servers. * Send queries to outside servers and wait for answers from servers.
@ -97,6 +96,10 @@ struct pending {
struct comm_point* c; struct comm_point* c;
/** timeout event */ /** timeout event */
struct comm_timer* timer; struct comm_timer* timer;
/** callback for the timeout, error or reply to the message */
comm_point_callback_t* cb;
/** callback user argument */
void* cb_arg;
}; };
/** /**
@ -129,9 +132,12 @@ void outside_network_delete(struct outside_network* outnet);
* @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_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,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout); struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
comm_point_callback_t* callback, void* callback_arg);
/** /**
* Delete pending answer. * Delete pending answer.