From 940356bdf463f1decefb2c8d63dd33d7276d5991 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 26 Sep 1999 18:59:34 +0000 Subject: [PATCH] Changes from Tony Finch: poll-using option and bugfix for adnslogres; new adns_wait_poll function. --- changelog | 1 + client/adnslogres.c | 75 ++++++++++++++++++++++++++++++++------------- client/adnstest.c | 18 +---------- src/adns.h | 6 ++++ src/event.c | 12 ++++---- src/internal.h | 4 +++ src/poll.c | 34 ++++++++++++++++++++ 7 files changed, 105 insertions(+), 45 deletions(-) diff --git a/changelog b/changelog index 9365d2a..f161310 100644 --- a/changelog +++ b/changelog @@ -5,6 +5,7 @@ adns (0.5) unstable; urgency=medium Thanks to Tony Finch for the program and the performance figure. * New adnshost utility - currently only a usage message :-). * New internal consistency checking with assert if right options set. + * New adns_wait_poll function like adns_wait but uses poll, not select. Incompatible changes: * RRs with mailboxes never rejected due to strange chars if _raw. diff --git a/client/adnslogres.c b/client/adnslogres.c index 814ad62..bf17cca 100644 --- a/client/adnslogres.c +++ b/client/adnslogres.c @@ -31,6 +31,7 @@ static const char * const cvsid = #include #include +#include #include #include #include @@ -45,6 +46,10 @@ static const char * const cvsid = /* maximum length of a line */ #define MAXLINE 1024 +/* option flags */ +#define OPT_DEBUG 1 +#define OPT_POLL 2 + static const char *progname; static void aargh(const char *msg) { @@ -56,19 +61,25 @@ static void aargh(const char *msg) { /* * Parse the IP address and convert to a reverse domain name. */ -static void ipaddr2domain(char *start, char **addr, char **rest, char **domain) { +static char *ipaddr2domain(char *start, char **addr, char **rest) { static char buf[30]; /* "123.123.123.123.in-addr.arpa.\0" */ char *ptrs[5]; int i; - for (ptrs[0]= start; !isdigit(*ptrs[0]); ptrs[0]++) - if (!*ptrs[0]) - goto invalid; + ptrs[0]= start; +retry: + while (!isdigit(*ptrs[0])) + if (!*ptrs[0]++) { + strcpy(buf, "invalid."); + *addr= *rest= NULL; + return buf; + } for (i= 1; i < 5; i ++) { ptrs[i]= strchr(ptrs[i-1], (i == 4) ? ' ' : '.'); - if (!ptrs[i] || ptrs[i]-ptrs[i-1] > 3) - goto invalid; - else + if (!ptrs[i] || ptrs[i]-ptrs[i-1] > 3) { + ptrs[0]++; + goto retry; + } else ptrs[i]++; } sprintf(buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.", @@ -78,13 +89,7 @@ static void ipaddr2domain(char *start, char **addr, char **rest, char **domain) ptrs[1]-ptrs[0]-1, ptrs[0]); *addr= ptrs[0]; *rest= ptrs[4]-1; - *domain= buf; - return; -invalid: - strcpy(buf, "invalid."); - *addr= *rest= NULL; - *domain= buf; - return; + return buf; } static void printline(char *start, char *addr, char *rest, char *domain) { @@ -101,7 +106,7 @@ typedef struct logline { adns_query query; } logline; -static logline *readline(adns_state adns) { +static logline *readline(adns_state adns, int opts) { static char buf[MAXLINE]; char *str; logline *line; @@ -113,7 +118,9 @@ static logline *readline(adns_state adns) { line->next= NULL; line->start= str+sizeof(logline); strcpy(line->start, buf); - ipaddr2domain(line->start, &line->addr, &line->rest, &str); + str = ipaddr2domain(line->start, &line->addr, &line->rest); + if (opts & OPT_DEBUG) + fprintf(stderr, "%s: adns_submit %s\n", progname, str); if (adns_submit(adns, str, adns_r_ptr, adns_qf_quoteok_cname|adns_qf_cname_loose, NULL, &line->query)) @@ -125,19 +132,22 @@ static logline *readline(adns_state adns) { return NULL; } -static void proclog(void) { +static void proclog(int opts) { int eof, err, len; adns_state adns; adns_answer *answer; logline *head, *tail, *line; - errno= adns_init(&adns, 0, 0); + errno= adns_init(&adns, (opts & OPT_DEBUG) ? adns_if_debug : 0, 0); if (errno) aargh("adns_init"); - head= tail= readline(adns); + head= tail= readline(adns, opts); len= 1; eof= 0; while (head) { if (eof || len > MAXPENDING) - err= adns_wait(adns, &head->query, &answer, NULL); + if (opts & OPT_POLL) + err= adns_wait_poll(adns, &head->query, &answer, NULL); + else + err= adns_wait(adns, &head->query, &answer, NULL); else err= adns_check(adns, &head->query, &answer, NULL); if (err != EWOULDBLOCK) { @@ -148,7 +158,7 @@ static void proclog(void) { len--; } if (!eof) { - line= readline(adns); + line= readline(adns, opts); if (!line) eof= 1; else { @@ -165,8 +175,29 @@ static void proclog(void) { } int main(int argc, char *argv[]) { + int c, opts; + progname= *argv; - proclog(); + opts= 0; + + while ((c= getopt(argc, argv, "dp")) != -1) { + switch (c) { + case 'd': + opts |= OPT_DEBUG; + break; + case 'p': + opts |= OPT_POLL; + break; + default: + fprintf(stderr, "usage: %s [-d] < logfile\n", progname); + exit(1); + } + argc-= optind; + argv+= optind; + } + + proclog(opts); + if (fclose(stdout)) aargh("finish writing output"); return 0; } diff --git a/client/adnstest.c b/client/adnstest.c index c4dd6b1..91b175b 100644 --- a/client/adnstest.c +++ b/client/adnstest.c @@ -279,23 +279,7 @@ int main(int argc, char *const *argv) { } if (strchr(owninitflags,'p')) { - for (;;) { - r= adns_check(ads,&qu,&ans,&mcr); - if (r != EWOULDBLOCK) break; - for (;;) { - npollfds= npollfdsavail; - timeout= -1; - r= adns_beforepoll(ads, pollfds, &npollfds, &timeout, 0); - if (r != ERANGE) break; - pollfds= realloc(pollfds,sizeof(*pollfds)*npollfds); - if (!pollfds) failure_errno("realloc pollfds",errno); - npollfdsavail= npollfds; - } - if (r) failure_errno("beforepoll",r); - r= poll(pollfds,npollfds,timeout); - if (r == -1) failure_errno("poll",errno); - adns_afterpoll(ads,pollfds, r?npollfds:0, 0); - } + r= adns_wait_poll(ads,&qu,&ans,&mcr); } else { r= adns_wait(ads,&qu,&ans,&mcr); } diff --git a/src/adns.h b/src/adns.h index dac2f57..08033cb 100644 --- a/src/adns.h +++ b/src/adns.h @@ -336,6 +336,12 @@ int adns_wait(adns_state ads, adns_answer **answer_r, void **context_r); +/* same as adns_wait but uses poll(2) internally */ +int adns_wait_poll(adns_state ads, + adns_query *query_io, + adns_answer **answer_r, + void **context_r); + void adns_cancel(adns_query query); /* The adns_query you get back from _submit is valid (ie, can be diff --git a/src/event.c b/src/event.c index 7702fe1..c156e75 100644 --- a/src/event.c +++ b/src/event.c @@ -540,10 +540,10 @@ void adns__autosys(adns_state ads, struct timeval now) { adns_processany(ads); } -static int internal_check(adns_state ads, - adns_query *query_io, - adns_answer **answer, - void **context_r) { +int adns__internal_check(adns_state ads, + adns_query *query_io, + adns_answer **answer, + void **context_r) { adns_query qu; qu= *query_io; @@ -571,7 +571,7 @@ int adns_wait(adns_state ads, adns__consistency(ads,*query_io,cc_entex); for (;;) { - r= internal_check(ads,query_io,answer_r,context_r); + r= adns__internal_check(ads,query_io,answer_r,context_r); if (r != EWOULDBLOCK) break; maxfd= 0; tvp= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); @@ -604,7 +604,7 @@ int adns_check(adns_state ads, r= gettimeofday(&now,0); if (!r) adns__autosys(ads,now); - r= internal_check(ads,query_io,answer_r,context_r); + r= adns__internal_check(ads,query_io,answer_r,context_r); adns__consistency(ads,0,cc_entex); return r; } diff --git a/src/internal.h b/src/internal.h index 12ecd6f..b0e96c7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -639,6 +639,10 @@ void adns__fdevents(adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, struct timeval now, int *r_r); +int adns__internal_check(adns_state ads, + adns_query *query_io, + adns_answer **answer, + void **context_r); /* From check.c: */ diff --git a/src/poll.c b/src/poll.c index 7b1054a..1fe28f4 100644 --- a/src/poll.c +++ b/src/poll.c @@ -21,6 +21,7 @@ */ #include +#include #include "internal.h" @@ -89,4 +90,37 @@ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds, adns__consistency(ads,0,cc_entex); } +int adns_wait_poll(adns_state ads, + adns_query *query_io, + adns_answer **answer_r, + void **context_r) { + int r, nfds, to; + struct pollfd fds[MAX_POLLFDS]; + + adns__consistency(ads,0,cc_entex); + + for (;;) { + r= adns__internal_check(ads,query_io,answer_r,context_r); + if (r != EWOULDBLOCK) goto xit; + nfds= MAX_POLLFDS; to= -1; + adns_beforepoll(ads,fds,&nfds,&to,0); + r= poll(fds,nfds,to); + if (r == -1) { + if (errno == EINTR) { + if (ads->iflags & adns_if_eintr) { r= EINTR; goto xit; } + } else { + adns__diag(ads,-1,0,"poll failed in wait: %s",strerror(errno)); + adns_globalsystemfailure(ads); + } + } else { + assert(r >= 0); + adns_afterpoll(ads,fds,nfds,0); + } + } + + xit: + adns__consistency(ads,0,cc_entex); + return r; +} + #endif -- 2.30.2