diff options
| -rw-r--r-- | rfc1035/rfc1035.h | 19 | ||||
| -rw-r--r-- | rfc1035/rfc1035udp.c | 67 | ||||
| -rw-r--r-- | rfc1035/testlookup.c | 3 | 
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(¤t_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(¤t_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) | 
