ReactOS  0.4.14-dev-554-g2f8d847
event.c
Go to the documentation of this file.
1 /*
2  * event.c
3  * - event loop core
4  * - TCP connection management
5  * - user-visible check/wait and event-loop-related functions
6  */
7 /*
8  * This file is
9  * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
10  *
11  * It is part of adns, which is
12  * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
13  * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2, or (at your option)
18  * any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, adns_socket_write to the Free Software Foundation,
27  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28  */
29 
30 #include <errno.h>
31 #include <stdlib.h>
32 
33 #ifdef ADNS_JGAA_WIN32
34 # include "adns_win32.h"
35 #else
36 # include <unistd.h>
37 # include <sys/types.h>
38 # include <sys/time.h>
39 # include <netdb.h>
40 # include <sys/socket.h>
41 # include <netinet/in.h>
42 # include <arpa/inet.h>
43 #endif
44 
45 #include "internal.h"
46 #include "tvarith.h"
47 
48 /* TCP connection management. */
49 
50 static void tcp_close(adns_state ads) {
51  int serv;
52 
53  serv= ads->tcpserver;
55  ads->tcpsocket= -1;
57 }
58 
59 void adns__tcp_broken(adns_state ads, const char *what, const char *why) {
60  int serv;
61  adns_query qu;
62 
63  assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok);
64  serv= ads->tcpserver;
65  if (what) adns__warn(ads,serv,0,"TCP connection failed: %s: %s",what,why);
66 
67  if (ads->tcpstate == server_connecting) {
68  /* Counts as a retry for all the queries waiting for TCP. */
69  for (qu= ads->tcpw.head; qu; qu= qu->next)
70  qu->retries++;
71  }
72 
73  tcp_close(ads);
74  ads->tcpstate= server_broken;
75  ads->tcpserver= (serv+1)%ads->nservers;
76 }
77 
78 static void tcp_connected(adns_state ads, struct timeval now) {
79  adns_query qu, nqu;
80 
81  adns__debug(ads,ads->tcpserver,0,"TCP connected");
82  ads->tcpstate= server_ok;
83  for (qu= ads->tcpw.head; qu && ads->tcpstate == server_ok; qu= nqu) {
84  nqu= qu->next;
85  assert(qu->state == query_tcpw);
87  }
88 }
89 
91  int r, tries;
93  struct sockaddr_in addr;
94  struct protoent *proto;
95 
96  for (tries=0; tries<ads->nservers; tries++) {
97  switch (ads->tcpstate) {
98  case server_connecting:
99  case server_ok:
100  case server_broken:
101  return;
102  case server_disconnected:
103  break;
104  default:
105  abort();
106  }
107 
108  assert(!ads->tcpsend.used);
109  assert(!ads->tcprecv.used);
111 
112  proto= getprotobyname("tcp");
113  if (!proto) { adns__diag(ads,-1,0,"unable to find protocol no. for TCP !"); return; }
115  fd= socket(AF_INET,SOCK_STREAM,proto->p_proto);
117  if (fd<0) {
118  adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno));
119  return;
120  }
122  if (r) {
123  adns__diag(ads,-1,0,"cannot make TCP socket nonblocking: %s",strerror(r));
125  return;
126  }
127  memset(&addr,0,sizeof(addr));
128  addr.sin_family= AF_INET;
129  addr.sin_port= htons(DNS_PORT);
130  addr.sin_addr= ads->servers[ads->tcpserver].addr;
132  r= connect(fd,(const struct sockaddr*)&addr,sizeof(addr));
134  ads->tcpsocket= fd;
135  ads->tcpstate= server_connecting;
136  if (r==0) { tcp_connected(ads,now); return; }
137  if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
138  ads->tcptimeout= now;
140  return;
141  }
142  adns__tcp_broken(ads,"connect",strerror(errno));
143  ads->tcpstate= server_disconnected;
144  }
145 }
146 
147 /* Timeout handling functions. */
148 
149 void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
150  struct timeval *tv_buf) {
151  const struct timeval *now;
152  int r;
153 
154  now= *now_io;
155  if (now) return;
156  r= gettimeofday(tv_buf,0); if (!r) { *now_io= tv_buf; return; }
157  adns__diag(ads,-1,0,"gettimeofday failed: %s",strerror(errno));
159  return;
160 }
161 
162 static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf) {
163  struct timeval *rbuf;
164 
165  if (!tv_io) return;
166 
167  rbuf= *tv_io;
168  if (!rbuf) { *tv_io= rbuf= tvbuf; }
169 
170  timerclear(rbuf);
171 }
172 
173 static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf,
174  struct timeval maxto) {
175  struct timeval *rbuf;
176 
177  if (!tv_io) return;
178  rbuf= *tv_io;
179  if (!rbuf) {
180  *tvbuf= maxto; *tv_io= tvbuf;
181  } else {
182  if (timercmp(rbuf,&maxto,>)) *rbuf= maxto;
183  }
184 /*fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n",
185  maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec);*/
186 }
187 
188 static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf,
189  struct timeval now, struct timeval maxtime) {
190  /* tv_io may be 0 */
191  ldiv_t dr;
192 
193 /*fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n",
194  now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec);*/
195  if (!tv_io) return;
196  maxtime.tv_sec -= (now.tv_sec+2);
197  maxtime.tv_usec -= (now.tv_usec-2000000);
198  dr= ldiv(maxtime.tv_usec,1000000);
199  maxtime.tv_sec += dr.quot;
200  maxtime.tv_usec -= dr.quot*1000000;
201  if (maxtime.tv_sec<0) timerclear(&maxtime);
202  inter_maxto(tv_io,tvbuf,maxtime);
203 }
204 
205 static void timeouts_queue(adns_state ads, int act,
206  struct timeval **tv_io, struct timeval *tvbuf,
207  struct timeval now, struct query_queue *queue) {
208  adns_query qu, nqu;
209 
210  for (qu= queue->head; qu; qu= nqu) {
211  nqu= qu->next;
212  if (!timercmp(&now,&qu->timeout,>)) {
213  inter_maxtoabs(tv_io,tvbuf,now,qu->timeout);
214  } else {
215  if (!act) { inter_immed(tv_io,tvbuf); return; }
216  LIST_UNLINK(*queue,qu);
217  if (qu->state != query_tosend) {
219  } else {
220  adns__query_send(qu,now);
221  }
222  nqu= queue->head;
223  }
224  }
225 }
226 
227 static void tcp_events(adns_state ads, int act,
228  struct timeval **tv_io, struct timeval *tvbuf,
229  struct timeval now) {
230  adns_query qu, nqu;
231 
232  for (;;) {
233  switch (ads->tcpstate) {
234  case server_broken:
235  if (!act) { inter_immed(tv_io,tvbuf); return; }
236  for (qu= ads->tcpw.head; qu; qu= nqu) {
237  nqu= qu->next;
238  assert(qu->state == query_tcpw);
239  if (qu->retries > ads->nservers) {
240  LIST_UNLINK(ads->tcpw,qu);
242  }
243  }
244  ads->tcpstate= server_disconnected;
245  case server_disconnected: /* fall through */
246  if (!ads->tcpw.head) return;
247  if (!act) { inter_immed(tv_io,tvbuf); return; }
249  break;
250  case server_ok:
251  if (ads->tcpw.head) return;
252  if (!ads->tcptimeout.tv_sec) {
253  assert(!ads->tcptimeout.tv_usec);
254  ads->tcptimeout= now;
256  }
257  case server_connecting: /* fall through */
258  if (!act || !timercmp(&now,&ads->tcptimeout,>)) {
259  inter_maxtoabs(tv_io,tvbuf,now,ads->tcptimeout);
260  return;
261  } {
262  /* TCP timeout has happened */
263  switch (ads->tcpstate) {
264  case server_connecting: /* failed to connect */
265  adns__tcp_broken(ads,"unable to make connection","timed out");
266  break;
267  case server_ok: /* idle timeout */
268  tcp_close(ads);
269  ads->tcpstate= server_disconnected;
270  return;
271  default:
272  abort();
273  }
274  }
275  break;
276  default:
277  abort();
278  }
279  }
280  return;
281 }
282 
284  struct timeval **tv_io, struct timeval *tvbuf,
285  struct timeval now) {
286  timeouts_queue(ads,act,tv_io,tvbuf,now, &ads->udpw);
287  timeouts_queue(ads,act,tv_io,tvbuf,now, &ads->tcpw);
288  tcp_events(ads,act,tv_io,tvbuf,now);
289 }
290 
292  struct timeval **tv_io, struct timeval *tvbuf,
293  struct timeval now) {
295  adns__timeouts(ads, 0, tv_io,tvbuf, now);
297 }
298 
300  struct timeval tv_buf;
301 
303  adns__must_gettimeofday(ads,&now,&tv_buf);
304  if (now) adns__timeouts(ads, 1, 0,0, *now);
306 }
307 
308 /* fd handling functions. These are the top-level of the real work of
309  * reception and often transmission.
310  */
311 
312 int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) {
313  /* Returns the number of entries filled in. Always zeroes revents. */
314 
315  assert(MAX_POLLFDS==2);
316 
317  pollfds_buf[0].fd= ads->udpsocket;
318  pollfds_buf[0].events= POLLIN;
319  pollfds_buf[0].revents= 0;
320 
321  switch (ads->tcpstate) {
322  case server_disconnected:
323  case server_broken:
324  return 1;
325  case server_connecting:
326  pollfds_buf[1].events= POLLOUT;
327  break;
328  case server_ok:
329  pollfds_buf[1].events= ads->tcpsend.used ? POLLIN|POLLOUT|POLLPRI : POLLIN|POLLPRI;
330  break;
331  default:
332  abort();
333  }
334  pollfds_buf[1].fd= ads->tcpsocket;
335  return 2;
336 }
337 
339  int want, dgramlen, r, udpaddrlen, serv, old_skip;
340  byte udpbuf[DNS_MAXUDP];
341  struct sockaddr_in udpaddr;
342 
344 
345  switch (ads->tcpstate) {
346  case server_disconnected:
347  case server_broken:
348  case server_connecting:
349  break;
350  case server_ok:
351  if (fd != ads->tcpsocket) break;
353  do {
354  if (ads->tcprecv.used >= ads->tcprecv_skip+2) {
355  dgramlen= ((ads->tcprecv.buf[ads->tcprecv_skip]<<8) |
357  if (ads->tcprecv.used >= ads->tcprecv_skip+2+dgramlen) {
358  old_skip= ads->tcprecv_skip;
359  ads->tcprecv_skip += 2+dgramlen;
360  adns__procdgram(ads, ads->tcprecv.buf+old_skip+2,
361  dgramlen, ads->tcpserver, 1,*now);
362  continue;
363  } else {
364  want= 2+dgramlen;
365  }
366  } else {
367  want= 2;
368  }
371  ads->tcprecv_skip= 0;
372  if (!adns__vbuf_ensure(&ads->tcprecv,want)) { r= ENOMEM; goto xit; }
374  if (ads->tcprecv.used == ads->tcprecv.avail) continue;
380  if (r>0) {
381  ads->tcprecv.used+= r;
382  } else {
383  if (r) {
384  if (errno==EAGAIN || errno==EWOULDBLOCK) { r= 0; goto xit; }
385  if (errno==EINTR) continue;
386  if (errno_resources(errno)) { r= errno; goto xit; }
387  }
388  adns__tcp_broken(ads,"adns_socket_read",r?strerror(errno):"closed");
389  }
390  } while (ads->tcpstate == server_ok);
391  r= 0; goto xit;
392  default:
393  abort();
394  }
395  if (fd == ads->udpsocket) {
396  for (;;) {
397  udpaddrlen= sizeof(udpaddr);
399  r= recvfrom(ads->udpsocket,(char*)udpbuf,sizeof(udpbuf),0,
400  (struct sockaddr*)&udpaddr,&udpaddrlen);
402  if (r<0) {
403  if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ECONNRESET) { r= 0; goto xit; }
404  if (errno == EINTR) continue;
405  if (errno_resources(errno)) { r= errno; goto xit; }
406  adns__warn(ads,-1,0,"datagram receive error: %s (%d)",strerror(errno), errno);
407  r= 0; goto xit;
408  }
409  if (udpaddrlen != sizeof(udpaddr)) {
410  adns__diag(ads,-1,0,"datagram received with wrong address length %d"
411  " (expected %lu)", udpaddrlen,
412  (unsigned long)sizeof(udpaddr));
413  continue;
414  }
415  if (udpaddr.sin_family != AF_INET) {
416  adns__diag(ads,-1,0,"datagram received with wrong protocol family"
417  " %u (expected %u)",udpaddr.sin_family,AF_INET);
418  continue;
419  }
420  if (ntohs(udpaddr.sin_port) != DNS_PORT) {
421  adns__diag(ads,-1,0,"datagram received from wrong port %u (expected %u)",
422  ntohs(udpaddr.sin_port),DNS_PORT);
423  continue;
424  }
425  for (serv= 0;
426  serv < ads->nservers &&
427  ads->servers[serv].addr.s_addr != udpaddr.sin_addr.s_addr;
428  serv++);
429  if (serv >= ads->nservers) {
430  adns__warn(ads,-1,0,"datagram received from unknown nameserver %s",
431  inet_ntoa(udpaddr.sin_addr));
432  continue;
433  }
434  adns__procdgram(ads,udpbuf,r,serv,0,*now);
435  }
436  }
437  r= 0;
438 xit:
440  return r;
441 }
442 
444  int r;
445 
447 
448  switch (ads->tcpstate) {
449  case server_disconnected:
450  case server_broken:
451  break;
452  case server_connecting:
453  if (fd != ads->tcpsocket) break;
454  assert(ads->tcprecv.used==0);
455  assert(ads->tcprecv_skip==0);
456  for (;;) {
457  if (!adns__vbuf_ensure(&ads->tcprecv,1)) { r= ENOMEM; goto xit; }
461  if (r==0 || (r<0 && (errno==EAGAIN || errno==EWOULDBLOCK))) {
463  r= 0; goto xit;
464  }
465  if (r>0) {
466  adns__tcp_broken(ads,"connect/adns_socket_read","sent data before first request");
467  r= 0; goto xit;
468  }
469  if (errno==EINTR) continue;
470  if (errno_resources(errno)) { r= errno; goto xit; }
471  adns__tcp_broken(ads,"connect/adns_socket_read",strerror(errno));
472  r= 0; goto xit;
473  } /* not reached */
474  case server_ok:
475  if (fd != ads->tcpsocket) break;
476  while (ads->tcpsend.used) {
482  if (r<0) {
483  if (errno==EINTR) continue;
484  if (errno==EAGAIN || errno==EWOULDBLOCK) { r= 0; goto xit; }
485  if (errno_resources(errno)) { r= errno; goto xit; }
486  adns__tcp_broken(ads,"adns_socket_write",strerror(errno));
487  r= 0; goto xit;
488  } else if (r>0) {
489  ads->tcpsend.used -= r;
490  memmove(ads->tcpsend.buf,ads->tcpsend.buf+r, (size_t) ads->tcpsend.used);
491  }
492  }
493  r= 0;
494  goto xit;
495  default:
496  abort();
497  }
498  r= 0;
499 xit:
501  return r;
502 }
503 
506  switch (ads->tcpstate) {
507  case server_disconnected:
508  case server_broken:
509  break;
510  case server_connecting:
511  case server_ok:
512  if (fd != ads->tcpsocket) break;
513  adns__tcp_broken(ads,"poll/select","exceptional condition detected");
514  break;
515  default:
516  abort();
517  }
519  return 0;
520 }
521 
523  int revent, int pollflag,
524  int maxfd, const fd_set *fds,
525  int (*func)(adns_state, ADNS_SOCKET fd, const struct timeval *now),
526  struct timeval now, int *r_r) {
527  int r;
528 
529  if (!(revent & pollflag)) return;
530  if (fds && !((int)fd<maxfd && FD_ISSET(fd,fds))) return;
531  r= func(ads,fd,&now);
532  if (r) {
533  if (r_r) {
534  *r_r= r;
535  } else {
536  adns__diag(ads,-1,0,"process fd failed after select: %s",strerror(errno));
538  }
539  }
540 }
541 
543  const struct pollfd *pollfds, int npollfds,
544  int maxfd, const fd_set *readfds,
545  const fd_set *writefds, const fd_set *exceptfds,
546  struct timeval now, int *r_r) {
547  int i, revents;
548  ADNS_SOCKET fd;
549 
550  for (i=0; i<npollfds; i++) {
551  fd= pollfds[i].fd;
552  if ((int)fd >= maxfd) maxfd= fd+1;
553  revents= pollfds[i].revents;
554  fd_event(ads,fd, revents,POLLIN, maxfd,readfds, adns_processreadable,now,r_r);
555  fd_event(ads,fd, revents,POLLOUT, maxfd,writefds, adns_processwriteable,now,r_r);
556  fd_event(ads,fd, revents,POLLPRI, maxfd,exceptfds, adns_processexceptional,now,r_r);
557  }
558 }
559 
560 /* Wrappers for select(2). */
561 
562 void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io,
563  fd_set *writefds_io, fd_set *exceptfds_io,
564  struct timeval **tv_mod, struct timeval *tv_tobuf,
565  const struct timeval *now) {
566  struct timeval tv_nowbuf;
567  struct pollfd pollfds[MAX_POLLFDS];
568  int i, maxfd, npollfds;
569  ADNS_SOCKET fd;
570 
572 
573  if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) {
574  /* The caller is planning to sleep. */
575  adns__must_gettimeofday(ads,&now,&tv_nowbuf);
576  if (!now) { inter_immed(tv_mod,tv_tobuf); goto xit; }
577  adns__timeouts(ads, 0, tv_mod,tv_tobuf, *now);
578  }
579 
580  npollfds= adns__pollfds(ads,pollfds);
581  maxfd= *maxfd_io;
582  for (i=0; i<npollfds; i++) {
583  fd= pollfds[i].fd;
584  if ((int)fd >= maxfd) maxfd= fd+1;
585  if (pollfds[i].events & POLLIN) FD_SET(fd,readfds_io);
586  if (pollfds[i].events & POLLOUT) FD_SET(fd,writefds_io);
587  if (pollfds[i].events & POLLPRI) FD_SET(fd,exceptfds_io);
588  }
589  *maxfd_io= maxfd;
590 
591 xit:
593 }
594 
595 void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds,
596  const fd_set *writefds, const fd_set *exceptfds,
597  const struct timeval *now) {
598  struct timeval tv_buf;
599  struct pollfd pollfds[MAX_POLLFDS];
600  int npollfds, i;
601 
603  adns__must_gettimeofday(ads,&now,&tv_buf);
604  if (!now) goto xit;
606 
607  npollfds= adns__pollfds(ads,pollfds);
608  for (i=0; i<npollfds; i++) pollfds[i].revents= POLLIN|POLLOUT|POLLPRI;
610  pollfds,npollfds,
611  maxfd,readfds,writefds,exceptfds,
612  *now, 0);
613 xit:
615 }
616 
617 /* General helpful functions. */
618 
621 
622  while (ads->udpw.head) adns__query_fail(ads->udpw.head, adns_s_systemfail);
623  while (ads->tcpw.head) adns__query_fail(ads->tcpw.head, adns_s_systemfail);
624 
625  switch (ads->tcpstate) {
626  case server_connecting:
627  case server_ok:
628  adns__tcp_broken(ads,0,0);
629  break;
630  case server_disconnected:
631  case server_broken:
632  break;
633  default:
634  abort();
635  }
637 }
638 
640  int r, i;
641  struct timeval now;
642  struct pollfd pollfds[MAX_POLLFDS];
643  int npollfds;
644 
646 
647  r= gettimeofday(&now,0);
648  if (!r) adns_processtimeouts(ads,&now);
649 
650  /* We just use adns__fdevents to loop over the fd's trying them.
651  * This seems more sensible than calling select, since we're most
652  * likely just to want to do a adns_socket_read on one or two fds anyway.
653  */
654  npollfds= adns__pollfds(ads,pollfds);
655  for (i=0; i<npollfds; i++) pollfds[i].revents= pollfds[i].events & ~POLLPRI;
657  pollfds,npollfds,
658  0,0,0,0,
659  now,&r);
660 
662  return 0;
663 }
664 
666  if (ads->iflags & adns_if_noautosys) return;
668 }
669 
671  adns_query *query_io,
672  adns_answer **answer,
673  void **context_r) {
674  adns_query qu;
675 
676  qu= *query_io;
677  if (!qu) {
678  if (ads->output.head) {
679  qu= ads->output.head;
680  } else if (ads->udpw.head || ads->tcpw.head) {
681  return EAGAIN;
682  } else {
683  return ESRCH;
684  }
685  } else {
686  if (qu->id>=0) return EAGAIN;
687  }
688  LIST_UNLINK(ads->output,qu);
689  *answer= qu->answer;
690  if (context_r) *context_r= qu->ctx.ext;
691  *query_io= qu;
692  free(qu);
693  return 0;
694 }
695 
697  adns_query *query_io,
698  adns_answer **answer_r,
699  void **context_r) {
700  int r, maxfd, rsel;
701  fd_set readfds, writefds, exceptfds;
702  struct timeval tvbuf, *tvp;
703 
704  adns__consistency(ads,*query_io,cc_entex);
705  for (;;) {
706  r= adns__internal_check(ads,query_io,answer_r,context_r);
707  if (r != EAGAIN) break;
708  maxfd= 0; tvp= 0;
709  FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
710  adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0);
711  assert(tvp);
713  rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp);
715  if (rsel==-1) {
716  if (errno == EINTR) {
717  if (ads->iflags & adns_if_eintr) { r= EINTR; break; }
718  } else {
719  adns__diag(ads,-1,0,"select failed in wait: %s",strerror(errno));
721  }
722  } else {
723  assert(rsel >= 0);
724  adns_afterselect(ads,maxfd,&readfds,&writefds,&exceptfds,0);
725  }
726  }
728  return r;
729 }
730 
732  adns_query *query_io,
733  adns_answer **answer_r,
734  void **context_r) {
735  struct timeval now;
736  int r;
737 
738  adns__consistency(ads,*query_io,cc_entex);
739  r= gettimeofday(&now,0);
740  if (!r) adns__autosys(ads,now);
741 
742  r= adns__internal_check(ads,query_io,answer_r,context_r);
744  return r;
745 }
Definition: winsock.h:66
GLenum func
Definition: glext.h:6028
INT WSAAPI recvfrom(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags, OUT LPSOCKADDR from, IN OUT INT FAR *fromlen)
Definition: recv.c:87
int adns_processwriteable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:443
static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime)
Definition: event.c:188
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define DNS_PORT
Definition: internal.h:72
static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf)
Definition: event.c:162
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
adns_state ads
Definition: adh-query.c:35
void adns__fdevents(adns_state ads, const struct pollfd *pollfds, int npollfds, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, struct timeval now, int *r_r)
Definition: event.c:542
#define ADNS_SOCKET
Definition: adns_win32.h:98
adns_initflags iflags
Definition: internal.h:292
static void tcp_close(adns_state ads)
Definition: event.c:50
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define free
Definition: debug_ros.c:5
int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS])
Definition: event.c:312
int nservers
Definition: internal.h:300
#define EINTR
Definition: acclib.h:80
unsigned long tv_sec
Definition: linux.h:1738
vbuf tcprecv
Definition: internal.h:299
ADNS_SOCKET udpsocket
Definition: internal.h:298
int adns_processexceptional(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:504
LPPROTOENT WSAAPI getprotobyname(IN CONST CHAR FAR *name)
Definition: getproto.c:305
void adns_globalsystemfailure(adns_state ads)
Definition: event.c:619
#define assert(x)
Definition: debug.h:53
int retries
Definition: internal.h:227
static int fd
Definition: io.c:51
void adns__querysend_tcp(adns_query qu, struct timeval now)
Definition: transmit.c:168
int avail
Definition: internal.h:111
#define EINPROGRESS
Definition: errno.h:126
void adns__sigpipe_unprotect(adns_state ads)
Definition: general.c:360
int errno
#define FD_ZERO(set)
Definition: winsock.h:96
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf)
Definition: event.c:149
#define FD_SET(fd, set)
Definition: winsock.h:89
const char * strerror(int err)
Definition: compat_str.c:23
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
static int errno_resources(int e)
Definition: internal.h:707
Definition: arc.h:48
#define ntohs(x)
Definition: module.h:208
int tcpserver
Definition: internal.h:300
void adns_processtimeouts(adns_state ads, const struct timeval *now)
Definition: event.c:299
#define ESRCH
Definition: errno.h:9
int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:731
void adns__timeouts(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:283
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int adns__vbuf_ensure(vbuf *vb, int want)
Definition: general.c:116
#define FD_ISSET(fd, set)
Definition: winsock.h:100
#define ECONNRESET
Definition: errno.h:115
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:102
time_t now
Definition: finger.c:65
#define EWOULDBLOCK
Definition: errno.h:42
struct timeval timeout
Definition: internal.h:230
void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:86
Definition: _queue.h:59
void adns_firsttimeout(adns_state ads, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:291
unsigned long tv_usec
Definition: linux.h:1739
void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:94
int tcprecv_skip
Definition: internal.h:300
#define LIST_UNLINK(list, node)
Definition: dlist.h:50
Definition: arc.h:35
long quot
Definition: stdlib.h:56
vbuf tcpsend
Definition: internal.h:299
#define TCPCONNMS
Definition: internal.h:68
#define ADNS_CLEAR_ERRNO
Definition: adns_win32.h:108
static void timevaladd(struct timeval *tv_io, long ms)
Definition: tvarith.h:31
#define inet_ntoa(addr)
Definition: inet.h:100
void * ext
Definition: internal.h:173
void adns__tcp_tryconnect(adns_state ads, struct timeval now)
Definition: event.c:90
adns_query next
Definition: internal.h:184
qcontext ctx
Definition: internal.h:233
int adns__internal_check(adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r)
Definition: event.c:670
struct adns__state::server servers[MAXSERVERS]
_Check_return_ ldiv_t __cdecl ldiv(_In_ long _Numerator, _In_ long _Denominator)
int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:696
adns_answer * answer
Definition: internal.h:201
void adns__tcp_broken(adns_state ads, const char *what, const char *why)
Definition: event.c:59
static void tcp_connected(adns_state ads, struct timeval now)
Definition: event.c:78
enum adns__query::@3856 state
struct timeval tcptimeout
Definition: internal.h:305
#define POLLIN
Definition: linux.h:1853
Definition: linux.h:1867
#define POLLPRI
Definition: linux.h:1854
ADNS_SOCKET tcpsocket
Definition: internal.h:298
Definition: stdlib.h:55
#define DNS_MAXUDP
Definition: internal.h:73
GLenum const GLvoid * addr
Definition: glext.h:9621
#define adns_socket_close(sck)
Definition: adns_win32.h:99
int adns_processany(adns_state ads)
Definition: event.c:639
void adns__autosys(adns_state ads, struct timeval now)
Definition: event.c:665
int adns_processreadable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:338
#define MAX_POLLFDS
Definition: internal.h:82
int fd
Definition: linux.h:1868
byte * buf
Definition: internal.h:112
#define abort()
Definition: i386-dis.c:35
#define ADNS_CAPTURE_ERRNO
Definition: adns_win32.h:107
int used
Definition: internal.h:111
static void timeouts_queue(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct query_queue *queue)
Definition: event.c:205
short revents
Definition: linux.h:1870
void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc)
Definition: check.c:185
HANDLE events[2]
Definition: event.c:4
#define timercmp(tvp, uvp, cmp)
Definition: rdesktop.h:184
void adns__query_send(adns_query qu, struct timeval now)
Definition: transmit.c:232
struct query_queue udpw tcpw childw output
Definition: internal.h:295
#define AF_INET
Definition: tcpip.h:117
void adns__query_fail(adns_query qu, adns_status stat)
Definition: query.c:547
#define adns_socket_write(sck, data, len)
Definition: adns_win32.h:101
void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io, fd_set *writefds_io, fd_set *exceptfds_io, struct timeval **tv_mod, struct timeval *tv_tobuf, const struct timeval *now)
Definition: event.c:562
int adns__setnonblock(adns_state ads, ADNS_SOCKET fd)
Definition: setup.c:457
#define SOCK_STREAM
Definition: tcpip.h:118
void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, const struct timeval *now)
Definition: event.c:595
#define htons(x)
Definition: module.h:213
void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv, int viatcp, struct timeval now)
Definition: reply.c:36
void adns__sigpipe_protect(adns_state ads)
Definition: general.c:340
#define memset(x, y, z)
Definition: compat.h:39
#define timerclear(tvp)
Definition: rdesktop.h:190
#define POLLOUT
Definition: linux.h:1855
static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, struct timeval maxto)
Definition: event.c:173
static void fd_event(adns_state ads, ADNS_SOCKET fd, int revent, int pollflag, int maxfd, const fd_set *fds, int(*func)(adns_state, ADNS_SOCKET fd, const struct timeval *now), struct timeval now, int *r_r)
Definition: event.c:522
enum adns__state::adns__tcpstate tcpstate
static void tcp_events(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:227
#define TCPIDLEMS
Definition: internal.h:69
#define adns_socket_read(sck, data, len)
Definition: adns_win32.h:100