chiark / gitweb /
+ * Do not spin if connect() fails immediately (!)
authorian <ian>
Sun, 22 Jun 2003 13:49:20 +0000 (13:49 +0000)
committerian <ian>
Sun, 22 Jun 2003 13:49:20 +0000 (13:49 +0000)
@@ -1,6 +1,7 @@
   Bugfixes:
+  * Do not spin if connect() fails immediately (!)

changelog
regress/case-connfail.err [new file with mode: 0644]
regress/case-connfail.out [new file with mode: 0644]
regress/case-connfail.sys [new file with mode: 0644]
regress/hcommon.c
src/event.c

index 39469bf..e14fec3 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,6 +1,7 @@
 adns (1.1); urgency=medium
 
   Bugfixes:
+  * Do not spin if connect() fails immediately (!)
   * Stop searching on a CNAME (even if it's broken).
   * When search list runs out, _qf_owner sets owner to query domain.
   * Don't use <sys/select.h> any more, it was a mistake made in pre-1.0
diff --git a/regress/case-connfail.err b/regress/case-connfail.err
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/regress/case-connfail.out b/regress/case-connfail.out
new file mode 100644 (file)
index 0000000..bc01126
--- /dev/null
@@ -0,0 +1,9 @@
+adns debug: using nameserver 172.18.45.36
+adns debug: using nameserver 172.18.45.6
+davenant.greenend.org.uk flags 2 type 1adns warning: TCP connection failed: connect: Socket operation on non-socket (NS=172.18.45.36)
+adns warning: TCP connection failed: connect: Socket operation on non-socket (NS=172.18.45.6)
+ A(-) submitted
+adns warning: TCP connection failed: connect: Socket operation on non-socket (NS=172.18.45.36)
+adns warning: TCP connection failed: connect: Socket operation on non-socket (NS=172.18.45.6)
+davenant.greenend.org.uk flags 2 type A(-): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800
+rc=0
diff --git a/regress/case-connfail.sys b/regress/case-connfail.sys
new file mode 100644 (file)
index 0000000..b62923b
--- /dev/null
@@ -0,0 +1,78 @@
+./adnstest 2ndserver
+:1 2/davenant.greenend.org.uk
+ start 1056289303.784817
+ socket type=SOCK_DGRAM
+ socket=6
+ +0.000031
+ fcntl fd=6 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000010
+ fcntl fd=6 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000007
+ socket type=SOCK_STREAM
+ socket=7
+ +0.000059
+ fcntl fd=7 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000007
+ fcntl fd=7 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000006
+ connect fd=7 addr=172.18.45.36:53
+ connect=ENOTSOCK
+ +0.000013
+ close fd=7
+ close=OK
+ +0.000031
+ socket type=SOCK_STREAM
+ socket=7
+ +0.000035
+ fcntl fd=7 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000006
+ fcntl fd=7 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000007
+ connect fd=7 addr=172.18.45.6:53
+ connect=ENOTSOCK
+ +0.000008
+ close fd=7
+ close=OK
+ +0.000013
+ select max=7 rfds=[6] wfds=[] efds=[] to=0.000000
+ select=0 rfds=[] wfds=[] efds=[]
+ +0.000036
+ socket type=SOCK_STREAM
+ socket=7
+ +0.000036
+ fcntl fd=7 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000007
+ fcntl fd=7 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000006
+ connect fd=7 addr=172.18.45.36:53
+ connect=ENOTSOCK
+ +0.000008
+ close fd=7
+ close=OK
+ +0.000013
+ socket type=SOCK_STREAM
+ socket=7
+ +0.000036
+ fcntl fd=7 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000007
+ fcntl fd=7 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000006
+ connect fd=7 addr=172.18.45.6:53
+ connect=ENOTSOCK
+ +0.000008
+ close fd=7
+ close=OK
+ +0.000012
+ close fd=6
+ close=OK
+ +0.000023
index 2cd3508..4a6293a 100644 (file)
@@ -29,6 +29,7 @@ const struct Terrno Terrnos[]= {
   { "ECONNRESET",                ECONNRESET                   },
   { "ECONNREFUSED",              ECONNREFUSED                 },
   { "EPIPE",                     EPIPE                        },
+  { "ENOTSOCK",                  ENOTSOCK                     },
   {  0,                          0                            }
 };
 static vbuf vbw;
index d51f980..f91a146 100644 (file)
@@ -83,6 +83,21 @@ static void tcp_connected(adns_state ads, struct timeval now) {
   }
 }
 
+static void tcp_broken_events(adns_state ads) {
+  adns_query qu, nqu;
+  
+  assert(ads->tcpstate == server_broken);
+  for (qu= ads->tcpw.head; qu; qu= nqu) {
+    nqu= qu->next;
+    assert(qu->state == query_tcpw);
+    if (qu->retries > ads->nservers) {
+      LIST_UNLINK(ads->tcpw,qu);
+      adns__query_fail(qu,adns_s_allservfail);
+    }
+  }
+  ads->tcpstate= server_disconnected;
+}
+
 void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
   int r, fd, tries;
   struct sockaddr_in addr;
@@ -135,7 +150,7 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
       return;
     }
     adns__tcp_broken(ads,"connect",strerror(errno));
-    ads->tcpstate= server_disconnected;
+    tcp_broken_events(ads);
   }
 }
 
@@ -222,21 +237,11 @@ static void timeouts_queue(adns_state ads, int act,
 static void tcp_events(adns_state ads, int act,
                       struct timeval **tv_io, struct timeval *tvbuf,
                       struct timeval now) {
-  adns_query qu, nqu;
-  
   for (;;) {
     switch (ads->tcpstate) {
     case server_broken:
       if (!act) { inter_immed(tv_io,tvbuf); return; }
-      for (qu= ads->tcpw.head; qu; qu= nqu) {
-       nqu= qu->next;
-       assert(qu->state == query_tcpw);
-       if (qu->retries > ads->nservers) {
-         LIST_UNLINK(ads->tcpw,qu);
-         adns__query_fail(qu,adns_s_allservfail);
-       }
-      }
-      ads->tcpstate= server_disconnected;
+      tcp_broken_events(ads);
     case server_disconnected: /* fall through */
       if (!ads->tcpw.head) return;
       if (!act) { inter_immed(tv_io,tvbuf); return; }