/*************************************************************************** query.cpp - query handling ------------------- begin : wo dec 25 2002 copyright : (C) 2002 by Meilof email : meilof@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "query.h" #include "stdquery.h" #include "zonetransfer.h" #include "secondary.h" #include "configuration.h" /* ----- utility functions ------------------------------------------------- */ DnsMessage *srvfail(DnsMessage *q, DnsMessage *a, uint16_t rcode) { a->ID = q->ID; a->RCODE = rcode; a->OPCODE = q->OPCODE; return a; } DnsMessage *new_srvfail(DnsMessage *q, uint16_t rcode) { DnsMessage *a = new DnsMessage(); return srvfail(q, a, rcode); } /* ----- query entry point ------------------------------------------------- */ DnsMessage *query_entry_point(pending_query *q) { if (do_query_logging) { try { if (!q->message->questions.empty()) { #ifdef DEBUG printf("Doing pos_log.\n"); printf("Qname is %s\n", q->message->questions.begin()->QNAME.c_str()); #endif pos_log(context_query, log_info, "Query from %s: OPCODE %s, q={%s,%s}", addr_to_string(&q->querier).c_str(), str_opcode(q->message->OPCODE).c_str(), q->message->questions.begin()->QNAME.tocstr(), str_qtype(q->message->questions.begin()->QTYPE).c_str()); } else if (q->message->OPCODE == OPCODE_NOTIFY && q->message->answers.size() == 1) { pos_log(context_query, log_info, "Query from %s: OPCODE NOTIFY, q={%s,%s}", addr_to_string(&q->querier).c_str(), q->message->answers.begin()->NAME.tocstr(), str_type(q->message->answers.begin()->TYPE).c_str()); } else { pos_log(context_query, log_info, "Query from %s: OPCODE %s, qd=%d, ad=%d", addr_to_string(&q->querier).c_str(), str_opcode(q->message->OPCODE).c_str(), q->message->questions.size(), q->message->answers.size()); } } catch (PException p) { pos_log(context_query, log_error, "Error logging query!"); } } switch (q->message->OPCODE) { case OPCODE_QUERY: if (q->message->questions.size() != 1) return new_srvfail(q->message, RCODE_QUERYERR); switch (q->message->questions.begin()->QTYPE) { case QTYPE_AXFR: return answer_axfr(q); case QTYPE_IXFR: /* zone transfers */ return new_srvfail(q->message, RCODE_NOTIMP); default: return answer_stdquery(q); } case OPCODE_NOTIFY: return answer_notify(q); default: return new_srvfail(q->message, RCODE_NOTIMP); } }