ReactOS 0.4.16-dev-199-g898cc56
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
50static void tcp_close(adns_state ads) {
51 int serv;
52
53 serv= ads->tcpserver;
55 ads->tcpsocket= -1;
57}
58
59void 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
74 ads->tcpstate= server_broken;
75 ads->tcpserver= (serv+1)%ads->nservers;
76}
77
78static 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
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) {
140 return;
141 }
143 ads->tcpstate= server_disconnected;
144 }
145}
146
147/* Timeout handling functions. */
148
149void 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
162static 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
173static 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
188static 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
205static 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 {
221 }
222 nqu= queue->head;
223 }
224 }
225}
226
227static 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);
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
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
312int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) {
313 /* Returns the number of entries filled in. Always zeroes revents. */
314
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;
438xit:
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);
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;
491 }
492 }
493 r= 0;
494 goto xit;
495 default:
496 abort();
497 }
498 r= 0;
499xit:
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;
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
562void 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;
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
591xit:
593}
594
595void 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
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);
613xit:
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:
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);
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 }
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}
void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc)
Definition: check.c:185
#define EINTR
Definition: acclib.h:80
#define ENOMEM
Definition: acclib.h:84
#define EAGAIN
Definition: acclib.h:83
adns_state ads
Definition: adh-query.c:35
@ adns_if_noautosys
Definition: adns.h:93
@ adns_if_eintr
Definition: adns.h:94
@ adns_s_timeout
Definition: adns.h:226
@ adns_s_allservfail
Definition: adns.h:227
@ adns_s_systemfail
Definition: adns.h:221
#define adns_socket_write(sck, data, len)
Definition: adns_win32.h:101
#define ADNS_SOCKET
Definition: adns_win32.h:98
#define adns_socket_read(sck, data, len)
Definition: adns_win32.h:100
#define ADNS_CLEAR_ERRNO
Definition: adns_win32.h:108
#define adns_socket_close(sck)
Definition: adns_win32.h:99
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
#define ADNS_CAPTURE_ERRNO
Definition: adns_win32.h:107
#define timercmp(tvp, uvp, cmp)
Definition: rdesktop.h:184
#define timerclear(tvp)
Definition: rdesktop.h:190
Definition: _queue.h:67
#define free
Definition: debug_ros.c:5
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 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
#define assert(x)
Definition: debug.h:53
#define ESRCH
Definition: errno.h:9
#define EWOULDBLOCK
Definition: errno.h:42
#define EINPROGRESS
Definition: errno.h:126
#define ECONNRESET
Definition: errno.h:115
#define POLLIN
Definition: linux.h:1853
#define POLLOUT
Definition: linux.h:1855
#define POLLPRI
Definition: linux.h:1854
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
time_t now
Definition: finger.c:65
LPPROTOENT WSAAPI getprotobyname(IN CONST CHAR FAR *name)
Definition: getproto.c:305
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum func
Definition: glext.h:6028
GLenum const GLvoid * addr
Definition: glext.h:9621
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
#define abort()
Definition: i386-dis.c:34
_Check_return_ ldiv_t __cdecl ldiv(_In_ long _Numerator, _In_ long _Denominator)
#define inet_ntoa(addr)
Definition: inet.h:100
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
HANDLE events[2]
Definition: event.c:4
const char * strerror(int err)
Definition: compat_str.c:23
#define errno
Definition: errno.h:18
#define LIST_UNLINK(list, node)
Definition: dlist.h:50
int adns_processexceptional(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:504
void adns__timeouts(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:283
static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, struct timeval maxto)
Definition: event.c:173
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
int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:731
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
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
static void tcp_close(adns_state ads)
Definition: event.c:50
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf)
Definition: event.c:149
int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:696
static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime)
Definition: event.c:188
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
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
void adns__tcp_broken(adns_state ads, const char *what, const char *why)
Definition: event.c:59
static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf)
Definition: event.c:162
void adns__autosys(adns_state ads, struct timeval now)
Definition: event.c:665
int adns_processany(adns_state ads)
Definition: event.c:639
static void tcp_connected(adns_state ads, struct timeval now)
Definition: event.c:78
int adns_processwriteable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:443
void adns_globalsystemfailure(adns_state ads)
Definition: event.c:619
void adns_processtimeouts(adns_state ads, const struct timeval *now)
Definition: event.c:299
int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS])
Definition: event.c:312
void adns__tcp_tryconnect(adns_state ads, struct timeval now)
Definition: event.c:90
int adns__internal_check(adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r)
Definition: event.c:670
int adns_processreadable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:338
static void tcp_events(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:227
void adns_firsttimeout(adns_state ads, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:291
void adns__sigpipe_protect(adns_state ads)
Definition: general.c:340
void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:86
void adns__sigpipe_unprotect(adns_state ads)
Definition: general.c:360
void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:94
int adns__vbuf_ensure(vbuf *vb, int want)
Definition: general.c:116
void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:102
#define MAX_POLLFDS
Definition: internal.h:82
void adns__querysend_tcp(adns_query qu, struct timeval now)
Definition: transmit.c:168
#define TCPIDLEMS
Definition: internal.h:69
#define DNS_MAXUDP
Definition: internal.h:73
static int errno_resources(int e)
Definition: internal.h:707
void adns__query_fail(adns_query qu, adns_status stat)
Definition: query.c:547
@ cc_entex
Definition: internal.h:86
int adns__setnonblock(adns_state ads, ADNS_SOCKET fd)
Definition: setup.c:457
#define TCPCONNMS
Definition: internal.h:68
#define DNS_PORT
Definition: internal.h:72
void adns__query_send(adns_query qu, struct timeval now)
Definition: transmit.c:232
void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv, int viatcp, struct timeval now)
Definition: reply.c:36
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: stdlib.h:43
long quot
Definition: stdlib.h:44
int retries
Definition: internal.h:227
enum adns__query::@4223 state
adns_query next
Definition: internal.h:184
struct timeval timeout
Definition: internal.h:230
adns_answer * answer
Definition: internal.h:201
qcontext ctx
Definition: internal.h:233
int nservers
Definition: internal.h:300
ADNS_SOCKET tcpsocket
Definition: internal.h:298
int tcprecv_skip
Definition: internal.h:300
enum adns__state::adns__tcpstate tcpstate
vbuf tcprecv
Definition: internal.h:299
struct query_queue udpw tcpw childw output
Definition: internal.h:295
ADNS_SOCKET udpsocket
Definition: internal.h:298
struct timeval tcptimeout
Definition: internal.h:305
struct adns__state::server servers[MAXSERVERS]
adns_initflags iflags
Definition: internal.h:292
int tcpserver
Definition: internal.h:300
vbuf tcpsend
Definition: internal.h:299
Definition: winsock.h:66
Definition: linux.h:1867
int fd
Definition: linux.h:1868
short revents
Definition: linux.h:1870
void * ext
Definition: internal.h:173
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
int avail
Definition: internal.h:111
int used
Definition: internal.h:111
byte * buf
Definition: internal.h:112
static void timevaladd(struct timeval *tv_io, long ms)
Definition: tvarith.h:31
#define FD_ISSET(fd, set)
Definition: winsock.h:100
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89