static void dns_handler(int err, const struct dnshdr *hdr, struct list *ansl, struct list *authl, struct list *addl, void *arg) { struct rst *rst = arg; struct dnsrr *rr; struct sa srv; (void)err; (void)hdr; (void)authl; (void)addl; rr = dns_rrlist_find(ansl, rst->host, DNS_TYPE_A, DNS_CLASS_IN, true); if (!rr) { re_printf("rst: unable to resolve: %s\n", rst->host); tmr_start(&rst->tmr, RETRY_WAIT, reconnect, rst); return; } sa_set_in(&srv, rr->rdata.a.addr, rst->port); err = tcp_connect(&rst->tc, &srv, estab_handler, recv_handler, close_handler, rst); if (err) { re_printf("rst: tcp connect error: %m\n", err); tmr_start(&rst->tmr, RETRY_WAIT, reconnect, rst); return; } }
static void aaaa_handler(int err, const struct dnshdr *hdr, struct list *ansl, struct list *authl, struct list *addl, void *arg) { struct stun_dns *dns = arg; struct dnsrr *rr; (void)hdr; (void)authl; (void)addl; /* Find A answers */ rr = dns_rrlist_find(ansl, NULL, DNS_TYPE_AAAA, DNS_CLASS_IN, false); if (!rr) { err = err ? err : EDESTADDRREQ; goto out; } sa_set_in6(&dns->srv, rr->rdata.aaaa.addr, sa_port(&dns->srv)); DEBUG_INFO("AAAA answer: %j\n", &dns->srv); out: resolved(dns, err); }
static void srv_handler(int err, const struct dnshdr *hdr, struct list *ansl, struct list *authl, struct list *addl, void *arg) { struct stun_dns *dns = arg; struct dnsrr *rr, *arr; (void)hdr; (void)authl; dns_rrlist_sort(ansl, DNS_TYPE_SRV); /* Find SRV answers */ rr = dns_rrlist_find(ansl, NULL, DNS_TYPE_SRV, DNS_CLASS_IN, false); if (!rr) { DEBUG_INFO("no SRV entry, trying A lookup on \"%s\"\n", dns->domain); sa_set_in(&dns->srv, 0, dns->port); err = a_or_aaaa_query(dns, dns->domain); if (err) goto out; return; } DEBUG_INFO("SRV answer: %s:%u\n", rr->rdata.srv.target, rr->rdata.srv.port); /* Look for Additional information */ switch (dns->af) { case AF_INET: arr = dns_rrlist_find(addl, rr->rdata.srv.target, DNS_TYPE_A, DNS_CLASS_IN, true); if (arr) { sa_set_in(&dns->srv, arr->rdata.a.addr, rr->rdata.srv.port); DEBUG_INFO("additional A: %j\n", &dns->srv); goto out; } break; #ifdef HAVE_INET6 case AF_INET6: arr = dns_rrlist_find(addl, rr->rdata.srv.target, DNS_TYPE_AAAA, DNS_CLASS_IN, true); if (arr) { sa_set_in6(&dns->srv, arr->rdata.aaaa.addr, rr->rdata.srv.port); DEBUG_INFO("additional AAAA: %j\n", &dns->srv); goto out; } break; #endif } sa_set_in(&dns->srv, 0, rr->rdata.srv.port); err = a_or_aaaa_query(dns, rr->rdata.srv.target); if (err) { DEBUG_WARNING("SRV: A lookup failed (%m)\n", err); goto out; } DEBUG_INFO("SRV handler: doing A/AAAA lookup..\n"); return; out: resolved(dns, err); }