return 0;
}
-void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw)
+void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType,
+ uint32_t signTTL, DNSPacketWriter::Place signPlace,
+ vector<shared_ptr<DNSRecordContent> >& toSign, uint16_t maxReplyLen, DNSPacketWriter& pw)
{
// cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n";
}
pw.startRecord(signQName, QType::RRSIG, 3600, 1,
- signQType==QType::DNSKEY ? DNSPacketWriter:: ANSWER : signPlace);
+ signQType==QType::DNSKEY ? DNSPacketWriter:: ANSWER : signPlace);
rrc.toPacket(pw);
+ if(maxReplyLen && (pw.size() + 20) > maxReplyLen) {
+ pw.rollback();
+ pw.getHeader()->tc=1;
+ return;
+ }
pw.commit();
if(signQType != QType::DNSKEY)
if(d_dnssecOk) {
if(pos != d_rrs.begin() && (signQType != pos->qtype.getCode() || signQName != pos->qname)) {
- addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, pw);
+ addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, d_tcp ? 0 : getMaxReplyLen(), pw);
}
signQName= pos->qname;
wildcardQName = pos->wildcardname;
pw.startRecord(pos->qname, pos->qtype.getCode(), pos->ttl, pos->qclass, (DNSPacketWriter::Place)pos->d_place);
drc->toPacket(pw);
- if(!d_tcp && pw.size() + 20 > getMaxReplyLen()) { // XXX FIXME, 20? what does it mean?
+ if(!d_tcp && pw.size() + 20 > getMaxReplyLen()) { // 20 = room for EDNS0
pw.rollback();
if(pos->d_place == DNSResourceRecord::ANSWER) {
pw.getHeader()->tc=1;
}
// I assume this is some dirty hack to prevent us from signing the last SOA record in an AXFR.. XXX FIXME
if(d_dnssecOk && !(d_tcp && d_rrs.rbegin()->qtype.getCode() == QType::SOA && d_rrs.rbegin()->priority == 1234)) {
- // cerr<<"Last signature.. "<<d_tcp<<", "<<d_rrs.rbegin()->priority<<", "<<d_rrs.rbegin()->qtype.getCode()<<", "<< d_rrs.size()<<endl;
- addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, pw);
+ addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, d_tcp ? 0 : getMaxReplyLen(), pw);
}
if(!opts.empty() || d_dnssecOk)
pw.addOpt(2800, 0, d_dnssecOk ? EDNSOpts::DNSSECOK : 0, opts);
- pw.commit();
+ if(!pw.getHeader()->tc) // protect against double commit from addSignature
+ pw.commit();
noCommit:;
}
catch(std::exception& e) {
DNSKEYRecordContent getDNSKEYFor(DNSSECKeeper& dk, const std::string& keyrepodir, const std::string& qname, bool withKSK, RSAContext* rc);
void fillOutRRSIG(DNSSECKeeper& dk, const std::string& signQName, RRSIGRecordContent& rrc, const std::string& hash, vector<shared_ptr<DNSRecordContent> >& toSign, bool withKSK=false);
uint32_t getCurrentInception();
-void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw);
+void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign,
+ uint16_t maxReplyLength, DNSPacketWriter& pw);
int getRRSIGForRRSET(DNSSECKeeper& dk, const std::string signQName, uint16_t signQType, uint32_t signTTL,
vector<shared_ptr<DNSRecordContent> >& toSign, RRSIGRecordContent &rrc, bool ksk);