summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian>2003-06-22 13:49:20 +0000
committerian <ian>2003-06-22 13:49:20 +0000
commit237ce71042451bd1b4039b01cd769fc187750246 (patch)
tree56370fae27dff8d50616c9b7e335891185b698ee
parent609133ee3365572c56ffa2ffb14d274ff47eb94b (diff)
+ * Do not spin if connect() fails immediately (!)
@@ -1,6 +1,7 @@ Bugfixes: + * Do not spin if connect() fails immediately (!)
-rw-r--r--changelog1
-rw-r--r--regress/case-connfail.err0
-rw-r--r--regress/case-connfail.out9
-rw-r--r--regress/case-connfail.sys78
-rw-r--r--regress/hcommon.c1
-rw-r--r--src/event.c29
6 files changed, 106 insertions, 12 deletions
diff --git a/changelog b/changelog
index 39469bf..e14fec3 100644
--- 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
index 0000000..e69de29
--- /dev/null
+++ b/regress/case-connfail.err
diff --git a/regress/case-connfail.out b/regress/case-connfail.out
new file mode 100644
index 0000000..bc01126
--- /dev/null
+++ b/regress/case-connfail.out
@@ -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
index 0000000..b62923b
--- /dev/null
+++ b/regress/case-connfail.sys
@@ -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
diff --git a/regress/hcommon.c b/regress/hcommon.c
index 2cd3508..4a6293a 100644
--- a/regress/hcommon.c
+++ b/regress/hcommon.c
@@ -29,6 +29,7 @@ const struct Terrno Terrnos[]= {
{ "ECONNRESET", ECONNRESET },
{ "ECONNREFUSED", ECONNREFUSED },
{ "EPIPE", EPIPE },
+ { "ENOTSOCK", ENOTSOCK },
{ 0, 0 }
};
static vbuf vbw;
diff --git a/src/event.c b/src/event.c
index d51f980..f91a146 100644
--- a/src/event.c
+++ b/src/event.c
@@ -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; }