summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2015-02-10 22:06:39 +0000
committerBrad Smith <brad@cvs.openbsd.org>2015-02-10 22:06:39 +0000
commit448660bfcb8eed806e11dde21af174040428a88d (patch)
treeca0d2c49df04cb37e63db287de1eec1a5d810a30 /usr.sbin/nsd
parent33f252a37116a039bb832ed13f47cf966e5c5b80 (diff)
Merge in a commit from upstream..
- Fix tcp waiting list for zone transfers where the bind and connect calls fail. ok sthen@
Diffstat (limited to 'usr.sbin/nsd')
-rw-r--r--usr.sbin/nsd/xfrd-tcp.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/usr.sbin/nsd/xfrd-tcp.c b/usr.sbin/nsd/xfrd-tcp.c
index cf4831e8dbd..e251df7d6ca 100644
--- a/usr.sbin/nsd/xfrd-tcp.c
+++ b/usr.sbin/nsd/xfrd-tcp.c
@@ -944,7 +944,9 @@ xfrd_tcp_pipe_release(xfrd_tcp_set_t* set, struct xfrd_tcp_pipeline* tp,
(void)rbtree_delete(xfrd->tcp_set->pipetree, &tp->node);
/* a waiting zone can use the free tcp slot (to another server) */
- if(set->tcp_count == XFRD_MAX_TCP && set->tcp_waiting_first) {
+ /* if that zone fails to set-up or connect, we try to start the next
+ * waiting zone in the list */
+ while(set->tcp_count == XFRD_MAX_TCP && set->tcp_waiting_first) {
int i;
/* pop first waiting process */
@@ -952,15 +954,16 @@ xfrd_tcp_pipe_release(xfrd_tcp_set_t* set, struct xfrd_tcp_pipeline* tp,
/* start it */
assert(zone->tcp_conn == -1);
zone->tcp_conn = conn;
+ tcp_zone_waiting_list_popfirst(set, zone);
/* stop udp (if any) */
if(zone->zone_handler.ev_fd != -1)
xfrd_udp_release(zone);
if(!xfrd_tcp_open(set, tp, zone)) {
zone->tcp_conn = -1;
- set->tcp_count --;
xfrd_set_refresh_now(zone);
- return;
+ /* try to start the next zone (if any) */
+ continue;
}
/* re-init this tcppipe */
/* ip and ip_len set by tcp_open */
@@ -976,15 +979,15 @@ xfrd_tcp_pipe_release(xfrd_tcp_set_t* set, struct xfrd_tcp_pipeline* tp,
/* insert into tree */
(void)rbtree_insert(set->pipetree, &tp->node);
- /* succeeded? remove zone from lists and setup write */
+ /* setup write */
xfrd_unset_timer(zone);
- tcp_zone_waiting_list_popfirst(set, zone);
pipeline_setup_new_zone(set, tp, zone);
+ /* started a task, no need for cleanups, so return */
+ return;
}
- else {
- assert(!set->tcp_waiting_first);
- set->tcp_count --;
- assert(set->tcp_count >= 0);
- }
+ /* no task to start, cleanup */
+ assert(!set->tcp_waiting_first);
+ set->tcp_count --;
+ assert(set->tcp_count >= 0);
}