measureResultAndClean(iter);
}
}
- catch(MOADNSException &e)
+ catch(const MOADNSException &mde)
{
s_wednserrors++;
}
EDNS0Record edns0;
edns0.extRCode = 0;
edns0.version = 0;
- edns0.Z = 0;
+ edns0.extFlags = 0;
dh.d_type = htons(QType::OPT);
dh.d_class = htons(1280);
res.append(optRData.c_str(), optRData.length());
}
-static void addECSOption(char* packet, const size_t& packetSize, uint16_t* len, const ComboAddress& remote, int stamp)
+static void addECSOption(char* packet, const size_t packetSize, uint16_t* len, const ComboAddress& remote, int stamp)
{
string EDNSRR;
struct dnsheader* dh = (struct dnsheader*) packet;
uint16_t arcount = ntohs(dh->arcount);
/* does it fit in the existing buffer? */
- if (packetSize - *len > EDNSRR.size()) {
+ if (packetSize > *len && (packetSize - *len) > EDNSRR.size()) {
arcount++;
dh->arcount = htons(arcount);
memcpy(packet + *len, EDNSRR.c_str(), EDNSRR.size());
static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, int stamp)
{
- dnsheader* dh=(dnsheader*)pr.d_payload;
bool sent=false;
- if((ntohs(pr.d_udp->uh_dport)!=g_pcapDnsPort && ntohs(pr.d_udp->uh_sport)!=g_pcapDnsPort) || dh->rd != g_rdSelector || (unsigned int)pr.d_len <= sizeof(dnsheader))
+ if (pr.d_len <= sizeof(dnsheader)) {
+ return sent;
+ }
+ if (pr.d_len > std::numeric_limits<uint16_t>::max()) {
+ /* too large for an DNS UDP query, something is not right */
+ return false;
+ }
+ dnsheader* dh=const_cast<dnsheader*>(reinterpret_cast<const dnsheader*>(pr.d_payload));
+ if((ntohs(pr.d_udp->uh_dport)!=g_pcapDnsPort && ntohs(pr.d_udp->uh_sport)!=g_pcapDnsPort) || dh->rd != g_rdSelector)
return sent;
QuestionData qd;
// dh->rd=1; // useful to replay traffic to auths to a recursor
uint16_t dlen = pr.d_len;
- if (stamp >= 0) addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
- pr.d_len=dlen;
+ if (stamp >= 0) {
+ static_assert(sizeof(pr.d_buffer) >= 1500, "The size of the underlying buffer should be at least 1500 bytes");
+ if (dlen > 1500) {
+ /* the existing packet is larger than the maximum size we are willing to send, and it won't get better by adding ECS */
+ return false;
+ }
+ addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
+ pr.d_len=dlen;
+ }
+
s_socket->sendTo((const char*)pr.d_payload, dlen, remote);
sent=true;
dh->id=tmp;
}
}
}
- catch(MOADNSException &e)
+ catch(const MOADNSException &mde)
{
if(!g_quiet)
- cerr<<"Error parsing packet: "<<e.what()<<endl;
+ cerr<<"Error parsing packet: "<<mde.what()<<endl;
s_idmanager.releaseID(qd.d_assignedID); // not added to qids for cleanup
s_origdnserrors++;
}