summaryrefslogtreecommitdiffstats
path: root/rfc1035
diff options
context:
space:
mode:
authorSam Varshavchik2020-04-07 00:05:02 -0400
committerSam Varshavchik2020-04-07 00:06:31 -0400
commit9cef0af75486f68720a813b03ec8e69848c6b04a (patch)
tree3e622d22162ae4bb278c1efe20e920dfca9967ae /rfc1035
parente7b9dfe7c3f940625941ca725d403677c744c671 (diff)
downloadcourier-libs-9cef0af75486f68720a813b03ec8e69848c6b04a.tar.bz2
Refactor rfc1035_query_udp (2/2).
Adds rfc1035_udp_query_multi(). rfc1035_query_udp is just a wrapper for it, now.
Diffstat (limited to 'rfc1035')
-rw-r--r--rfc1035/rfc1035.h19
-rw-r--r--rfc1035/rfc1035udp.c67
-rw-r--r--rfc1035/testlookup.c3
3 files changed, 61 insertions, 28 deletions
diff --git a/rfc1035/rfc1035.h b/rfc1035/rfc1035.h
index 9884677..2123c2a 100644
--- a/rfc1035/rfc1035.h
+++ b/rfc1035/rfc1035.h
@@ -646,6 +646,25 @@ rfc1035_udp_query_response_alloc(const char **queries,
int n_queries);
/*
+** Send all queries via UDPs, wait for responses.
+**
+** Returns non-0 if all queries are received, 0 if not. EAGAIN indicates
+** a timeout, and this can be called again with the same
+** rfc1035_udp_query_responses object; this resends all queries for which
+** no response was received, and this will wait for the remaining responses.
+*/
+int rfc1035_udp_query_multi(struct rfc1035_res *res,
+ /* Socket: */
+ int fd,
+ /* Where to send it to */
+ const struct sockaddr *sin, int sin_len,
+ /* The queries */
+ struct rfc1035_udp_query_responses *qr,
+
+ /* How long to wait for responses, in seconds. */
+ unsigned w);
+
+/*
** Deallocate rfc1035_udp_query_responses. Each non-NULL response pointer
** gets free()d.
*/
diff --git a/rfc1035/rfc1035udp.c b/rfc1035/rfc1035udp.c
index 91fbe3c..c128efd 100644
--- a/rfc1035/rfc1035udp.c
+++ b/rfc1035/rfc1035udp.c
@@ -195,60 +195,73 @@ unsigned buflen=sizeof(rfc1035_buf);
return (0);
}
-static char *rfc1035_recv_udp(int fd,
- const struct sockaddr *addrshouldfrom, int addrshouldfrom_len,
- int *buflen, const char *query,
- unsigned query_len)
+char *rfc1035_query_udp(struct rfc1035_res *res,
+ int fd, const struct sockaddr *sin, int sin_len,
+ const char *query, unsigned query_len, int *buflen, unsigned w)
{
struct rfc1035_udp_query_responses *resps=
rfc1035_udp_query_response_alloc(&query, &query_len, 1);
+ char *bufptr=0;
if (!resps)
return 0;
- if (rfc1035_recv_one_udp_response(fd,
- addrshouldfrom,
- addrshouldfrom_len,
- resps))
+ if (rfc1035_udp_query_multi(res, fd, sin, sin_len, resps, w))
{
- char *bufptr=resps->queries[0].response;
-
+ bufptr=resps->queries[0].response;
*buflen=resps->queries[0].resplen;
-
resps->queries[0].response=0;
- rfc1035_udp_query_response_free(resps);
- return bufptr;
}
rfc1035_udp_query_response_free(resps);
-
- return NULL;
+ return bufptr;
}
-char *rfc1035_query_udp(struct rfc1035_res *res,
- int fd, const struct sockaddr *sin, int sin_len,
- const char *query, unsigned query_len, int *buflen, unsigned w)
+int rfc1035_udp_query_multi(struct rfc1035_res *res,
+ int fd, const struct sockaddr *sin, int sin_len,
+ struct rfc1035_udp_query_responses *qr,
+ unsigned w)
{
time_t current_time, final_time;
-char *rc;
+int i;
time(&current_time);
- if (rfc1035_send_udp(fd, sin, sin_len, query, query_len))
- return (0);
+ for (i=0; i<qr->n_queries; ++i)
+ {
+ if (qr->queries[i].response)
+ continue; /* Already sent it */
+ if (rfc1035_send_udp(fd, sin, sin_len,
+ qr->queries[i].query,
+ qr->queries[i].querylen))
+ return (0);
+ }
final_time=current_time+w;
- while (current_time < final_time)
+ while (1)
{
- if (rfc1035_wait_reply(fd, final_time-current_time))
+ for (i=0; i<qr->n_queries; ++i)
+ if (!qr->queries[i].response)
+ break;
+
+ if (i == qr->n_queries)
+ return 1; /* Everything received */
+
+ if (current_time >= final_time)
break;
- rc=rfc1035_recv_udp(fd, sin, sin_len, buflen,
- query, query_len);
- if (rc) return (rc);
+ if (rfc1035_wait_reply(fd, final_time-current_time))
+ break;
- if (errno != EAGAIN) break;
+ if (!rfc1035_recv_one_udp_response(fd,
+ sin,
+ sin_len,
+ qr))
+ {
+ if (errno != EAGAIN)
+ return 0;
+ }
time(&current_time);
}
diff --git a/rfc1035/testlookup.c b/rfc1035/testlookup.c
index a406411..cd99c81 100644
--- a/rfc1035/testlookup.c
+++ b/rfc1035/testlookup.c
@@ -36,6 +36,7 @@ char *q=malloc(strlen(p)+1), *r;
r);
}
}
+ free(q);
rfc1035_init_ns(res, ia, i);
}
@@ -227,7 +228,7 @@ char ptrbuf[RFC1035_MAXNAMESIZE+1];
fprintf(stderr, "%s error.\n", errno == ENOENT ? "Hard":"Soft");
exit(1);
}
-
+
q_type= -1;
if (argn < argc)