- if (ads->tcpstate == server_connected) {
- if (oldtcpstate == server_connected)
- count+= callb_checkfd(maxfd,readfds,ads->tcpsocket) +
- callb_checkfd(maxfd,exceptfds,ads->tcpsocket) +
- (ads->tcpsend.used && callb_checkfd(maxfd,writefds,ads->tcpsocket));
- if (oldtcpstate != server_connected || callb_checkfd(maxfd,readfds,ads->tcpsocket)) {
- skip= 0;
- for (;;) {
- if (ads->tcprecv.used<skip+2) {
- want= 2;
- } else {
- dgramlen= (ads->tcprecv.buf[skip]<<8) | ads->tcprecv.buf[skip+1];
- if (ads->tcprecv.used<skip+2+dgramlen) {
- want= 2+dgramlen;
- } else {
- procdgram(ads,ads->tcprecv.buf+skip+2,dgramlen,ads->tcpserver);
- skip+= 2+dgramlen; continue;
- }
- }
- ads->tcprecv.used -= skip;
- memmove(ads->tcprecv.buf,ads->tcprecv.buf+skip,ads->tcprecv.used);
- vbuf_ensure(&ads->tcprecv,want);
- if (ads->tcprecv.used >= ads->tcprecv.avail) break;
- r= read(ads->tcpsocket,
- ads->tcprecv.buf+ads->tcprecv.used,
- ads->tcprecv.avail-ads->tcprecv.used);
- if (r>0) {
- ads->tcprecv.used+= r;
+}
+
+void adns_firsttimeout(adns_state ads,
+ struct timeval **tv_io, struct timeval *tvbuf,
+ struct timeval now) {
+ adns__consistency(ads,0,cc_entex);
+ adns__timeouts(ads, 0, tv_io,tvbuf, now);
+ adns__consistency(ads,0,cc_entex);
+}
+
+void adns_processtimeouts(adns_state ads, const struct timeval *now) {
+ struct timeval tv_buf;
+
+ adns__consistency(ads,0,cc_entex);
+ adns__must_gettimeofday(ads,&now,&tv_buf);
+ if (now) adns__timeouts(ads, 1, 0,0, *now);
+ adns__consistency(ads,0,cc_entex);
+}
+
+/* fd handling functions. These are the top-level of the real work of
+ * reception and often transmission.
+ */
+
+int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) {
+ /* Returns the number of entries filled in. Always zeroes revents. */
+
+ assert(MAX_POLLFDS==2);
+
+ pollfds_buf[0].fd= ads->udpsocket;
+ pollfds_buf[0].events= POLLIN;
+ pollfds_buf[0].revents= 0;
+
+ switch (ads->tcpstate) {
+ case server_disconnected:
+ return 1;
+ case server_connecting:
+ pollfds_buf[1].events= POLLOUT;
+ break;
+ case server_ok:
+ pollfds_buf[1].events= ads->tcpsend.used ? POLLIN|POLLOUT|POLLPRI : POLLIN|POLLPRI;
+ break;
+ default:
+ abort();
+ }
+ pollfds_buf[1].fd= ads->tcpsocket;
+ return 2;
+}
+
+int adns_processreadable(adns_state ads, int fd, const struct timeval *now) {
+ int skip, want, dgramlen, r, udpaddrlen, serv;
+ byte udpbuf[DNS_MAXUDP];
+ struct sockaddr_in udpaddr;
+
+ adns__consistency(ads,0,cc_entex);
+
+ switch (ads->tcpstate) {
+ case server_disconnected:
+ case server_connecting:
+ break;
+ case server_ok:
+ if (fd != ads->tcpsocket) break;
+ skip= 0;
+ for (;;) {
+ if (ads->tcprecv.used<skip+2) {
+ want= 2;
+ } else {
+ dgramlen= (ads->tcprecv.buf[skip]<<8) | ads->tcprecv.buf[skip+1];
+ if (ads->tcprecv.used<skip+2+dgramlen) {
+ want= 2+dgramlen;