]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Fix IPv6 detection on XP.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2009 08:24:19 +0000 (08:24 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2009 08:24:19 +0000 (08:24 +0000)
Fix loop to service on quit when there are messages waiting.

git-svn-id: file:///svn/unbound/trunk@1624 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index 611781ace8803e6dc953fb4fafd03abdd0c1ede7..2aa64a44c6c66f058a4c187cca270ecebd6fc698 100644 (file)
@@ -1163,6 +1163,7 @@ worker_delete(struct worker* worker)
                mesh_stats(worker->env.mesh, "mesh has");
                worker_mem_report(worker, NULL);
        }
+       outside_network_quit_prepare(worker->back);
        mesh_delete(worker->env.mesh);
        ldns_buffer_free(worker->env.scratch_buffer);
        forwards_delete(worker->env.fwds);
index ac25ecdb4e83024368cc373ef8235cdeaa9f3d50..a8d1de135114227548489320f9619233301480b8 100644 (file)
@@ -1,3 +1,11 @@
+27 May 2009: Wouter
+       - detect lack of IPv6 support on XP (with a different error code).
+       - Fixup a crash-on-exit which was triggered by a very long queue.
+         Unbound would try to re-use ports that came free, but this is
+         of course not really possible because everything is deleted.
+         Most easily triggered on XP (not Vista), maybe because of the
+         network stack encouraging large messages backlogs.
+
 26 May 2009: Wouter
        - Thanks again to Brett Carr, found an assertion that was not true.
          Assertion checked if recursion parent query still existed.
index 63fd0082d532c394bd8af4dc9b45e32cb0c4ede2..c17dc56e856677269c8ab0317abec6c4623e243a 100644 (file)
@@ -72,6 +72,7 @@ libworker_delete(struct libworker* w)
 {
        if(!w) return;
        if(w->env) {
+               outside_network_quit_prepare(w->back);
                mesh_delete(w->env->mesh);
                context_release_alloc(w->ctx, w->env->alloc, 
                        !w->is_bg || w->is_bg_thread);
index a82fa48c83874a51d0db38f2dd8666f5c2057ad9..f0bec69a7d15fe5885878b4534377b1c87659701 100644 (file)
@@ -295,6 +295,12 @@ make_sock(int stype, const char* ifname, const char* port,
        hints->ai_socktype = stype;
        *noip6 = 0;
        if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) {
+#ifdef USE_WINSOCK
+               if(r == EAI_NONAME && hints->ai_family == AF_INET6){
+                       *noip6 = 1; /* 'Host not found' for IP6 on winXP */
+                       return -1;
+               }
+#endif
                log_err("node %s:%s getaddrinfo: %s %s", 
                        ifname?ifname:"default", port, gai_strerror(r),
 #ifdef EAI_SYSTEM
index 34cc6db3e8c5170f980c5515e040281f4f0c52e5..d8033035c2a2ae039ba380b0bd0120e469ee59c6 100644 (file)
@@ -194,7 +194,8 @@ static void
 use_free_buffer(struct outside_network* outnet)
 {
        struct waiting_tcp* w;
-       while(outnet->tcp_free && outnet->tcp_wait_first) {
+       while(outnet->tcp_free && outnet->tcp_wait_first 
+               && !outnet->want_to_quit) {
                w = outnet->tcp_wait_first;
                outnet->tcp_wait_first = w->next_waiting;
                if(outnet->tcp_wait_last == w)
@@ -276,7 +277,8 @@ outnet_send_wait_udp(struct outside_network* outnet)
 {
        struct pending* pend;
        /* process waiting queries */
-       while(outnet->udp_wait_first && outnet->unused_fds) {
+       while(outnet->udp_wait_first && outnet->unused_fds 
+               && !outnet->want_to_quit) {
                pend = outnet->udp_wait_first;
                outnet->udp_wait_first = pend->next_waiting;
                if(!pend->next_waiting) outnet->udp_wait_last = NULL;
@@ -483,6 +485,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
        outnet->infra = infra;
        outnet->rnd = rnd;
        outnet->svcd_overhead = 0;
+       outnet->want_to_quit = 0;
        outnet->unwanted_threshold = unwanted_threshold;
        outnet->unwanted_action = unwanted_action;
        outnet->unwanted_param = unwanted_param;
@@ -608,11 +611,21 @@ serviced_node_del(rbnode_t* node, void* ATTR_UNUSED(arg))
        free(sq);
 }
 
+void 
+outside_network_quit_prepare(struct outside_network* outnet)
+{
+       if(!outnet)
+               return;
+       /* prevent queued items from being sent */
+       outnet->want_to_quit = 1; 
+}
+
 void 
 outside_network_delete(struct outside_network* outnet)
 {
        if(!outnet)
                return;
+       outnet->want_to_quit = 1;
        /* check every element, since we can be called on malloc error */
        if(outnet->pending) {
                /* free pending elements, but do no unlink from tree. */
index 30f31f4519a17e8551aab355aeb77f030713499c..584f13a9bb09f5cef75705c59f16ff6f62764bed 100644 (file)
@@ -75,6 +75,8 @@ struct outside_network {
        size_t svcd_overhead;
        /** use x20 bits to encode additional ID random bits */
        int use_caps_for_id;
+       /** outside network wants to quit. Stop queued msgs from sent. */
+       int want_to_quit;
 
        /** number of unwanted replies received (for statistics) */
        size_t unwanted_replies;
@@ -360,6 +362,12 @@ struct outside_network* outside_network_create(struct comm_base* base,
  */
 void outside_network_delete(struct outside_network* outnet);
 
+/**
+ * Prepare for quit. Sends no more queries, even if queued up.
+ * @param outnet: object to prepare for removal
+ */
+void outside_network_quit_prepare(struct outside_network* outnet);
+
 /**
  * Send UDP query, create pending answer.
  * Changes the ID for the query to be random and unique for that destination.
index 21774626244f817d5c060b25e141b8f88d75c6c4..118fd0e8ab93c33aed934ed0e651fa12ee530bd8 100644 (file)
@@ -749,6 +749,11 @@ outside_network_delete(struct outside_network* outnet)
        free(outnet);
 }
 
+void 
+outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
+{
+}
+
 struct pending* 
 pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
        struct sockaddr_storage* addr, socklen_t addrlen, int timeout,