From 6e7fab70100e22ee6f585eb36388bde16003fd66 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Wed, 2 Mar 2022 22:15:55 -0500 Subject: Implement SRV record lookup --- enroll.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/enroll.c b/enroll.c index 7ef8e36..4ea8289 100644 --- a/enroll.c +++ b/enroll.c @@ -29,8 +29,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -177,8 +180,44 @@ static int getConfig(const char *configHome) { } static int srvLookup(char **host, char **port, const char *name) { - // TODO - return -1; + char dname[256]; + snprintf(dname, sizeof(dname), "_ircs._tcp.%s", name); + log("Looking up SRV record for %s", dname); + + uint8_t msg[512]; + int len = res_query(dname, 1 /* IN */, 33 /* SRV */, msg, sizeof(msg)); + if (len < 12) return -1; + + uint8_t *ptr = &msg[12]; +#define NAME_SKIP \ + for (uint8_t n; ptr < &msg[len] && (n = *ptr++); ptr += n) { \ + if (n & 0xC0) { ptr++; break; } \ + } + + uint16_t qdcount = msg[4] << 8 | msg[5]; + for (uint16_t q = 0; ptr < &msg[len] && q < qdcount; ++q) { + NAME_SKIP; // QNAME + ptr += 4; // QTYPE, QCLASS + } + + NAME_SKIP; // NAME + ptr += 14; // TYPE, CLASS, TTL, RDLENGTH, Priority, Weight + if (&msg[len] < ptr + 3) return -1; +#undef NAME_SKIP + + int n = asprintf(port, "%d", ptr[0] << 8 | ptr[1]); + if (n < 0) err(EX_OSERR, "asprintf"); + ptr += 2; + + // Name compression is not used for Target. + if (!ptr[0]) return -1; + char *host0 = (char *)&ptr[1]; + for (uint8_t n; ptr < &msg[len] && (n = *ptr); ptr += n) { + *ptr++ = '.'; + } + *host = strdup(host0); + if (!*host) err(EX_OSERR, "strdup"); + return 0; } static int getHostPort(void) { -- cgit 1.4.1