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);