X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fevent.c;h=684759a727f2cfa5c2e390978950ec49f6b7ac21;hb=73eb26037c46bebeaa30ba38eba887216f0e9a6e;hp=9e7bdc298756d125d2aec723a40da1b804ec9e11;hpb=6c68a59377bb39c45cf81bbc9072126ef974b865;p=adns.git diff --git a/src/event.c b/src/event.c index 9e7bdc2..684759a 100644 --- a/src/event.c +++ b/src/event.c @@ -6,10 +6,10 @@ */ /* * This file is - * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is - * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999 Tony Finch * * This program is free software; you can redistribute it and/or modify @@ -54,11 +54,18 @@ static void tcp_close(adns_state ads) { 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; @@ -328,12 +335,13 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { switch (ads->tcpstate) { case server_disconnected: + case server_broken: case server_connecting: break; case server_ok: if (fd != ads->tcpsocket) break; assert(!ads->tcprecv_skip); - for (;;) { + do { if (ads->tcprecv.used >= ads->tcprecv_skip+2) { dgramlen= ((ads->tcprecv.buf[ads->tcprecv_skip]<<8) | ads->tcprecv.buf[ads->tcprecv_skip+1]); @@ -367,9 +375,9 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { if (errno_resources(errno)) { r= errno; goto xit; } } adns__tcp_broken(ads,"read",r?strerror(errno):"closed"); - r= 0; goto xit; } - } /* never reached */ + } while (ads->tcpstate == server_ok); + r= 0; goto xit; default: abort(); } @@ -387,7 +395,8 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { } if (udpaddrlen != sizeof(udpaddr)) { adns__diag(ads,-1,0,"datagram received with wrong address length %d" - " (expected %d)", udpaddrlen,sizeof(udpaddr)); + " (expected %lu)", udpaddrlen, + (unsigned long)sizeof(udpaddr)); continue; } if (udpaddr.sin_family != AF_INET) { @@ -425,6 +434,7 @@ int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) { switch (ads->tcpstate) { case server_disconnected: + case server_broken: break; case server_connecting: if (fd != ads->tcpsocket) break; @@ -447,8 +457,8 @@ int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) { 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); @@ -462,7 +472,9 @@ int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) { ads->tcpsend.used -= r; memmove(ads->tcpsend.buf,ads->tcpsend.buf+r,ads->tcpsend.used); } - } /* not reached */ + } + r= 0; + goto xit; default: abort(); } @@ -476,6 +488,7 @@ int adns_processexceptional(adns_state ads, int fd, const struct timeval *now) { adns__consistency(ads,0,cc_entex); switch (ads->tcpstate) { case server_disconnected: + case server_broken: break; case server_connecting: case server_ok: @@ -596,6 +609,7 @@ void adns_globalsystemfailure(adns_state ads) { adns__tcp_broken(ads,0,0); break; case server_disconnected: + case server_broken: break; default: abort(); @@ -619,7 +633,7 @@ int adns_processany(adns_state ads) { * likely just to want to do a read on one or two fds anyway. */ npollfds= adns__pollfds(ads,pollfds); - for (i=0; ibug_if_query_done_now= 1; adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0); - ads->bug_if_query_done_now= 0; assert(tvp); rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp); if (rsel==-1) {