Beispiel #1
0
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);
}