* Function that creates all the stats
* when udpOrTCP is true, it is udp
*/
-void ResponseStats::submitResponse(DNSPacket &p, bool udpOrTCP) {
+void ResponseStats::submitResponse(DNSPacket &p, bool udpOrTCP, bool last) {
const string& buf=p.getString();
static AtomicCounter &udpnumanswered=*S.getPointer("udp-answers");
static AtomicCounter &udpnumanswered4=*S.getPointer("udp4-answers");
udpbytesanswered6+=buf.length();
}
} else { //tcp
- tcpnumanswered++;
tcpbytesanswered+=buf.length();
if(p.d_remote.sin4.sin_family==AF_INET) {
- tcpnumanswered4++;
tcpbytesanswered4+=buf.length();
} else {
- tcpnumanswered6++;
tcpbytesanswered6+=buf.length();
}
+ if(last) {
+ tcpnumanswered++;
+ if(p.d_remote.sin4.sin_family==AF_INET) {
+ tcpnumanswered4++;
+ } else {
+ tcpnumanswered6++;
+ }
+ }
}
submitResponse(p.qtype.getCode(), buf.length(), p.d.rcode, udpOrTCP);
}
}
-void TCPNameserver::sendPacket(std::unique_ptr<DNSPacket>& p, int outsock)
+void TCPNameserver::sendPacket(std::unique_ptr<DNSPacket>& p, int outsock, bool last)
{
- g_rs.submitResponse(*p, false);
+ g_rs.submitResponse(*p, false, last);
uint16_t len=htons(p->getString().length());
string buffer((const char*)&len, 2);
throw NetworkError("Error reading DNS data from TCP client "+remote.toString()+": "+ae.what());
}
-static void incTCPAnswerCount(const ComboAddress& remote)
-{
- S.inc("tcp-answers");
- if(remote.sin4.sin_family == AF_INET6)
- S.inc("tcp6-answers");
- else
- S.inc("tcp4-answers");
-}
-
static bool maxConnectionDurationReached(unsigned int maxConnectionDuration, time_t start, unsigned int& remainingTime)
{
if (maxConnectionDuration) {
break;
if(packet->qtype.getCode()==QType::AXFR) {
- if(doAXFR(packet->qdomain, packet, fd))
- incTCPAnswerCount(remote);
+ doAXFR(packet->qdomain, packet, fd);
continue;
}
if(packet->qtype.getCode()==QType::IXFR) {
- if(doIXFR(packet, fd))
- incTCPAnswerCount(remote);
+ doIXFR(packet, fd);
continue;
}
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac); // first answer is 'normal'
- sendPacket(outpacket, outsock);
+ sendPacket(outpacket, outsock, false);
trc.d_mac = outpacket->d_trc.d_mac;
outpacket = getFreshAXFRPacket(q);
if(!outpacket->getRRS().empty()) {
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true);
- sendPacket(outpacket, outsock);
+ sendPacket(outpacket, outsock, false);
trc.d_mac=outpacket->d_trc.d_mac;
outpacket=getFreshAXFRPacket(q);
}
if(!outpacket->getRRS().empty()) {
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true);
- sendPacket(outpacket, outsock);
+ sendPacket(outpacket, outsock, false);
trc.d_mac=outpacket->d_trc.d_mac;
outpacket=getFreshAXFRPacket(q);
}
if(!outpacket->getRRS().empty()) {
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true);
- sendPacket(outpacket, outsock);
+ sendPacket(outpacket, outsock, false);
trc.d_mac=outpacket->d_trc.d_mac;
outpacket=getFreshAXFRPacket(q);
}
if(!outpacket->getRRS().empty()) {
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); // first answer is 'normal'
- sendPacket(outpacket, outsock);
+ sendPacket(outpacket, outsock, false);
trc.d_mac=outpacket->d_trc.d_mac;
outpacket=getFreshAXFRPacket(q);
}