X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/4353a5c47b202786905257e520fe570a570e67bc..3955725ceceb330041f8e7a27e6629a2e8a9b5ba:/src/event.c?ds=inline diff --git a/src/event.c b/src/event.c index 14ce1b0..8329ff4 100644 --- a/src/event.c +++ b/src/event.c @@ -1,4 +1,26 @@ -/**/ +/* + * event.c + * - event loop core + * - TCP connection management + * - user-visible check/wait and event-loop-related functions + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include #include @@ -17,7 +39,7 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) { assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok); serv= ads->tcpserver; - adns__warn(ads,serv,"TCP connection lost: %s: %s",what,why); + adns__warn(ads,serv,0,"TCP connection lost: %s: %s",what,why); close(ads->tcpsocket); ads->tcpstate= server_disconnected; @@ -29,7 +51,7 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) { qu->tcpfailed |= (1<tcpfailed == (1<nservers)-1) { LIST_UNLINK(ads->timew,qu); - adns__query_fail(ads,qu,adns_s_allservfail); + adns__query_fail(qu,adns_s_allservfail); } } @@ -40,13 +62,13 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) { static void tcp_connected(adns_state ads, struct timeval now) { adns_query qu, nqu; - adns__debug(ads,ads->tcpserver,"TCP connected"); + adns__debug(ads,ads->tcpserver,0,"TCP connected"); ads->tcpstate= server_ok; for (qu= ads->timew.head; qu; qu= nqu) { nqu= qu->next; if (qu->state == query_udp) continue; assert (qu->state == query_tcpwait); - adns__query_tcp(ads,qu,now); + adns__query_tcp(qu,now); } } @@ -63,21 +85,21 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) { assert(!ads->tcprecv.used); proto= getprotobyname("tcp"); - if (!proto) { adns__diag(ads,-1,"unable to find protocol no. for TCP !"); return; } + if (!proto) { adns__diag(ads,-1,0,"unable to find protocol no. for TCP !"); return; } fd= socket(AF_INET,SOCK_STREAM,proto->p_proto); if (fd<0) { - adns__diag(ads,-1,"cannot create TCP socket: %s",strerror(errno)); + adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno)); return; } r= adns__setnonblock(ads,fd); if (r) { - adns__diag(ads,-1,"cannot make TCP socket nonblocking: %s",strerror(r)); + adns__diag(ads,-1,0,"cannot make TCP socket nonblocking: %s",strerror(r)); close(fd); return; } memset(&addr,0,sizeof(addr)); addr.sin_family= AF_INET; - addr.sin_port= htons(NSPORT); + addr.sin_port= htons(DNS_PORT); addr.sin_addr= ads->servers[ads->tcpserver].addr; r= connect(fd,&addr,sizeof(addr)); ads->tcpsocket= fd; @@ -98,20 +120,28 @@ static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, if (!tv_io) return; rbuf= *tv_io; - if (!rbuf) { *tvbuf= maxto; *tv_io= tvbuf; return; } - if (timercmp(rbuf,&maxto,>)) *rbuf= maxto; + if (!rbuf) { + *tvbuf= maxto; *tv_io= tvbuf; + } else { + if (timercmp(rbuf,&maxto,>)) *rbuf= maxto; + } +fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n", + maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec); } static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime) { ldiv_t dr; +fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n", + now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec); if (!tv_io) return; - maxtime.tv_sec -= (now.tv_sec-1); - maxtime.tv_usec += (1000-now.tv_usec); - dr= ldiv(maxtime.tv_usec,1000); + maxtime.tv_sec -= (now.tv_sec+2); + maxtime.tv_usec -= (now.tv_usec-2000000); + dr= ldiv(maxtime.tv_usec,1000000); maxtime.tv_sec += dr.quot; - maxtime.tv_usec -= dr.rem; + maxtime.tv_usec -= dr.quot*1000000; + if (maxtime.tv_sec<0) timerclear(&maxtime); inter_maxto(tv_io,tvbuf,maxtime); } @@ -130,9 +160,9 @@ static void checktimeouts(adns_state ads, struct timeval now, if (timercmp(&now,&qu->timeout,>)) { LIST_UNLINK(ads->timew,qu); if (qu->state != query_udp) { - adns__query_fail(ads,qu,adns_s_timeout); + adns__query_fail(qu,adns_s_timeout); } else { - adns__query_udp(ads,qu,now); + adns__query_udp(qu,now); } } else { inter_maxtoabs(tv_io,tvbuf,now,qu->timeout); @@ -147,9 +177,12 @@ void adns_interest(adns_state ads, int *maxfd, struct timeval tvto_lr; int r; - r= gettimeofday(&now,0); +fprintf(stderr,"adns_interest\n"); + +r= gettimeofday(&now,0); if (r) { - adns__warn(ads,-1,"gettimeofday failed - will sleep for a bit: %s",strerror(errno)); + adns__warn(ads,-1,0,"gettimeofday failed - will sleep for a bit: %s", + strerror(errno)); timerclear(&tvto_lr); timevaladd(&tvto_lr,LOCALRESOURCEMS); inter_maxto(tv_io, tvbuf, tvto_lr); } else { @@ -185,7 +218,7 @@ static int internal_callback(adns_state ads, int maxfd, const fd_set *exceptfds, struct timeval now) { int skip, want, dgramlen, count, udpaddrlen, r, serv; - byte udpbuf[MAXUDPDGRAM]; + byte udpbuf[DNS_MAXUDP]; struct sockaddr_in udpaddr; count= 0; @@ -224,7 +257,7 @@ static int internal_callback(adns_state ads, int maxfd, if (ads->tcprecv.usedtcprecv.buf+skip+2,dgramlen,ads->tcpserver); + adns__procdgram(ads,ads->tcprecv.buf+skip+2,dgramlen,ads->tcpserver,now); skip+= 2+dgramlen; continue; } } @@ -271,22 +304,22 @@ static int internal_callback(adns_state ads, int maxfd, if (r<0) { if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR || errno == ENOMEM || errno == ENOBUFS)) - adns__warn(ads,-1,"datagram receive error: %s",strerror(errno)); + adns__warn(ads,-1,0,"datagram receive error: %s",strerror(errno)); break; } if (udpaddrlen != sizeof(udpaddr)) { - adns__diag(ads,-1,"datagram received with wrong address length %d (expected %d)", - udpaddrlen,sizeof(udpaddr)); + adns__diag(ads,-1,0,"datagram received with wrong address length %d" + " (expected %d)", udpaddrlen,sizeof(udpaddr)); continue; } if (udpaddr.sin_family != AF_INET) { - adns__diag(ads,-1,"datagram received with wrong protocol family" + adns__diag(ads,-1,0,"datagram received with wrong protocol family" " %u (expected %u)",udpaddr.sin_family,AF_INET); continue; } - if (ntohs(udpaddr.sin_port) != NSPORT) { - adns__diag(ads,-1,"datagram received from wrong port %u (expected %u)", - ntohs(udpaddr.sin_port),NSPORT); + if (ntohs(udpaddr.sin_port) != DNS_PORT) { + adns__diag(ads,-1,0,"datagram received from wrong port %u (expected %u)", + ntohs(udpaddr.sin_port),DNS_PORT); continue; } for (serv= 0; @@ -294,11 +327,11 @@ static int internal_callback(adns_state ads, int maxfd, ads->servers[serv].addr.s_addr != udpaddr.sin_addr.s_addr; serv++); if (serv >= ads->nservers) { - adns__warn(ads,-1,"datagram received from unknown nameserver %s", + adns__warn(ads,-1,0,"datagram received from unknown nameserver %s", inet_ntoa(udpaddr.sin_addr)); continue; } - adns__procdgram(ads,udpbuf,r,serv); + adns__procdgram(ads,udpbuf,r,serv,now); } } return count; @@ -336,7 +369,7 @@ static int internal_check(adns_state ads, if (qu->id>=0) return EWOULDBLOCK; } LIST_UNLINK(ads->output,qu); - *answer= (adns_answer*)qu->answer.buf; + *answer= qu->answer; if (context_r) *context_r= qu->context.ext; free(qu); return 0; @@ -352,7 +385,7 @@ int adns_wait(adns_state ads, for (;;) { r= internal_check(ads,query_io,answer_r,context_r); - if (r && r != EWOULDBLOCK) return r; + if (r != EWOULDBLOCK) return r; maxfd= 0; tvp= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); adns_interest(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf);