summaryrefslogtreecommitdiff
path: root/src/network/lookup_name.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-06-02 04:47:45 -0400
committerRich Felker <dalias@aerifal.cx>2014-06-02 04:47:45 -0400
commit3330198060c7b3165a2fba530ffde5fc6706ecf2 (patch)
treebc87811d35022e240dfe8d24f96402ac2feaa65a /src/network/lookup_name.c
parenta2a328bd896fa909542b492601e3689119b95de0 (diff)
downloadmusl-3330198060c7b3165a2fba530ffde5fc6706ecf2.tar.gz
switch standard resolver functions to use the new dns backend
this is the third phase of the "resolver overhaul" project. this commit removes all of the old dns code, and switches the __lookup_name backend (used by getaddrinfo, etc.) and the getnameinfo function to use the newly implemented __res_mkquery and __res_msend interfaces. for parsing the results, a new callback-based __dns_parse function, based on __dns_get_rr from the old dns code, is used.
Diffstat (limited to 'src/network/lookup_name.c')
-rw-r--r--src/network/lookup_name.c82
1 files changed, 61 insertions, 21 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index e1b583ee..83c0fc27 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -9,7 +9,6 @@
#include "lookup.h"
#include "stdio_impl.h"
#include "syscall.h"
-#include "__dns.h"
static int is_valid_hostname(const char *host)
{
@@ -86,30 +85,71 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
return cnt;
}
-static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+struct dpc_ctx {
+ struct address *addrs;
+ char *canon;
+ int cnt;
+};
+
+int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
+int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
+
+#define RR_A 1
+#define RR_CNAME 5
+#define RR_AAAA 28
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
{
- unsigned char reply[1024] = { 0 }, *p = reply;
char tmp[256];
- int i, cnt = 0;
-
- /* Perform one or more DNS queries for host */
- int result = __dns_query(reply, name, family, 0);
- if (result < 0) return result;
+ struct dpc_ctx *ctx = c;
+ switch (rr) {
+ case RR_A:
+ if (len != 4) return -1;
+ ctx->addrs[ctx->cnt].family = AF_INET;
+ memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
+ break;
+ case RR_AAAA:
+ if (len != 16) return -1;
+ ctx->addrs[ctx->cnt].family = AF_INET6;
+ memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
+ break;
+ case RR_CNAME:
+ if (__dn_expand(packet, (const unsigned char *)packet + 512,
+ data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
+ strcpy(ctx->canon, tmp);
+ break;
+ }
+ return 0;
+}
- for (i=0; i<result; i++) {
- if (family != AF_INET6) {
- int j = __dns_get_rr(&buf[cnt].addr, sizeof *buf, 4, MAXADDRS-cnt, p, RR_A, 0);
- while (j--) buf[cnt++].family = AF_INET;
- }
- if (family != AF_INET) {
- int j = __dns_get_rr(&buf[cnt].addr, sizeof *buf, 16, MAXADDRS-cnt, p, RR_AAAA, 0);
- while (j--) buf[cnt++].family = AF_INET6;
- }
- p += 512;
+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+ unsigned char qbuf[2][280], abuf[2][512];
+ const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
+ unsigned char *ap[2] = { abuf[0], abuf[1] };
+ int qlens[2], alens[2];
+ int i, nq = 0;
+ struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
+
+ if (family != AF_INET6) {
+ qlens[nq] = __res_mkquery(0, name, 1, RR_A, 0, 0, 0,
+ qbuf[nq], sizeof *qbuf);
+ nq++;
}
- __dns_get_rr(tmp, 0, 256, 1, reply, RR_CNAME, 1);
- if (is_valid_hostname(tmp)) strcpy(canon, tmp);
- return cnt;
+ if (family != AF_INET) {
+ qlens[nq] = __res_mkquery(0, name, 1, RR_AAAA, 0, 0, 0,
+ qbuf[nq], sizeof *qbuf);
+ nq++;
+ }
+
+ if (__res_msend(nq, qp, qlens, ap, alens, sizeof *abuf) < 0) return EAI_SYSTEM;
+
+ for (i=0; i<nq; i++)
+ __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
+
+ return ctx.cnt;
}
int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)