22 if (byte_diff(
ip,2,V6linklocal))
return 0;
24 if (byte_equal(
d->servers + 16 * i,16,
ip))
34 if (
out[2] & 2)
return 1;
45 if ((rcode == 0) || (rcode == 3))
return 0;
46 if (rcode == 5) byte_zero(server,16);
58 if (byte_diff(
out,2,
d->nonce + 8))
return 1;
59 if (
out[4] != 0)
return 1;
60 if (
out[5] != 1)
return 1;
68 if (byte_diff(
out,2,
d->qtype))
return 1;
76 if (!
d->packet)
return;
77 alloc_free(
d->packet);
83 if (!
d->query)
return;
106 for (j = 0; j < 10; ++j) {
107 if (socket_bind(
d->s1 - 1,
d->localip,1025 +
dns_random(64510),
d->scope_id) == 0)
111 if (socket_bind(
d->s1 - 1,
d->localip,0,
d->scope_id) == 0)
121 for (j = 0; j < 10; ++j) {
122 if (socket_bind6(
d->s1 - 1,
d->localip,1025 +
dns_random(64510),
d->scope_id) == 0)
126 if (socket_bind6(
d->s1 - 1,
d->localip,0,
d->scope_id) == 0)
136 for (j = 0; j < 10; ++j) {
137 if (socket_bind4(
d->s1 - 1,
d->localip + 12,1025 +
dns_random(64510)) == 0)
141 if (socket_bind4(
d->s1 - 1,
d->localip + 12,0) == 0)
147static const int timeouts[5] = { 1, 2, 4, 8, 16 };
157 ip =
d->servers + 16 *
d->curserver;
158 if (byte_equal(
ip,16,V6localnet))
continue;
163 if (ip6_isv4mapped(
ip)) {
164 d->s1 = 1 + socket_udp4();
168 d->s1 = 1 + socket_udp6();
173 if (byte_equal(
ip,2,V6linklocal) && !
d->scope_id)
175 if (socket_connect(
d->s1 - 1,
ip,
DNSPORT,
d->scope_id) == 0)
176 if (send(
d->s1 - 1,
d->query + 2,
d->querylen - 2,0) ==
d->querylen - 2) {
179 taia_uint(&
d->deadline,timeouts[
d->udploop]);
180 taia_add(&
d->deadline,&
d->deadline,&
now);
215 ip =
d->servers + 16 *
d->curserver;
216 if (byte_equal(
ip,16,V6localnet))
continue;
219 if (ip6_isv4mapped(
ip)) {
220 d->s1 = 1 + socket_tcp4();
224 d->s1 = 1 + socket_tcp6();
230 taia_uint(&
d->deadline,10);
231 taia_add(&
d->deadline,&
d->deadline,&
now);
233 if (byte_equal(
ip,2,V6linklocal) && !
d->scope_id)
235 if (socket_connect(
d->s1 - 1,
ip,
DNSPORT,
d->scope_id) == 0) {
239 if ((errno == EINPROGRESS) || (errno == EWOULDBLOCK)) {
265 int flagrecursive,
const char *q,
const char qtype[2],
const char localip[16])
271 int flagrecursive,
const char *q,
const char qtype[2], \
272 const char localip[16],
const uint32 scopes[
QUERY_MAXNS])
283 switch (
d->tcpstate) {
284 case 0:
case 3:
case 4:
case 5:
285 x->events = IOPAUSE_READ;
288 x->events = IOPAUSE_WRITE;
292 if (taia_less(&
d->deadline,deadline))
293 *deadline =
d->deadline;
308 if (taia_less((
struct taia *)when,&
d->deadline))
return 0;
318 if (
d->tcpstate == 0) {
319 r = recv(
fd,udpbuf,
sizeof(udpbuf),0);
321 if (errno == ECONNREFUSED)
if (
d->udploop == 2)
return 0;
324 if (r + 1 >
sizeof(udpbuf))
return 0;
330 if (
serverfailed(udpbuf,r,(
char *)(
d->servers + 16 *
d->curserver))) {
331 if (
d->udploop == 2)
return 0;
337 d->packet = alloc(
d->packetlen);
339 byte_copy(
d->packet,
d->packetlen,udpbuf);
348 if (
d->tcpstate == 1) {
359 if (
d->tcpstate == 2) {
360 r = write(
fd,
d->query +
d->pos,
d->querylen -
d->pos);
363 if (
d->pos ==
d->querylen) {
366 taia_uint(&
d->deadline,10);
367 taia_add(&
d->deadline,&
d->deadline,&
now);
377 if (
d->tcpstate == 3) {
390 if (
d->tcpstate == 4) {
397 d->packet = alloc(
d->packetlen);
408 if (
d->tcpstate == 5) {
409 r = read(
fd,
d->packet +
d->pos,
d->packetlen -
d->pos);
412 if (
d->pos <
d->packetlen)
return 0;
418 if (
serverfailed(
d->packet,
d->packetlen,(
char *)(
d->servers + 16 *
d->curserver)))
int cns_transmit_start(struct dns_transmit *d, const char servers[QUERY_MAXIPLEN], int flagrecursive, const char *q, const char qtype[2], const char localip[16], const char keys[1024], const char pubkey[32], const char *suffix)
void cns_query(struct dns_transmit *d)
int cns_uncurve(const struct dns_transmit *d, char *buf, unsigned int *lenp)
int dns_domain_equal(const char *dn1, const char *dn2)
unsigned int dns_packet_getname(const char *buf, unsigned int len, unsigned int pos, char **d)
unsigned int dns_packet_copy(const char *buf, unsigned int len, unsigned int pos, char *out, unsigned int outlen)
unsigned int dns_random(unsigned int n)
void dns_transmit_io(struct dns_transmit *d, iopause_fd *x, struct taia *deadline)
int thisudp(struct dns_transmit *d)
void socketfree(struct dns_transmit *d)
void packetfree(struct dns_transmit *d)
void dns_transmit_free(struct dns_transmit *d)
int randombind6(struct dns_transmit *d)
int getscopeid(const struct dns_transmit *d, const char *ip)
int randombind4(struct dns_transmit *d)
int thistcp(struct dns_transmit *d)
int firstudp(struct dns_transmit *d)
int dns_transmit_start6(struct dns_transmit *d, const char servers[QUERY_MAXIPLEN], int flagrecursive, const char *q, const char qtype[2], const char localip[16], const uint32 scopes[QUERY_MAXNS])
int nexttcp(struct dns_transmit *d)
int serverwantstcp(const char *buf, unsigned int len)
uint32 scope_ids[QUERY_MAXNS]
int serverfailed(const char *buf, unsigned int len, char *server)
void queryfree(struct dns_transmit *d)
int randombind(struct dns_transmit *d)
int dns_transmit_start(struct dns_transmit *d, const char servers[QUERY_MAXIPLEN], int flagrecursive, const char *q, const char qtype[2], const char localip[16])
int dns_transmit_get(struct dns_transmit *d, const iopause_fd *x, const struct taia *when)
int nextudp(struct dns_transmit *d)
int irrelevant(const struct dns_transmit *d, const char *buf, unsigned int len)
int firsttcp(struct dns_transmit *d)
char servers[QUERY_MAXIPLEN]
uint32 scopes[QUERY_MAXNS]
void out(const char *s, unsigned int len)
void d(const char *home, const char *subdir, int uid, int gid, int mode)