int removeEDNSOptionFromOPT(char* optStart, size_t* optLen, const uint16_t optionCodeToRemove)
{
- /* we need at least:
- root label (1), type (2), class (2), ttl (4) + rdlen (2)*/
- if (*optLen < 11) {
+ if (*optLen < optRecordMinimumSize) {
return EINVAL;
}
const unsigned char* end = (const unsigned char*) optStart + *optLen;
bool isEDNSOptionInOpt(const std::string& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart, uint16_t* optContentLen)
{
- /* we need at least:
- root label (1), type (2), class (2), ttl (4) + rdlen (2)*/
- if (optLen < 11) {
+ if (optLen < optRecordMinimumSize) {
return false;
}
size_t p = optStart + 9;
uint16_t rdLen = (0x100*packet.at(p) + packet.at(p+1));
p += sizeof(rdLen);
- if (rdLen > (optLen - 11)) {
+ if (rdLen > (optLen - optRecordMinimumSize)) {
return false;
}
return false;
}
+
+bool getEDNS0Record(const DNSQuestion& dq, EDNS0Record& edns0)
+{
+ uint16_t optStart;
+ size_t optLen = 0;
+ bool last = false;
+ const char * packet = reinterpret_cast<const char*>(dq.dh);
+ std::string packetStr(packet, dq.len);
+ int res = locateEDNSOptRR(packetStr, &optStart, &optLen, &last);
+ if (res != 0) {
+ // no EDNS OPT RR
+ return false;
+ }
+
+ if (optLen < optRecordMinimumSize) {
+ return false;
+ }
+
+ if (optStart < dq.len && packetStr.at(optStart) != 0) {
+ // OPT RR Name != '.'
+ return false;
+ }
+
+ static_assert(sizeof(EDNS0Record) == sizeof(uint32_t), "sizeof(EDNS0Record) must match sizeof(uint32_t) AKA RR TTL size");
+ // copy out 4-byte "ttl" (really the EDNS0 record), after root label (1) + type (2) + class (2).
+ memcpy(&edns0, packet + optStart + 5, sizeof edns0);
+ return true;
+}
*/
#pragma once
+// root label (1), type (2), class (2), ttl (4) + rdlen (2)
+static const size_t optRecordMinimumSize = 11;
+
extern size_t g_EdnsUDPPayloadSize;
extern uint16_t g_PayloadSizeSelfGenAnswers;
int getEDNSZ(const DNSQuestion& dq);
bool queryHasEDNS(const DNSQuestion& dq);
+bool getEDNS0Record(const DNSQuestion& dq, EDNS0Record& edns0);
hadEDNS = getEDNSUDPPayloadSizeAndZ(packet, *len, &payloadSize, &z);
}
- *len=(uint16_t) (sizeof(dnsheader)+consumed+DNS_TYPE_SIZE+DNS_CLASS_SIZE);
+ *len=static_cast<uint16_t>(sizeof(dnsheader)+consumed+DNS_TYPE_SIZE+DNS_CLASS_SIZE);
struct dnsheader* dh = reinterpret_cast<struct dnsheader*>(packet);
dh->ancount = dh->arcount = dh->nscount = 0;
char * response = packet;
size_t responseSize = sizeof(packet);
- if (got < static_cast<ssize_t>(sizeof(dnsheader)))
+ if (got < 0 || static_cast<size_t>(got) < sizeof(dnsheader))
continue;
uint16_t responseLen = static_cast<uint16_t>(got);
return false;
}
- uint16_t optStart;
- size_t optLen = 0;
- bool last = false;
- const char * packet = reinterpret_cast<const char*>(dq->dh);
- std::string packetStr(packet, dq->len);
- int res = locateEDNSOptRR(packetStr, &optStart, &optLen, &last);
- if (res != 0) {
- // no EDNS OPT RR
- return d_extrcode == 0;
- }
-
- // root label (1), type (2), class (2), ttl (4) + rdlen (2)
- if (optLen < 11) {
- return false;
- }
-
- if (optStart < dq->len && packet[optStart] != 0) {
- // OPT RR Name != '.'
+ EDNS0Record edns0;
+ if (!getEDNS0Record(*dq, edns0)) {
return false;
}
- EDNS0Record edns0;
- static_assert(sizeof(EDNS0Record) == sizeof(uint32_t), "sizeof(EDNS0Record) must match sizeof(uint32_t) AKA RR TTL size");
- // copy out 4-byte "ttl" (really the EDNS0 record), after root label (1) + type (2) + class (2).
- memcpy(&edns0, packet + optStart + 5, sizeof edns0);
return d_extrcode == edns0.extRCode;
}
}
bool matches(const DNSQuestion* dq) const override
{
- uint16_t optStart;
- size_t optLen = 0;
- bool last = false;
- const char * packet = reinterpret_cast<const char*>(dq->dh);
- std::string packetStr(packet, dq->len);
- int res = locateEDNSOptRR(packetStr, &optStart, &optLen, &last);
- if (res != 0) {
- // no EDNS OPT RR
- return false;
- }
-
- // root label (1), type (2), class (2), ttl (4) + rdlen (2)
- if (optLen < 11) {
- return false;
- }
-
- if (optStart < dq->len && packetStr.at(optStart) != 0) {
- // OPT RR Name != '.'
+ EDNS0Record edns0;
+ if (!getEDNS0Record(*dq, edns0)) {
return false;
}
- EDNS0Record edns0;
- static_assert(sizeof(EDNS0Record) == sizeof(uint32_t), "sizeof(EDNS0Record) must match sizeof(uint32_t) AKA RR TTL size");
- // copy out 4-byte "ttl" (really the EDNS0 record), after root label (1) + type (2) + class (2).
- memcpy(&edns0, packet + optStart + 5, sizeof edns0);
return d_version < edns0.version;
}
return false;
}
- // root label (1), type (2), class (2), ttl (4) + rdlen (2)
- if (optLen < 11) {
+ if (optLen < optRecordMinimumSize) {
return false;
}
return false;
}
- // root label (1), type (2), class (2), ttl (4) + rdlen (2)
- if (optLen < 11) {
+ if (optLen < optRecordMinimumSize) {
return false;
}