void adns__tcp_broken(adns_state ads, const char *what, const char *why) {
int serv;
+ adns_query qu;
assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok);
serv= ads->tcpserver;
if (what) adns__warn(ads,serv,0,"TCP connection failed: %s: %s",what,why);
+ if (ads->tcpstate == server_connecting) {
+ /* Counts as a retry for all the queries waiting for TCP. */
+ for (qu= ads->tcpw.head; qu; qu= qu->next)
+ qu->retries++;
+ }
+
tcp_close(ads);
ads->tcpstate= server_broken;
ads->tcpserver= (serv+1)%ads->nservers;
switch (ads->tcpstate) {
case server_disconnected:
+ case server_broken:
case server_connecting:
break;
case server_ok:
switch (ads->tcpstate) {
case server_disconnected:
+ case server_broken:
break;
case server_connecting:
if (fd != ads->tcpsocket) break;
r= 0; goto xit;
} /* not reached */
case server_ok:
- if (!(ads->tcpsend.used && fd == ads->tcpsocket)) break;
- for (;;) {
+ if (fd != ads->tcpsocket) break;
+ while (ads->tcpsend.used) {
adns__sigpipe_protect(ads);
r= write(ads->tcpsocket,ads->tcpsend.buf,ads->tcpsend.used);
adns__sigpipe_unprotect(ads);
ads->tcpsend.used -= r;
memmove(ads->tcpsend.buf,ads->tcpsend.buf+r,ads->tcpsend.used);
}
- } /* not reached */
+ }
+ r= 0;
+ goto xit;
default:
abort();
}
adns__consistency(ads,0,cc_entex);
switch (ads->tcpstate) {
case server_disconnected:
+ case server_broken:
break;
case server_connecting:
case server_ok:
adns__tcp_broken(ads,0,0);
break;
case server_disconnected:
+ case server_broken:
break;
default:
abort();