#include <dns.h>
dns_transmit_start(&dt,s,flagrecursive,q,t,localip);
dns_transmit_io(&dt,x,&deadline);
dns_transmit_get(&dt,x,&stamp);
dns_transmit_free(&dt);
struct dns_transmit dt = {0};
char s[64];
int flagrecursive;
char *q;
char t[2];
char localip[4];
iopause_fd x[1];
struct taia deadline;
struct taia stamp;
The dns_transmit functions send a DNS query to some DNS servers.
They save the first useful response inside dt.
The query asks for Internet records of type t for the domain name packet-encoded in q. It requests server recursion if flagrecursive is nonzero.
The IP addresses of the DNS servers are listed in s. The dns_transmit functions skip IP addresses of 0.0.0.0. The dns_transmit functions record only a pointer to the contents of s, not a copy of s, so you must leave s in place and unchanged.
The dns_transmit functions send outgoing packets from a local IP address of localip.
The dns_transmit functions act asynchronously. They are designed to be used in an iopause event loop:
if (dns_transmit_start(&dt,s,flagrecursive,q,t,localip) == -1)
return -1;
for (;;) {
int r;
taia_now(&stamp);
taia_uint(&deadline,120);
taia_add(&deadline,&deadline,&stamp);
dns_transmit_io(&dt,x,&deadline);
iopause(x,1,&deadline,&stamp);
r = dns_transmit_get(&dt,x,&stamp);
if (r == -1) return -1;
if (r == 1) break;
}
dosomething(dt.packet,dt.packetlen);
dns_transmit_free(&dt);
return 0;
dns_transmit_start begins the query;
it returns 0 on success, or -1 on failure.
dns_transmit_get continues the query;
it returns 1 if the response has arrived,
0 if the response has not yet arrived,
or -1 on failure.
Here ``failure'' means
a socket creation failure,
a memory allocation failure,
a timeout after the final query attempt,
an empty list of servers (reported as EIO),
a query longer than 65535 bytes (reported as EIO),
a malformed response to the final query attempt (reported as EIO),
or a server declaration of failure
in response to the final query attempt (reported as EAGAIN).
The dns_transmit functions communicate through dt. They dynamically allocate a socket for network communication, memory for the DNS request, and memory for the DNS response; these resources are freed when you call dns_transmit_free, or when you call dns_transmit_start again with the same dt to handle another query. You must zero-initialize dt before calling dns_transmit_start the first time.
If dns_transmit_get returns 1, the DNS response is a byte string of length dt.packetlen; dt.packet points to the first byte. The IP address of the server that provided the response is stored at dt.servers + 4 * dt.curserver.
dns_transmit_get does not always return the first packet it sees: