uint32_t DNSDistPacketCache::getMinTTL(const char* packet, uint16_t length)
{
- const struct dnsheader* dh = (const struct dnsheader*) packet;
- uint32_t result = std::numeric_limits<uint32_t>::max();
- vector<uint8_t> content(length - sizeof(dnsheader));
- copy(packet + sizeof(dnsheader), packet + length, content.begin());
- PacketReader pr(content);
- size_t idx = 0;
- DNSName rrname;
- uint16_t qdcount = ntohs(dh->qdcount);
- uint16_t ancount = ntohs(dh->ancount);
- uint16_t nscount = ntohs(dh->nscount);
- uint16_t arcount = ntohs(dh->arcount);
- uint16_t rrtype;
- uint16_t rrclass;
- struct dnsrecordheader ah;
-
- /* consume qd */
- for(idx = 0; idx < qdcount; idx++) {
- rrname = pr.getName();
- rrtype = pr.get16BitInt();
- rrclass = pr.get16BitInt();
- (void) rrtype;
- (void) rrclass;
- }
-
- /* consume AN and NS */
- for (idx = 0; idx < ancount + nscount; idx++) {
- rrname = pr.getName();
- pr.getDnsrecordheader(ah);
- pr.d_pos += ah.d_clen;
- if (result > ah.d_ttl)
- result = ah.d_ttl;
- }
-
- /* consume AR, watch for OPT */
- for (idx = 0; idx < arcount; idx++) {
- rrname = pr.getName();
- pr.getDnsrecordheader(ah);
- pr.d_pos += ah.d_clen;
- if (ah.d_type == QType::OPT) {
- continue;
- }
- if (result > ah.d_ttl)
- result = ah.d_ttl;
- }
- return result;
+ return getDNSPacketMinTTL(packet, length);
}
uint32_t DNSDistPacketCache::getKey(const DNSName& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp)
{
moveOffset(bytes);
}
+ uint32_t get32BitInt()
+ {
+ const char* p = d_packet + d_offset;
+ moveOffset(4);
+ uint32_t ret;
+ memcpy(&ret, (void*)p, 4);
+ return ntohl(ret);
+ }
uint16_t get16BitInt()
{
const char* p = d_packet + d_offset;
{
ageDNSPacket((char*)packet.c_str(), packet.length(), seconds);
}
+
+uint32_t getDNSPacketMinTTL(const char* packet, size_t length)
+{
+ uint32_t result = std::numeric_limits<uint32_t>::max();
+ if(length < sizeof(dnsheader)) {
+ return result;
+ }
+ try
+ {
+ const dnsheader* dh = (const dnsheader*) packet;
+ DNSPacketMangler dpm(const_cast<char*>(packet), length);
+
+ const uint16_t qdcount = ntohs(dh->qdcount);
+ for(size_t n = 0; n < qdcount; ++n) {
+ dpm.skipLabel();
+ dpm.skipBytes(4); // qtype, qclass
+ }
+ const size_t numrecords = ntohs(dh->ancount) + ntohs(dh->nscount) + ntohs(dh->arcount);
+ for(size_t n = 0; n < numrecords; ++n) {
+ dpm.skipLabel();
+
+ const uint16_t dnstype = dpm.get16BitInt();
+ /* uint16_t dnsclass = */ dpm.get16BitInt();
+
+ if(dnstype == QType::OPT)
+ break;
+
+ const uint32_t ttl = dpm.get32BitInt();
+ if (result > ttl)
+ result = ttl;
+
+ dpm.skipRData();
+ }
+ }
+ catch(...)
+ {
+ }
+ return result;
+}
void simpleExpandTo(const string& label, unsigned int frompos, string& ret);
void ageDNSPacket(char* packet, size_t length, uint32_t seconds);
void ageDNSPacket(std::string& packet, uint32_t seconds);
+uint32_t getDNSPacketMinTTL(const char* packet, size_t length);
template<typename T>
std::shared_ptr<T> getRR(const DNSRecord& dr)