ReactOS 0.4.15-dev-7788-g1ad9096
event.c File Reference
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "internal.h"
#include "tvarith.h"
Include dependency graph for event.c:

Go to the source code of this file.

Functions

static void tcp_close (adns_state ads)
 
void adns__tcp_broken (adns_state ads, const char *what, const char *why)
 
static void tcp_connected (adns_state ads, struct timeval now)
 
void adns__tcp_tryconnect (adns_state ads, struct timeval now)
 
void adns__must_gettimeofday (adns_state ads, const struct timeval **now_io, struct timeval *tv_buf)
 
static void inter_immed (struct timeval **tv_io, struct timeval *tvbuf)
 
static void inter_maxto (struct timeval **tv_io, struct timeval *tvbuf, struct timeval maxto)
 
static void inter_maxtoabs (struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime)
 
static void timeouts_queue (adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct query_queue *queue)
 
static void tcp_events (adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
 
void adns__timeouts (adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
 
void adns_firsttimeout (adns_state ads, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
 
void adns_processtimeouts (adns_state ads, const struct timeval *now)
 
int adns__pollfds (adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS])
 
int adns_processreadable (adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
 
int adns_processwriteable (adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
 
int adns_processexceptional (adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
 
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)
 
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)
 
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)
 
void adns_afterselect (adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, const struct timeval *now)
 
void adns_globalsystemfailure (adns_state ads)
 
int adns_processany (adns_state ads)
 
void adns__autosys (adns_state ads, struct timeval now)
 
int adns__internal_check (adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r)
 
int adns_wait (adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
 
int adns_check (adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
 

Function Documentation

◆ adns__autosys()

void adns__autosys ( adns_state  ads,
struct timeval  now 
)

Definition at line 665 of file event.c.

665 {
666 if (ads->iflags & adns_if_noautosys) return;
668}
adns_state ads
Definition: adh-query.c:35
@ adns_if_noautosys
Definition: adns.h:93
int adns_processany(adns_state ads)
Definition: event.c:639
adns_initflags iflags
Definition: internal.h:292

Referenced by adns_check(), and adns_submit().

◆ adns__fdevents()

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 at line 542 of file event.c.

546 {
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}
#define ADNS_SOCKET
Definition: adns_win32.h:98
#define POLLIN
Definition: linux.h:1853
#define POLLOUT
Definition: linux.h:1855
#define POLLPRI
Definition: linux.h:1854
time_t now
Definition: finger.c:65
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_processexceptional(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:504
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
int adns_processwriteable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:443
int adns_processreadable(adns_state ads, ADNS_SOCKET fd, const struct timeval *now)
Definition: event.c:338
static int fd
Definition: io.c:51
int fd
Definition: linux.h:1868
short revents
Definition: linux.h:1870

Referenced by adns_afterselect(), and adns_processany().

◆ adns__internal_check()

int adns__internal_check ( adns_state  ads,
adns_query query_io,
adns_answer **  answer,
void **  context_r 
)

Definition at line 670 of file event.c.

673 {
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}
#define EAGAIN
Definition: acclib.h:83
#define free
Definition: debug_ros.c:5
#define ESRCH
Definition: errno.h:9
#define LIST_UNLINK(list, node)
Definition: dlist.h:50
adns_answer * answer
Definition: internal.h:201
qcontext ctx
Definition: internal.h:233
struct query_queue udpw tcpw childw output
Definition: internal.h:295
void * ext
Definition: internal.h:173

Referenced by adns_check(), and adns_wait().

◆ adns__must_gettimeofday()

void adns__must_gettimeofday ( adns_state  ads,
const struct timeval **  now_io,
struct timeval tv_buf 
)

Definition at line 149 of file event.c.

150 {
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}
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const char * strerror(int err)
Definition: compat_str.c:23
#define errno
Definition: errno.h:18
void adns_globalsystemfailure(adns_state ads)
Definition: event.c:619
void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:102

Referenced by adns_afterselect(), adns_beforeselect(), and adns_processtimeouts().

◆ adns__pollfds()

int adns__pollfds ( adns_state  ads,
struct pollfd  pollfds_buf[MAX_POLLFDS] 
)

Definition at line 312 of file event.c.

312 {
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:
330 break;
331 default:
332 abort();
333 }
334 pollfds_buf[1].fd= ads->tcpsocket;
335 return 2;
336}
#define assert(x)
Definition: debug.h:53
#define abort()
Definition: i386-dis.c:34
#define MAX_POLLFDS
Definition: internal.h:82
ADNS_SOCKET tcpsocket
Definition: internal.h:298
enum adns__state::adns__tcpstate tcpstate
ADNS_SOCKET udpsocket
Definition: internal.h:298
vbuf tcpsend
Definition: internal.h:299
short events
Definition: linux.h:1869
int used
Definition: internal.h:111

Referenced by adns_afterselect(), adns_beforeselect(), and adns_processany().

◆ adns__tcp_broken()

void adns__tcp_broken ( adns_state  ads,
const char what,
const char why 
)

Definition at line 59 of file event.c.

59 {
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}
static void tcp_close(adns_state ads)
Definition: event.c:50
void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:94
int retries
Definition: internal.h:227
adns_query next
Definition: internal.h:184
int nservers
Definition: internal.h:300
int tcpserver
Definition: internal.h:300

Referenced by adns__querysend_tcp(), adns__tcp_tryconnect(), adns_globalsystemfailure(), adns_processexceptional(), adns_processreadable(), adns_processwriteable(), and tcp_events().

◆ adns__tcp_tryconnect()

void adns__tcp_tryconnect ( adns_state  ads,
struct timeval  now 
)

Definition at line 90 of file event.c.

90 {
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}
#define ADNS_CLEAR_ERRNO
Definition: adns_win32.h:108
#define adns_socket_close(sck)
Definition: adns_win32.h:99
#define ADNS_CAPTURE_ERRNO
Definition: adns_win32.h:107
#define EWOULDBLOCK
Definition: errno.h:42
#define EINPROGRESS
Definition: errno.h:126
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
LPPROTOENT WSAAPI getprotobyname(IN CONST CHAR FAR *name)
Definition: getproto.c:305
GLenum const GLvoid * addr
Definition: glext.h:9621
#define htons(x)
Definition: module.h:215
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
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
#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
int tcprecv_skip
Definition: internal.h:300
vbuf tcprecv
Definition: internal.h:299
struct timeval tcptimeout
Definition: internal.h:305
struct adns__state::server servers[MAXSERVERS]
static void timevaladd(struct timeval *tv_io, long ms)
Definition: tvarith.h:31

Referenced by query_usetcp(), and tcp_events().

◆ adns__timeouts()

void adns__timeouts ( adns_state  ads,
int  act,
struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  now 
)

Definition at line 283 of file event.c.

285 {
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}
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_events(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now)
Definition: event.c:227

Referenced by adns_beforeselect(), adns_firsttimeout(), and adns_processtimeouts().

◆ adns_afterselect()

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 at line 595 of file event.c.

597 {
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}
void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc)
Definition: check.c:185
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf)
Definition: event.c:149
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_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
@ cc_entex
Definition: internal.h:86
Definition: linux.h:1867

Referenced by adns_wait(), and main().

◆ adns_beforeselect()

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 at line 562 of file event.c.

565 {
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}
HANDLE events[2]
Definition: event.c:4
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_immed(struct timeval **tv_io, struct timeval *tvbuf)
Definition: event.c:162
#define FD_SET(fd, set)
Definition: winsock.h:89

Referenced by adns_wait(), and main().

◆ adns_check()

int adns_check ( adns_state  ads,
adns_query query_io,
adns_answer **  answer_r,
void **  context_r 
)

Definition at line 731 of file event.c.

734 {
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__autosys(adns_state ads, struct timeval now)
Definition: event.c:665
int adns__internal_check(adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r)
Definition: event.c:670

Referenced by checkadnsqueries(), main(), and proclog().

◆ adns_firsttimeout()

void adns_firsttimeout ( adns_state  ads,
struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  now 
)

Definition at line 291 of file event.c.

293 {
295 adns__timeouts(ads, 0, tv_io,tvbuf, now);
297}

◆ adns_globalsystemfailure()

void adns_globalsystemfailure ( adns_state  ads)

Definition at line 619 of file event.c.

619 {
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}
@ adns_s_systemfail
Definition: adns.h:221
void adns__query_fail(adns_query qu, adns_status stat)
Definition: query.c:547

Referenced by adns__must_gettimeofday(), adns_wait(), and fd_event().

◆ adns_processany()

int adns_processany ( adns_state  ads)

Definition at line 639 of file event.c.

639 {
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}

Referenced by adns__autosys().

◆ adns_processexceptional()

int adns_processexceptional ( adns_state  ads,
ADNS_SOCKET  fd,
const struct timeval now 
)

Definition at line 504 of file event.c.

504 {
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}

Referenced by adns__fdevents().

◆ adns_processreadable()

int adns_processreadable ( adns_state  ads,
ADNS_SOCKET  fd,
const struct timeval now 
)

Definition at line 338 of file event.c.

338 {
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}
#define EINTR
Definition: acclib.h:80
#define ENOMEM
Definition: acclib.h:84
#define adns_socket_read(sck, data, len)
Definition: adns_win32.h:100
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
#define ECONNRESET
Definition: errno.h:115
#define inet_ntoa(addr)
Definition: inet.h:100
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ntohs(x)
Definition: module.h:210
int adns__vbuf_ensure(vbuf *vb, int want)
Definition: general.c:116
#define DNS_MAXUDP
Definition: internal.h:73
static int errno_resources(int e)
Definition: internal.h:707
void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv, int viatcp, struct timeval now)
Definition: reply.c:36
int avail
Definition: internal.h:111
byte * buf
Definition: internal.h:112

Referenced by adns__fdevents().

◆ adns_processtimeouts()

void adns_processtimeouts ( adns_state  ads,
const struct timeval now 
)

Definition at line 299 of file event.c.

299 {
300 struct timeval tv_buf;
301
304 if (now) adns__timeouts(ads, 1, 0,0, *now);
306}

Referenced by adns_afterselect(), and adns_processany().

◆ adns_processwriteable()

int adns_processwriteable ( adns_state  ads,
ADNS_SOCKET  fd,
const struct timeval now 
)

Definition at line 443 of file event.c.

443 {
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}
#define adns_socket_write(sck, data, len)
Definition: adns_win32.h:101
void adns__sigpipe_protect(adns_state ads)
Definition: general.c:340
void adns__sigpipe_unprotect(adns_state ads)
Definition: general.c:360

Referenced by adns__fdevents().

◆ adns_wait()

int adns_wait ( adns_state  ads,
adns_query query_io,
adns_answer **  answer_r,
void **  context_r 
)

Definition at line 696 of file event.c.

699 {
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}
@ adns_if_eintr
Definition: adns.h:94
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_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
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
Definition: winsock.h:66
#define FD_ZERO(set)
Definition: winsock.h:96

Referenced by adns_synchronous(), main(), and proclog().

◆ fd_event()

static void fd_event ( adns_state  ads,
ADNS_SOCKET  fd,
int  revent,
int  pollflag,
int  maxfd,
const fd_set fds,
int(*)(adns_state, ADNS_SOCKET fd, const struct timeval *now func,
struct timeval  now,
int r_r 
)
static

Definition at line 522 of file event.c.

526 {
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}
GLenum func
Definition: glext.h:6028
#define FD_ISSET(fd, set)
Definition: winsock.h:100

Referenced by adns__fdevents().

◆ inter_immed()

static void inter_immed ( struct timeval **  tv_io,
struct timeval tvbuf 
)
static

Definition at line 162 of file event.c.

162 {
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}
#define timerclear(tvp)
Definition: rdesktop.h:190

Referenced by adns_beforeselect(), tcp_events(), and timeouts_queue().

◆ inter_maxto()

static void inter_maxto ( struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  maxto 
)
static

Definition at line 173 of file event.c.

174 {
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}
#define timercmp(tvp, uvp, cmp)
Definition: rdesktop.h:184

Referenced by inter_maxtoabs().

◆ inter_maxtoabs()

static void inter_maxtoabs ( struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  now,
struct timeval  maxtime 
)
static

Definition at line 188 of file event.c.

189 {
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}
_Check_return_ ldiv_t __cdecl ldiv(_In_ long _Numerator, _In_ long _Denominator)
static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, struct timeval maxto)
Definition: event.c:173
Definition: stdlib.h:43
long quot
Definition: stdlib.h:44
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739

Referenced by tcp_events(), and timeouts_queue().

◆ tcp_close()

static void tcp_close ( adns_state  ads)
static

Definition at line 50 of file event.c.

50 {
51 int serv;
52
53 serv= ads->tcpserver;
55 ads->tcpsocket= -1;
57}

Referenced by adns__tcp_broken(), and tcp_events().

◆ tcp_connected()

static void tcp_connected ( adns_state  ads,
struct timeval  now 
)
static

Definition at line 78 of file event.c.

78 {
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}
void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt,...)
Definition: general.c:86
void adns__querysend_tcp(adns_query qu, struct timeval now)
Definition: transmit.c:168
enum adns__query::@4222 state

Referenced by adns__tcp_tryconnect(), and adns_processwriteable().

◆ tcp_events()

static void tcp_events ( adns_state  ads,
int  act,
struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  now 
)
static

Definition at line 227 of file event.c.

229 {
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}
@ adns_s_allservfail
Definition: adns.h:227
static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime)
Definition: event.c:188
void adns__tcp_tryconnect(adns_state ads, struct timeval now)
Definition: event.c:90
#define TCPIDLEMS
Definition: internal.h:69

Referenced by adns__timeouts().

◆ timeouts_queue()

static void timeouts_queue ( adns_state  ads,
int  act,
struct timeval **  tv_io,
struct timeval tvbuf,
struct timeval  now,
struct query_queue queue 
)
static

Definition at line 205 of file event.c.

207 {
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}
@ adns_s_timeout
Definition: adns.h:226
Definition: _queue.h:67
void adns__query_send(adns_query qu, struct timeval now)
Definition: transmit.c:232
struct timeval timeout
Definition: internal.h:230

Referenced by adns__timeouts().