]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Functioning DNS udp forwarding.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 2 Feb 2007 13:44:00 +0000 (13:44 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 2 Feb 2007 13:44:00 +0000 (13:44 +0000)
git-svn-id: file:///svn/unbound/trunk@59 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
doc/Changelog
services/outside_network.c
services/outside_network.h

index f676e497a52f79203ec9ce6e85e4ea6029337ea4..bb83e73b17e75a6daf03a492e98ffef8702c33b1 100644 (file)
 
 /** timeout in seconds for UDP queries to auth servers. TODO: proper rtt */
 #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 */
 static void worker_process_query(struct worker* worker) 
 {
        /* query the forwarding address */
        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. 
@@ -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 != -1) {
+                       LDNS_QR_SET(ldns_buffer_begin(c->buffer));
                        LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
                        return 1;
                }
index 2cf55294a0aac17f186fc7b2bae1814eaa957129..58f2e3f0f1ab2ff0f23006a945cb0113bac02e38 100644 (file)
@@ -5,6 +5,7 @@
        - listens on both ip4 and ip6 ports to provide correct return address.
        - worker fwder address filled correctly.
        - fixup timer code.
+       - forwards udp queries and sends answer.
 
 1 February 2007: Wouter
        - outside network more UDP work.
index 41f98d77a908ab503f56a4cfd329b58353374803..d2ef6e9e2936126e46b07be8b3308e5edf0481b8 100644 (file)
@@ -106,9 +106,8 @@ static int outnet_udp_cb(struct comm_point* c, void* arg, int error,
                return 0;
        }
        comm_timer_disable(p->timer);
-       /* TODO handle it */
        log_info("outnet handle udp reply");
-
+       (void)(*p->cb)(p->c, p->cb_arg, 0, NULL);
        return 0;
 }
 
@@ -225,9 +224,10 @@ static void calc_num46(const char** ifs, int num_ifs,
 /** callback for udp timeout */
 static void pending_udp_timer_cb(void *arg)
 {
-       /* struct pending* p = (struct pending*)arg; */
-       /* it timed out . TODO handle it. */
+       struct pending* p = (struct pending*)arg;
+       /* it timed out */
        log_info("timeout udp");
+       (void)(*p->cb)(p->c, p->cb_arg, -2, NULL);
 }
 
 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 */
 static struct pending*
 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 */
        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));
        memcpy(&pend->addr, addr, addrlen);
        pend->addrlen = addrlen;
+       pend->cb = callback;
+       pend->cb_arg = callback_arg;
 
        /* insert in tree */
        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, 
-       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 timeval tv;
 
        /* 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 */
+               (void)(*cb)(NULL, cb_arg, -1, NULL);
                return;
        }
        select_port(outnet, pend);
@@ -454,6 +459,7 @@ void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
                /* error, call error callback function */
                pending_delete(outnet, pend);
                /* callback user for the error */
+               (void)(*pend->cb)(pend->c, pend->cb_arg, -1, NULL);
                return;
        }
 
index 1176877d0a086ef1b999a05725ca63bcdcd46f51..4659238dbb72ca031d22829984d0bedd28145b76 100644 (file)
 
 #include "config.h"
 #include "util/rbtree.h"
+#include "util/netevent.h"
 struct pending;
 struct pending_timeout;
-struct comm_point;
-struct comm_base;
 
 /**
  * Send queries to outside servers and wait for answers from servers.
@@ -97,6 +96,10 @@ struct pending {
        struct comm_point* c;
        /** timeout event */
        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 addrlen: length of addr.
  * @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, 
-       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.