From 995a16ca0cd9767460c72a856909962a34fdbfbd Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sun, 19 Jan 2025 21:44:19 +0000 Subject: [PATCH] Implement "DNS-0x20 encoding". This provides extra protection against reply-spoof attacks. Since DNS queries are case-insensitive, it's possible to randomly flip the case of letters in a query and still get the correct answer back. This adds an extra dimension for a cache-poisoning attacker to guess when sending replies in-the-blind since it's expected that the legitimate answer will have the same pattern of upper and lower case as the query, so any replies which don't can be ignored as malicious. The amount of extra entropy clearly depends on the number of a-z and A-Z characters in the query, and this implementation puts a hard limit of 32 bits to make rescource allocation easy. This about doubles entropy over the standard random ID and random port combination. --- CHANGELOG | 14 +++++++++ src/auth.c | 2 +- src/dnsmasq.h | 8 ++++- src/dnssec.c | 46 ++++++++++++++-------------- src/forward.c | 26 +++++++++++----- src/rfc1035.c | 83 ++++++++++++++++++++++++++++++--------------------- 6 files changed, 113 insertions(+), 66 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3a43ad2..594c77b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -97,6 +97,20 @@ version 2.91 queries to dnsmasq acting as forwarder for a zone for which it is authoritative. + Implement "DNS-0x20 encoding", for extra protection against + reply-spoof attacks. Since DNS queries are case-insensitive, + it's possible to randomly flip the case of letters in a query + and still get the correct answer back. + This adds an extra dimension for a cache-poisoning attacker + to guess when sending replies in-the-blind since it's expected + that the legitimate answer will have the same pattern of upper + and lower case as the query, so any replies which don't can be + ignored as malicious. The amount of extra entropy clearly depends + on the number of a-z and A-Z characters in the query, and this + implementation puts a hard limit of 32 bits to make rescource + allocation easy. This about doubles entropy over the standard + random ID and random port combination. + version 2.90 Fix reversion in --rev-server introduced in 2.88 which diff --git a/src/auth.c b/src/auth.c index efe8385..cd4fe44 100644 --- a/src/auth.c +++ b/src/auth.c @@ -137,7 +137,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n nameoffset = p - (unsigned char *)header; /* now extract name as .-concatenated string into name */ - if (!extract_name(header, qlen, &p, name, 1, 4)) + if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4)) return 0; /* bad packet */ GETSHORT(qtype, p); diff --git a/src/dnsmasq.h b/src/dnsmasq.h index d9e965a..2e1a9d8 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -790,6 +790,7 @@ struct frec { int forwardall, flags; time_t time; u32 forward_timestamp; + unsigned int encode_bitmap; int forward_delay; struct blockdata *stash; /* saved query or saved reply, whilst we validate */ size_t stash_len; @@ -1386,7 +1387,7 @@ int is_rev_synth(int flag, union all_addr *addr, char *name); /* rfc1035.c */ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff); int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, - char *name, int isExtract, int extrabytes); + char *name, int func, unsigned int parm); unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes); unsigned char *skip_questions(struct dns_header *header, size_t plen); unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen); @@ -1413,6 +1414,11 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int *offset, unsigned short type, unsigned short class, char *format, ...); int in_arpa_name_2_addr(char *namein, union all_addr *addrp); int private_net(struct in_addr addr, int ban_localhost); +/* extract_name ops */ +#define EXTR_NAME_EXTRACT 1 +#define EXTR_NAME_COMPARE 2 +#define EXTR_NAME_NOCASE 3 +#define EXTR_NAME_FLIP 4 /* auth.c */ #ifdef HAVE_AUTH diff --git a/src/dnssec.c b/src/dnssec.c index 027bb37..b848f46 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -191,7 +191,7 @@ static int get_rdata(struct dns_header *header, size_t plen, struct rdata_state /* domain-name, canonicalise */ int len; - if (!extract_name(header, plen, &state->ip, state->buff, 1, 0) || + if (!extract_name(header, plen, &state->ip, state->buff, EXTR_NAME_EXTRACT, 0) || (len = to_wire(state->buff)) == 0) continue; @@ -339,7 +339,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int pstart = p; - if (!(res = extract_name(header, plen, &p, name, 0, 10))) + if (!(res = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10))) return 0; /* bad packet */ GETSHORT(stype, p); @@ -374,14 +374,14 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int if (gotkey) { /* If there's more than one SIG, ensure they all have same keyname */ - if (extract_name(header, plen, &p, keyname, 0, 0) != 1) + if (extract_name(header, plen, &p, keyname, EXTR_NAME_COMPARE, 0) != 1) return 0; } else { gotkey = 1; - if (!extract_name(header, plen, &p, keyname, 1, 0)) + if (!extract_name(header, plen, &p, keyname, EXTR_NAME_EXTRACT, 0)) return 0; /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal @@ -503,7 +503,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in GETLONG(sig_inception, p); GETSHORT(key_tag, p); - if (!extract_name(header, plen, &p, keyname, 1, 0)) + if (!extract_name(header, plen, &p, keyname, EXTR_NAME_EXTRACT, 0)) return STAT_BOGUS; if (!time_check) @@ -568,7 +568,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in p = rrset[i]; - if (!extract_name(header, plen, &p, name, 1, 10)) + if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 10)) return STAT_BOGUS; name_start = name; @@ -661,7 +661,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in /* namebuff used for workspace above, restore to leave unchanged on exit */ p = (unsigned char*)(rrset[0]); - if (!extract_name(header, plen, &p, name, 1, 0)) + if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 0)) return STAT_BOGUS; if (key) @@ -727,7 +727,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch static unsigned char **cached_digest; static size_t cached_digest_size = 0; - if (ntohs(header->qdcount) != 1 || RCODE(header) != NOERROR || !extract_name(header, plen, &p, name, 1, 4)) + if (ntohs(header->qdcount) != 1 || RCODE(header) != NOERROR || !extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 4)) return STAT_BOGUS | DNSSEC_FAIL_NOKEY; GETSHORT(qtype, p); @@ -752,7 +752,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch for (j = ntohs(header->ancount); j != 0; j--) { /* Ensure we have type, class TTL and length */ - if (!(rc = extract_name(header, plen, &p, name, 0, 10))) + if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10))) return STAT_BOGUS; /* bad packet */ GETSHORT(qtype, p); @@ -904,7 +904,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch for (j = ntohs(header->ancount); j != 0; j--) { /* Ensure we have type, class TTL and length */ - if (!(rc = extract_name(header, plen, &p, name, 0, 10))) + if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10))) return STAT_BOGUS; /* bad packet */ GETSHORT(qtype, p); @@ -1024,7 +1024,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char } p = (unsigned char *)(header+1); - if (!extract_name(header, plen, &p, name, 1, 4)) + if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 4)) return STAT_BOGUS; p += 4; /* qtype, qclass */ @@ -1050,7 +1050,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char { unsigned char *psave; - if (!(rc = extract_name(header, plen, &p, name, 0, 10))) + if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10))) return STAT_BOGUS; /* bad packet */ GETSHORT(atype, p); @@ -1231,12 +1231,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi int sig_labels, name_labels; p = nsecs[i]; - if (!extract_name(header, plen, &p, workspace1, 1, 10)) + if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 10)) return DNSSEC_FAIL_BADPACKET; p += 8; /* class, type, TTL */ GETSHORT(rdlen, p); psave = p; - if (!extract_name(header, plen, &p, workspace2, 1, 0)) + if (!extract_name(header, plen, &p, workspace2, EXTR_NAME_EXTRACT, 0)) return DNSSEC_FAIL_BADPACKET; /* If NSEC comes from wildcard expansion, use original wildcard @@ -1400,7 +1400,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige for (i = 0; i < nsec_count; i++) if ((p = nsecs[i])) { - if (!extract_name(header, plen, &p, workspace1, 1, 10) || + if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 10) || !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2))) return 0; @@ -1609,7 +1609,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns for (i = 0; i < nsec_count; i++) if ((p = nsecs[i])) { - if (!extract_name(header, plen, &p, workspace1, 1, 0)) + if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 0)) return DNSSEC_FAIL_BADPACKET; if (!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2))) @@ -1684,7 +1684,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key { unsigned char *pstart = p; - if (!extract_name(header, plen, &p, daemon->workspacename, 1, 10)) + if (!extract_name(header, plen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 10)) return DNSSEC_FAIL_BADPACKET; GETSHORT(type, p); @@ -1735,7 +1735,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key { unsigned char *psav; - if (!(res = extract_name(header, plen, &p1, daemon->workspacename, 0, 10))) + if (!(res = extract_name(header, plen, &p1, daemon->workspacename, EXTR_NAME_COMPARE, 10))) return DNSSEC_FAIL_BADPACKET; GETSHORT(type1, p1); @@ -1965,7 +1965,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch targets[0] = p1; targetidx = 1; - if (!extract_name(header, plen, &p1, name, 1, 4)) + if (!extract_name(header, plen, &p1, name, EXTR_NAME_EXTRACT, 4)) return STAT_BOGUS; GETSHORT(qtype, p1); @@ -2003,7 +2003,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1)) return STAT_BOGUS; - if (!extract_name(header, plen, &p1, name, 1, 10)) + if (!extract_name(header, plen, &p1, name, EXTR_NAME_EXTRACT, 10)) return STAT_BOGUS; /* bad packet */ GETSHORT(type1, p1); @@ -2018,7 +2018,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch /* Check if we've done this RRset already */ for (p2 = ans_start, j = 0; j < i; j++) { - if (!(rc = extract_name(header, plen, &p2, name, 0, 10))) + if (!(rc = extract_name(header, plen, &p2, name, EXTR_NAME_COMPARE, 10))) return STAT_BOGUS; /* bad packet */ GETSHORT(type2, p2); @@ -2115,7 +2115,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch if ((p2 = targets[j])) { int rc1; - if (!(rc1 = extract_name(header, plen, &p2, name, 0, 10))) + if (!(rc1 = extract_name(header, plen, &p2, name, EXTR_NAME_COMPARE, 10))) return STAT_BOGUS; /* bad packet */ if (class1 == qclass && rc1 == 1 && (type1 == T_CNAME || type1 == qtype || qtype == T_ANY )) @@ -2149,7 +2149,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch if (neganswer) *neganswer = 1; - if (!extract_name(header, plen, &p2, name, 1, 10)) + if (!extract_name(header, plen, &p2, name, EXTR_NAME_EXTRACT, 10)) return STAT_BOGUS; /* bad packet */ /* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */ diff --git a/src/forward.c b/src/forward.c index 595e47b..ab43dba 100644 --- a/src/forward.c +++ b/src/forward.c @@ -264,6 +264,8 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr, /* new query */ if (!forward) { + unsigned char *p; + if (OPCODE(header) != QUERY) { flags = F_RCODE; @@ -323,7 +325,12 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr, forward->frec_src.orig_id = ntohs(header->id); forward->new_id = get_id(); header->id = ntohs(forward->new_id); - + + forward->encode_bitmap = rand32(); + p = (unsigned char *)(header+1); + if (!extract_name(header, plen, &p, NULL, EXTR_NAME_FLIP, forward->encode_bitmap)) + goto reply; + /* Keep copy of query for retries and move to TCP */ if (!(forward->stash = blockdata_alloc((char *)header, plen))) { @@ -968,7 +975,8 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header, new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY); new->flags |= flags; new->forwardall = 0; - + new->encode_bitmap = 0; + forward->next_dependent = NULL; new->dependent = forward; /* to find query awaiting new one. */ @@ -1085,7 +1093,7 @@ void reply_query(int fd, time_t now) return; p = (unsigned char *)(header+1); - if (!extract_name(header, n, &p, daemon->namebuff, 1, 4)) + if (!extract_name(header, n, &p, daemon->namebuff, EXTR_NAME_EXTRACT, 4)) return; /* bad packet */ GETSHORT(rrtype, p); GETSHORT(class, p); @@ -1195,7 +1203,11 @@ void reply_query(int fd, time_t now) /* denominator controls how many queries we average over. */ server->query_latency = server->mma_latency/128; - + /* Flip the bits back in the query name. */ + p = (unsigned char *)(header+1); + if (!extract_name(header, n, &p, NULL, EXTR_NAME_FLIP, forward->encode_bitmap)) + return; + #ifdef HAVE_DNSSEC if (option_bool(OPT_DNSSEC_VALID)) { @@ -1895,7 +1907,7 @@ static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet, /* Save the query to make sure we get the answer we expect. */ p = (unsigned char *)(header+1); - if (!extract_name(header, qsize, &p, daemon->namebuff, 1, 4)) + if (!extract_name(header, qsize, &p, daemon->namebuff, EXTR_NAME_EXTRACT, 4)) return 0; GETSHORT(type, p); GETSHORT(class, p); @@ -2006,7 +2018,7 @@ static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet, DNS-0x20 encoding is effective. Try another server, or give up */ p = (unsigned char *)(header+1); - if (extract_name(header, rsize, &p, daemon->namebuff, -1, 4) != 1) + if (extract_name(header, rsize, &p, daemon->namebuff, EXTR_NAME_NOCASE, 4) != 1) continue; GETSHORT(rtype, p); GETSHORT(rclass, p); @@ -3049,7 +3061,7 @@ static struct frec *lookup_frec(char *target, int class, int rrtype, int id, int int hclass, hrrtype; /* Case sensitive compare for DNS-0x20 encoding. */ - if (extract_name(header, f->stash_len, &p, target, -1, 4) != 1) + if (extract_name(header, f->stash_len, &p, target, EXTR_NAME_NOCASE, 4) != 1) continue; GETSHORT(hrrtype, p); diff --git a/src/rfc1035.c b/src/rfc1035.c index 6eca371..3380924 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -16,26 +16,29 @@ #include "dnsmasq.h" -/* isExtract == 1 -> extract name - isExtract == 0 -> compare name, case insensitive - isExtract == -1 -> compare name, case sensitive - +/* EXTR_NAME_EXTRACT -> extract name + EXTR_NAME_COMPARE -> compare name, case insensitive + EXTR_NAME_NOCASE -> compare name, case sensitive + EXTR_NAME_FLIP -> flip 0x20 bits in packet, controlled by bitmap in parm. name may be NULL + return = 0 -> error - return = 1 -> extract OK, compare OK + return = 1 -> extract OK, compare OK, flip OK return = 2 -> extract OK, compare failed. */ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, - char *name, int isExtract, int extrabytes) + char *name, int func, unsigned int parm) { unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL; unsigned int j, l, namelen = 0, hops = 0; - int retvalue = 1, case_insens = 1; - - if (isExtract == -1) - isExtract = case_insens = 0; - else if (isExtract) - *cp = 0; - + int retvalue = 1, case_insens = 1, isExtract = 0, flip = 0, extrabytes = (int)parm; + + if (func == EXTR_NAME_EXTRACT) + isExtract = 1, *cp = 0; + else if (func == EXTR_NAME_NOCASE) + case_insens = 0; + else if (func == EXTR_NAME_FLIP) + flip = 1, extrabytes = 0; + while (1) { unsigned int label_type; @@ -56,7 +59,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, cp--; *cp = 0; /* terminate: lose final period */ } - else if (*cp != 0) + else if (!flip && *cp != 0) retvalue = 2; if (p1) /* we jumped via compression */ @@ -95,7 +98,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, if (!CHECK_LEN(header, p, plen, l)) return 0; - for(j=0; j= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + { + if (parm & 1) + *p ^= 0x20; + parm >>= 1; + } + } else { unsigned char c1 = *cp, c2 = *p; @@ -117,15 +132,15 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, else { cp++; - if (case_insens && c1 >= 'A' && c1 <= 'Z') - c1 += 'a' - 'A'; if (c1 == NAME_ESCAPE) c1 = (*cp++)-1; + else if (case_insens && c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; if (case_insens && c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A'; - + if (c1 != c2) retvalue = 2; } @@ -133,7 +148,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, if (isExtract) *cp++ = '.'; - else if (*cp != 0 && *cp++ != '.') + else if (!flip && *cp != 0 && *cp++ != '.') retvalue = 2; } else @@ -409,7 +424,7 @@ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff) if (i == ntohs(header->ancount) && !(p = skip_section(p, ntohs(header->nscount), header, qlen))) return done; - if (!extract_name(header, qlen, &p, namebuff, 1, 10)) + if (!extract_name(header, qlen, &p, namebuff, EXTR_NAME_EXTRACT, 10)) return done; /* bad packet */ GETSHORT(qtype, p); @@ -490,7 +505,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *sub for (i = 0; i < ntohs(header->nscount); i++) { - if (!extract_name(header, qlen, &p, daemon->workspacename, 1, 0)) + if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0)) return 0; /* bad packet */ GETSHORT(qtype, p); @@ -519,7 +534,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *sub for (j = 0; j < 2; j++) /* MNAME, RNAME */ { - if (!extract_name(header, qlen, &p, daemon->workspacename, 1, 0)) + if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0)) { if (!no_cache) blockdata_free(addr.rrblock.rrdata); @@ -670,7 +685,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t namep = p = (unsigned char *)(header+1); - if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, 1, 4)) + if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4)) return 2; /* bad packet */ GETSHORT(qtype, p); @@ -694,7 +709,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t for (j = 0; j < ntohs(header->ancount); j++) { int secflag = 0; - if (!(res = extract_name(header, qlen, &p1, name, 0, 10))) + if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10))) return 2; /* bad packet */ GETSHORT(aqtype, p1); @@ -732,7 +747,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t if (aqtype == T_CNAME) log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL, 0); - if (!extract_name(header, qlen, &p1, name, 1, 0)) + if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0)) return 2; if (aqtype == T_CNAME) @@ -810,7 +825,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t { int secflag = 0; - if (!(res = extract_name(header, qlen, &p1, name, 0, 10))) + if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10))) return 2; /* bad packet */ GETSHORT(aqtype, p1); @@ -872,7 +887,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t } namep = p1; - if (!extract_name(header, qlen, &p1, name, 1, 0)) + if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0)) return 2; if (qtype != T_CNAME) @@ -942,7 +957,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t /* Name, extract it then re-encode. */ int len; - if (!extract_name(header, qlen, &p1, name, 1, 0)) + if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0)) { blockdata_free(addr.rrblock.rrdata); return 2; @@ -975,7 +990,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t } while (desc != -1); /* we overwrote the original name, so get it back here. */ - if (!extract_name(header, qlen, &tmp, name, 1, 0)) + if (!extract_name(header, qlen, &tmp, name, EXTR_NAME_EXTRACT, 0)) { blockdata_free(addr.rrblock.rrdata); return 2; @@ -1137,7 +1152,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark) { int aqtype, aqclass, ardlen; - if (!extract_name(header, len, &p, daemon->namebuff, 1, 10)) + if (!extract_name(header, len, &p, daemon->namebuff, EXTR_NAME_EXTRACT, 10)) return; if (!CHECK_LEN(header, p, len, 10)) @@ -1155,7 +1170,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark) { if (aqtype == T_CNAME) { - if (!extract_name(header, len, &p, daemon->workspacename, 1, 0)) + if (!extract_name(header, len, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0)) return; if (safe_name(daemon->namebuff) && safe_name(daemon->workspacename)) ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, daemon->workspacename, attl); @@ -1205,7 +1220,7 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, if (!(header->hb3 & HB3_QR) && (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0)) return 0; /* non-standard query. */ - if (!extract_name(header, qlen, &p, name, 1, 4)) + if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4)) return 0; /* bad packet */ GETSHORT(qtype, p); @@ -1319,7 +1334,7 @@ static int check_bad_address(struct dns_header *header, size_t qlen, struct bogu for (i = ntohs(header->ancount); i != 0; i--) { - if (name && !extract_name(header, qlen, &p, name, 1, 10)) + if (name && !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 10)) return 0; /* bad packet */ if (!name && !(p = skip_name(p, header, qlen, 10))) @@ -1629,7 +1644,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, nameoffset = p - (unsigned char *)header; /* now extract name as .-concatenated string into name */ - if (!extract_name(header, qlen, &p, name, 1, 4)) + if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4)) return 0; /* bad packet */ GETSHORT(qtype, p);