}
r=p->replyPacket(); // generate an empty reply packet, possibly with TSIG details inside
-
+
+ if (p->qtype == QType::TKEY) {
+ this->tkeyHandler(p, r);
+ return r;
+ }
+
try {
// XXX FIXME do this in DNSPacket::parse ?
}
+void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) {
+ TKEYRecordContent tkey_in;
+ boost::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent());
+ string label, lcLabel;
+
+ if (!p->getTKEYRecord(&tkey_in, &label)) {
+ L<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl;
+ r->setRcode(RCode::FormErr);
+ return;
+ }
+
+ // retain original label for response
+ lcLabel = toLowerCanonic(label);
+
+ tkey_out->d_error = 0;
+ tkey_out->d_mode = tkey_in.d_mode;
+ tkey_out->d_algo = tkey_in.d_algo;
+ tkey_out->d_inception = time((time_t*)NULL);
+ tkey_out->d_expiration = tkey_out->d_inception+15;
+
+ if (tkey_in.d_mode == 3) {
+ tkey_out->d_error = 19; // BADMODE
+ } else if (tkey_in.d_mode == 5) {
+ if (p->d_havetsig == false) { // unauthenticated
+ if (p->d.opcode == Opcode::Update)
+ r->setRcode(RCode::Refused);
+ else
+ r->setRcode(RCode::NotAuth);
+ return;
+ }
+ tkey_out->d_error = 20; // BADNAME (because we have no support for anything here)
+ } else {
+ if (p->d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated
+ if (p->d.opcode == Opcode::Update)
+ r->setRcode(RCode::Refused);
+ else
+ r->setRcode(RCode::NotAuth);
+ return;
+ }
+ tkey_out->d_error = 19; // BADMODE
+ }
+
+ tkey_out->d_keysize = tkey_out->d_key.size();
+ tkey_out->d_othersize = tkey_out->d_other.size();
+
+ DNSRecord rec;
+ rec.d_label = label;
+ rec.d_ttl = 0;
+ rec.d_type = QType::TKEY;
+ rec.d_class = QClass::ANY;
+ rec.d_content = tkey_out;
+
+ DNSResourceRecord rr(rec);
+ rr.qclass = QClass::ANY;
+ rr.qtype = QType::TKEY;
+ rr.d_place = DNSResourceRecord::ANSWER;
+ r->addRecord(rr);
+ r->commitD();
+}
bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata);
bool addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const string& dsname);
void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target);
-
+
+ void tkeyHandler(DNSPacket *p, DNSPacket *r);
+
static AtomicCounter s_count;
static pthread_mutex_t s_rfc2136lock;
bool d_doRecursion;