]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
duplicate query callbacks work.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 20 Jun 2007 14:01:58 +0000 (14:01 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 20 Jun 2007 14:01:58 +0000 (14:01 +0000)
git-svn-id: file:///svn/unbound/trunk@408 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index 8225e3478bc4b035791d7dd43e9cc249c63cd659..2277f65f463b19cd7f4856853b73d1023db731d6 100644 (file)
@@ -833,6 +833,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
                worker_delete(worker);
                return 0;
        }
+       outside_network_set_secondary_buffer(worker->back, 
+               worker->front->udp_buff);
        if(worker->thread_num != 0) {
                /* start listening to commands */
                if(!(worker->cmd_com=comm_point_create_local(worker->base, 
index 988f7e68f54d62a344ef33ef39cb2797cd4b5b59..3a5ee119ba9fd2d692e06258454ecafe124b38cd 100644 (file)
@@ -7,6 +7,7 @@
        - typo in check caused subquery errors to be ignored, fixed.
        - make lint happy about rlim_t.
        - freeup of modules after freeup of module-states.
+       - duplicate replies work, this uses secondary udp buffer in outnet.
 
 19 June 2007: Wouter
        - nicer layout in stats.c, review 0.3 change.
index ffe975a438a085a56a88a976b85108a0b1cb023f..85e2f1d28fcceb3a472f9f7614632c9232b25eaa 100644 (file)
@@ -472,6 +472,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
        outnet->num_tcp = num_tcp;
        outnet->infra = infra;
        outnet->rnd = rnd;
+       outnet->udp_second = 0;
 #ifndef INET6
        do_ip6 = 0;
 #endif
@@ -532,6 +533,13 @@ outside_network_create(struct comm_base *base, size_t bufsize,
        return outnet;
 }
 
+void 
+outside_network_set_secondary_buffer(struct outside_network* outnet,
+        ldns_buffer* buf)
+{
+       outnet->udp_second = buf;
+}
+
 /** helper pending delete */
 static void
 pending_node_del(rbnode_t* node, void* arg)
@@ -998,6 +1006,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
        struct comm_reply* rep)
 {
        struct service_callback* p = sq->cblist, *n;
+       int dobackup = (sq->cblist && sq->cblist->next); /* >1 cb*/
        rbnode_t* rem;
        /* remove from tree, and schedule for deletion, so that callbacks
         * can safely deregister themselves and even create new serviced
@@ -1005,8 +1014,28 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
        rem = rbtree_delete(sq->outnet->serviced, sq);
        log_assert(rem); /* should have been present */
        sq->to_be_deleted = 1; 
+       if(dobackup) {
+               /* make a backup of the query, since the querystate processing
+                * may send outgoing queries that overwrite the buffer.
+                * use secondary buffer to store the query.
+                * This is a data copy, but faster than packet to server */
+               log_assert(ldns_buffer_capacity(sq->outnet->udp_second) >=
+                       ldns_buffer_limit(c->buffer));
+               ldns_buffer_clear(sq->outnet->udp_second);
+               ldns_buffer_write(sq->outnet->udp_second, 
+                       ldns_buffer_begin(c->buffer),
+                       ldns_buffer_limit(c->buffer));
+               ldns_buffer_flip(sq->outnet->udp_second);
+       }
        while(p) {
                n = p->next;
+               if(dobackup) {
+                       ldns_buffer_clear(c->buffer);
+                       ldns_buffer_write(c->buffer, 
+                       ldns_buffer_begin(sq->outnet->udp_second),
+                       ldns_buffer_limit(sq->outnet->udp_second));
+                       ldns_buffer_flip(c->buffer);
+               }
                (void)(*p->cb)(c, p->cb_arg, error, rep);
                p = n;
        }
index 6fc794e256ed1d07a652bd5a3e724053d0448e9c..0e7e59c33fdd32ddfd7cad23c7db72e40833f558 100644 (file)
@@ -65,6 +65,12 @@ struct outside_network {
            datagram at any time. */
        ldns_buffer* udp_buff;
 
+       /** buffer for storage. (buffer for incoming connections, since
+        * either an event to outside or incoming happens, but not both 
+        * This buffer is used during callbacks, so that the datagram
+        * that just arrived does not collide with new datagrams sent out. */
+       ldns_buffer* udp_second;
+
        /** 
         * Array of udp comm point* that are used to listen to pending events.
         * Each is on a different port. This is for ip4 ports.
@@ -265,6 +271,16 @@ struct outside_network* outside_network_create(struct comm_base* base,
  */
 void outside_network_delete(struct outside_network* outnet);
 
+/**
+ * Set secondary UDP buffer. Make sure it is not used during outside network
+ * callbacks. Such as the incoming network UDP buffer. Caller responsible
+ * for deletion.
+ * @param outnet: outside network.
+ * @param buf: buffer to use as secondary buffer.
+ */
+void outside_network_set_secondary_buffer(struct outside_network* outnet,
+       ldns_buffer* buf);
+
 /**
  * Send UDP query, create pending answer.
  * Changes the ID for the query to be random and unique for that destination.
index ade1e1091002646a64b770ca4f4e99a7df9610e4..88e6b94d8036d37dd912b921d05c37080e4b1ead 100644 (file)
@@ -668,6 +668,13 @@ outside_network_delete(struct outside_network* outnet)
        free(outnet);
 }
 
+void
+outside_network_set_secondary_buffer(struct outside_network* 
+       ATTR_UNUSED(outnet), ldns_buffer* ATTR_UNUSED(buf))
+{
+       /* nothing to do */
+}
+
 struct pending* 
 pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
        struct sockaddr_storage* addr, socklen_t addrlen, int timeout,