auth_srv_unittest.cc 40.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

15
#include <config.h>
16 17 18

#include <vector>

19 20
#include <boost/shared_ptr.hpp>

21 22 23 24 25
#include <gtest/gtest.h>

#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
26
#include <dns/opcode.h>
27 28 29 30
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <dns/rdataclass.h>
31
#include <dns/tsig.h>
32

33
#include <server_common/portconfig.h>
34
#include <server_common/keyring.h>
35

JINMEI Tatuya's avatar
JINMEI Tatuya committed
36
#include <datasrc/memory_datasrc.h>
37
#include <auth/auth_srv.h>
38
#include <auth/common.h>
39
#include <auth/statistics.h>
40

41
#include <dns/tests/unittest_util.h>
JINMEI Tatuya's avatar
JINMEI Tatuya committed
42
#include <testutils/dnsmessage_test.h>
43
#include <testutils/srv_test.h>
44
#include <testutils/portconfig.h>
45
#include <testutils/socket_request.h>
46

JINMEI Tatuya's avatar
JINMEI Tatuya committed
47
using namespace std;
48
using namespace isc::cc;
49
using namespace isc::dns;
50
using namespace isc::util;
51
using namespace isc::dns::rdata;
52
using namespace isc::data;
53
using namespace isc::xfr;
54 55
using namespace isc::asiodns;
using namespace isc::asiolink;
56
using namespace isc::testutils;
57
using namespace isc::server_common::portconfig;
Evan Hunt's avatar
Evan Hunt committed
58
using isc::UnitTestUtil;
59 60

namespace {
61
const char* const CONFIG_TESTDB =
62
    "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\"}";
63 64
// The following file must be non existent and must be non"creatable" (see
// the sqlite3 test).
65
const char* const BADCONFIG_TESTDB =
66
    "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
67

68
class AuthSrvTest : public SrvTestBase {
69
protected:
70 71 72
    AuthSrvTest() :
        dnss_(ios_, NULL, NULL, NULL),
        server(true, xfrout),
73
        rrclass(RRClass::IN()),
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
74 75 76
        // The empty string is expected value of the parameter of
        // requestSocket, not the app_name (there's no fallback, it checks
        // the empty string is passed).
77
        sock_requestor_(dnss_, address_store_, 53210, "")
78 79
    {
        server.setDNSService(dnss_);
80
        server.setXfrinSession(&notify_session);
81
        server.setStatisticsSession(&statistics_session);
82
    }
83 84 85 86
    virtual void processMessage() {
        server.processMessage(*io_message, parse_message, response_obuffer,
                              &dnsserv);
    }
87 88
    IOService ios_;
    DNSService dnss_;
89
    MockSession statistics_session;
90
    MockXfroutClient xfrout;
91
    AuthSrv server;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
92
    const RRClass rrclass;
93
    vector<uint8_t> response_data;
94
    AddressList address_store_;
95
    TestSocketRequestor sock_requestor_;
96 97
};

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
// A helper function that builds a response to version.bind/TXT/CH that
// should be identical to the response from our builtin (static) data source
// by default.  The resulting wire-format data will be stored in 'data'.
void
createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
    const Name version_name("version.bind");
    Message message(Message::RENDER);

    UnitTestUtil::createRequestMessage(message, Opcode::QUERY(),
                                       qid, version_name,
                                       RRClass::CH(), RRType::TXT());
    message.setHeaderFlag(Message::HEADERFLAG_QR);
    message.setHeaderFlag(Message::HEADERFLAG_AA);
    RRsetPtr rrset_version = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                                RRType::TXT(), RRTTL(0)));
    rrset_version->addRdata(generic::TXT(PACKAGE_STRING));
    message.addRRset(Message::SECTION_ANSWER, rrset_version);

    RRsetPtr rrset_version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                                   RRType::NS(), RRTTL(0)));
    rrset_version_ns->addRdata(generic::NS(version_name));
    message.addRRset(Message::SECTION_AUTHORITY, rrset_version_ns);

    OutputBuffer obuffer(0);
    MessageRenderer renderer(obuffer);
    message.toWire(renderer);

    data.clear();
    data.assign(static_cast<const uint8_t*>(renderer.getData()),
                static_cast<const uint8_t*>(renderer.getData()) +
                renderer.getLength());
}

// In the following tests we confirm the response data is rendered in
// wire format in the expected way.

// The most primitive check: checking the result of the processMessage()
// method
TEST_F(AuthSrvTest, builtInQuery) {
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("version.bind"),
                                       RRClass::CH(), RRType::TXT());
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);
    createBuiltinVersionResponse(default_qid, response_data);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        response_obuffer->getData(),
                        response_obuffer->getLength(),
                        &response_data[0], response_data.size());
}

// Same test emulating the UDPServer class behavior (defined in libasiolink).
// This is not a good test in that it assumes internal implementation details
// of UDPServer, but we've encountered a regression due to the introduction
// of that class, so we add a test for that case to prevent such a regression
// in future.
// Besides, the generalization of UDPServer is probably too much for the
// authoritative only server in terms of performance, and it's quite likely
// we need to drop it for the authoritative server implementation.
// At that point we can drop this test, too.
TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("version.bind"),
                                       RRClass::CH(), RRType::TXT());
    createRequestPacket(request_message, IPPROTO_UDP);

    (*server.getDNSLookupProvider())(*io_message, parse_message,
166
                                     response_message,
167 168
                                     response_obuffer, &dnsserv);
    (*server.getDNSAnswerProvider())(*io_message, parse_message,
169
                                     response_message, response_obuffer);
170 171 172 173 174 175 176 177 178 179 180 181

    createBuiltinVersionResponse(default_qid, response_data);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        response_obuffer->getData(),
                        response_obuffer->getLength(),
                        &response_data[0], response_data.size());
}

// Same type of test as builtInQueryViaDNSServer but for an error response.
TEST_F(AuthSrvTest, iqueryViaDNSServer) {
    createDataFromFile("iquery_fromWire.wire");
    (*server.getDNSLookupProvider())(*io_message, parse_message,
182
                                     response_message,
183 184
                                     response_obuffer, &dnsserv);
    (*server.getDNSAnswerProvider())(*io_message, parse_message,
185
                                     response_message, response_obuffer);
186 187 188 189 190 191 192 193 194

    UnitTestUtil::readWireData("iquery_response_fromWire.wire",
                               response_data);
    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        response_obuffer->getData(),
                        response_obuffer->getLength(),
                        &response_data[0], response_data.size());
}

195 196
// Unsupported requests.  Should result in NOTIMP.
TEST_F(AuthSrvTest, unsupportedRequest) {
197
    unsupportedRequest();
198
}
199 200 201

// Multiple questions.  Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
202
    multiQuestion();
203 204
}

205 206 207
// Incoming data doesn't even contain the complete header.  Must be silently
// dropped.
TEST_F(AuthSrvTest, shortMessage) {
208
    shortMessage();
209 210 211 212 213
}

// Response messages.  Must be silently dropped, whether it's a valid response
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
214
    response();
215 216 217 218
}

// Query with a broken question
TEST_F(AuthSrvTest, shortQuestion) {
219
    shortQuestion();
220
}
221

222 223
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
224
    shortAnswer();
225 226
}

227 228
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
229
    ednsBadVers();
230 231
}

JINMEI Tatuya's avatar
JINMEI Tatuya committed
232
TEST_F(AuthSrvTest, AXFROverUDP) {
233
    axfrOverUDP();
JINMEI Tatuya's avatar
JINMEI Tatuya committed
234 235
}

236 237
TEST_F(AuthSrvTest, AXFRSuccess) {
    EXPECT_FALSE(xfrout.isConnected());
Evan Hunt's avatar
Evan Hunt committed
238
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
239 240
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
241
    createRequestPacket(request_message, IPPROTO_TCP);
242 243
    // On success, the AXFR query has been passed to a separate process,
    // so we shouldn't have to respond.
Evan Hunt's avatar
Evan Hunt committed
244 245
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
246
    EXPECT_TRUE(xfrout.isConnected());
247 248
}

249 250 251 252
// Try giving the server a TSIG signed request and see it can anwer signed as
// well
TEST_F(AuthSrvTest, TSIGSigned) {
    // Prepare key, the client message, etc
253
    const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
254 255
    TSIGContext context(key);
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
256 257
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
258 259
    createRequestPacket(request_message, IPPROTO_UDP, &context);

260
    // Run the message through the server
261
    boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
262 263
    keyring->add(key);
    server.setTSIGKeyRing(&keyring);
264 265 266 267 268 269 270 271 272 273
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);

    // What did we get?
    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
                opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
    // We need to parse the message ourself, or getTSIGRecord won't work
    InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
    Message m(Message::PARSE);
274
    m.fromWire(ib);
275 276

    const TSIGRecord* tsig = m.getTSIGRecord();
277
    ASSERT_TRUE(tsig != NULL) << "Missing TSIG signature";
278 279 280 281 282 283 284 285
    TSIGError error(context.verify(tsig, response_obuffer->getData(),
                                   response_obuffer->getLength()));
    EXPECT_EQ(TSIGError::NOERROR(), error) <<
        "The server signed the response, but it doesn't seem to be valid";
}

// Give the server a signed request, but don't give it the key. It will
// not be able to verify it, returning BADKEY
286
TEST_F(AuthSrvTest, TSIGSignedBadKey) {
287 288 289
    TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
    TSIGContext context(key);
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
290 291
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
292 293 294
    createRequestPacket(request_message, IPPROTO_UDP, &context);

    // Process the message, but use a different key there
295
    boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
296
    server.setTSIGKeyRing(&keyring);
297 298 299 300 301 302 303 304 305
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);

    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, TSIGError::BAD_KEY().toRcode(),
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
    // We need to parse the message ourself, or getTSIGRecord won't work
    InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
    Message m(Message::PARSE);
306
    m.fromWire(ib);
307 308

    const TSIGRecord* tsig = m.getTSIGRecord();
309
    ASSERT_TRUE(tsig != NULL) <<
310
        "Missing TSIG signature (we should have one even at error)";
311
    EXPECT_EQ(TSIGError::BAD_KEY_CODE, tsig->getRdata().getError());
312 313
    EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
        "It should be unsigned with this error";
314 315 316 317 318 319 320 321
}

// Give the server a signed request, but signed by a different key
// (with the same name). It should return BADSIG
TEST_F(AuthSrvTest, TSIGBadSig) {
    TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
    TSIGContext context(key);
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
322 323
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
324 325
    createRequestPacket(request_message, IPPROTO_UDP, &context);

326
    // Process the message, but use a different key there
327
    boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
328 329
    keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
    server.setTSIGKeyRing(&keyring);
330 331 332 333
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);

    EXPECT_TRUE(dnsserv.hasAnswer());
334
    headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
335 336 337 338
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
    // We need to parse the message ourself, or getTSIGRecord won't work
    InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
    Message m(Message::PARSE);
339
    m.fromWire(ib);
340 341

    const TSIGRecord* tsig = m.getTSIGRecord();
342
    ASSERT_TRUE(tsig != NULL) <<
343
        "Missing TSIG signature (we should have one even at error)";
344
    EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
345 346
    EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
        "It should be unsigned with this error";
347 348
}

349 350 351 352 353 354 355 356 357 358 359 360 361
// Give the server a signed unsupported request with a bad signature.
// This checks the server first verifies the signature before anything
// else.
TEST_F(AuthSrvTest, TSIGCheckFirst) {
    TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
    TSIGContext context(key);
    // Pass a wrong opcode there. The server shouldn't know what to do
    // about it.
    UnitTestUtil::createRequestMessage(request_message, Opcode::RESERVED14(),
                                       default_qid, Name("version.bind"),
                                       RRClass::CH(), RRType::TXT());
    createRequestPacket(request_message, IPPROTO_UDP, &context);

362
    // Process the message, but use a different key there
363
    boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
364 365
    keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
    server.setTSIGKeyRing(&keyring);
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);

    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
                Opcode::RESERVED14().getCode(), QR_FLAG, 0, 0, 0, 0);
    // We need to parse the message ourself, or getTSIGRecord won't work
    InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
    Message m(Message::PARSE);
    m.fromWire(ib);

    const TSIGRecord* tsig = m.getTSIGRecord();
    ASSERT_TRUE(tsig != NULL) <<
        "Missing TSIG signature (we should have one even at error)";
    EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
    EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
        "It should be unsigned with this error";
383 384 385
    // TSIG should have failed, and so the per opcode counter shouldn't be
    // incremented.
    EXPECT_EQ(0, server.getCounter(Opcode::RESERVED14()));
386 387
}

388 389 390
TEST_F(AuthSrvTest, AXFRConnectFail) {
    EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
    xfrout.disableConnect();
Evan Hunt's avatar
Evan Hunt committed
391
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
392 393
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
394 395 396
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
397
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
398 399 400 401 402 403 404
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
    EXPECT_FALSE(xfrout.isConnected());
}

TEST_F(AuthSrvTest, AXFRSendFail) {
    // first send a valid query, making the connection with the xfr process
    // open.
Evan Hunt's avatar
Evan Hunt committed
405
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
406 407
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
408 409
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
410
    EXPECT_TRUE(xfrout.isConnected());
411 412

    xfrout.disableSend();
413 414
    parse_message->clear(Message::PARSE);
    response_obuffer->clear();
Evan Hunt's avatar
Evan Hunt committed
415
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
416 417
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
418 419 420
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
421
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
422 423 424 425 426 427 428 429 430 431 432
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);

    // The connection should have been closed due to the send failure.
    EXPECT_FALSE(xfrout.isConnected());
}

TEST_F(AuthSrvTest, AXFRDisconnectFail) {
    // In our usage disconnect() shouldn't fail.  So we'll see the exception
    // should it be thrown.
    xfrout.disableSend();
    xfrout.disableDisconnect();
Evan Hunt's avatar
Evan Hunt committed
433
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
434 435
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
436
    createRequestPacket(request_message, IPPROTO_TCP);
437
    EXPECT_THROW(server.processMessage(*io_message, parse_message,
Evan Hunt's avatar
Evan Hunt committed
438
                                       response_obuffer, &dnsserv),
439 440 441 442 443 444 445
                 XfroutError);
    EXPECT_TRUE(xfrout.isConnected());
    // XXX: we need to re-enable disconnect.  otherwise an exception would be
    // thrown via the destructor of the server.
    xfrout.enableDisconnect();
}

446 447 448 449
TEST_F(AuthSrvTest, IXFRConnectFail) {
    EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
    xfrout.disableConnect();
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
450 451
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
452 453 454 455 456 457 458 459 460 461 462 463
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
    EXPECT_FALSE(xfrout.isConnected());
}

TEST_F(AuthSrvTest, IXFRSendFail) {
    // first send a valid query, making the connection with the xfr process
    // open.
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
464 465
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
466 467 468 469 470 471 472 473
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(xfrout.isConnected());

    xfrout.disableSend();
    parse_message->clear(Message::PARSE);
    response_obuffer->clear();
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
474 475
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);

    // The connection should have been closed due to the send failure.
    EXPECT_FALSE(xfrout.isConnected());
}

TEST_F(AuthSrvTest, IXFRDisconnectFail) {
    // In our usage disconnect() shouldn't fail.  So we'll see the exception
    // should it be thrown.
    xfrout.disableSend();
    xfrout.disableDisconnect();
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
492 493
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
494 495 496 497 498 499 500 501 502 503
    createRequestPacket(request_message, IPPROTO_TCP);
    EXPECT_THROW(server.processMessage(*io_message, parse_message,
                                       response_obuffer, &dnsserv),
                 XfroutError);
    EXPECT_TRUE(xfrout.isConnected());
    // XXX: we need to re-enable disconnect.  otherwise an exception would be
    // thrown via the destructor of the server.
    xfrout.enableDisconnect();
}

504
TEST_F(AuthSrvTest, notify) {
Jelte Jansen's avatar
Jelte Jansen committed
505 506 507
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
508
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
509 510 511
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
512 513 514

    // An internal command message should have been created and sent to an
    // external module.  Check them.
Evan Hunt's avatar
Evan Hunt committed
515
    EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
516
    EXPECT_EQ("notify",
Evan Hunt's avatar
Evan Hunt committed
517
              notify_session.getSentMessage()->get("command")->get(0)->stringValue());
518
    ConstElementPtr notify_args =
Evan Hunt's avatar
Evan Hunt committed
519
        notify_session.getSentMessage()->get("command")->get(1);
520 521 522
    EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
    EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
              notify_args->get("master")->stringValue());
523
    EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
524 525

    // On success, the server should return a response to the notify.
526
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
527 528
                Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);

529
    // The question must be identical to that of the received notify
530
    ConstQuestionPtr question = *parse_message->beginQuestion();
531 532 533 534 535
    EXPECT_EQ(Name("example.com"), question->getName());
    EXPECT_EQ(RRClass::IN(), question->getClass());
    EXPECT_EQ(RRType::SOA(), question->getType());
}

536 537
TEST_F(AuthSrvTest, notifyForCHClass) {
    // Same as the previous test, but for the CH RRClass.
Jelte Jansen's avatar
Jelte Jansen committed
538 539 540
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::CH(), RRType::SOA());
541
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
542 543 544
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
545 546 547

    // Other conditions should be the same, so simply confirm the RR class is
    // set correctly.
548
    ConstElementPtr notify_args =
Evan Hunt's avatar
Evan Hunt committed
549
        notify_session.getSentMessage()->get("command")->get(1);
550
    EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
551 552
}

553 554 555
TEST_F(AuthSrvTest, notifyEmptyQuestion) {
    request_message.clear(Message::RENDER);
    request_message.setOpcode(Opcode::NOTIFY());
556
    request_message.setRcode(Rcode::NOERROR());
557
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
558 559
    request_message.setQid(default_qid);
    request_message.toWire(request_renderer);
Evan Hunt's avatar
Evan Hunt committed
560 561 562
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
563
    headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
564 565 566 567
                Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
}

TEST_F(AuthSrvTest, notifyMultiQuestions) {
Jelte Jansen's avatar
Jelte Jansen committed
568 569 570
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
571 572 573
    // add one more SOA question
    request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
                                         RRType::SOA()));
574
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
575 576 577
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
578
    headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
579 580 581 582
                Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
}

TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
Jelte Jansen's avatar
Jelte Jansen committed
583 584 585
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
586
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
587 588 589
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
590
    headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
591 592 593 594 595
                Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
}

TEST_F(AuthSrvTest, notifyWithoutAA) {
    // implicitly leave the AA bit off.  our implementation will accept it.
Jelte Jansen's avatar
Jelte Jansen committed
596 597 598
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
Evan Hunt's avatar
Evan Hunt committed
599 600 601
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
602
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
603 604 605 606
                Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}

TEST_F(AuthSrvTest, notifyWithErrorRcode) {
Jelte Jansen's avatar
Jelte Jansen committed
607 608 609
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
610
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
611
    request_message.setRcode(Rcode::SERVFAIL());
Evan Hunt's avatar
Evan Hunt committed
612 613 614
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
615
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
616
                Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
Han Feng's avatar
Han Feng committed
617 618
}

619
TEST_F(AuthSrvTest, notifyWithoutSession) {
620
    server.setXfrinSession(NULL);
621

Jelte Jansen's avatar
Jelte Jansen committed
622 623 624
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
625
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
626
    createRequestPacket(request_message, IPPROTO_UDP);
627 628 629

    // we simply ignore the notify and let it be resent if an internal error
    // happens.
Evan Hunt's avatar
Evan Hunt committed
630 631
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
632 633 634 635 636
}

TEST_F(AuthSrvTest, notifySendFail) {
    notify_session.disableSend();

Jelte Jansen's avatar
Jelte Jansen committed
637 638 639
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
640
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
641
    createRequestPacket(request_message, IPPROTO_UDP);
642

Evan Hunt's avatar
Evan Hunt committed
643 644
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
645 646 647 648 649
}

TEST_F(AuthSrvTest, notifyReceiveFail) {
    notify_session.disableReceive();

Jelte Jansen's avatar
Jelte Jansen committed
650 651 652
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
653
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
654 655 656
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
657 658 659
}

TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
660
    notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
661

Jelte Jansen's avatar
Jelte Jansen committed
662 663 664
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
665
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
666 667 668
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
669 670 671 672
}

TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
    notify_session.setMessage(
673
        Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
674

Jelte Jansen's avatar
Jelte Jansen committed
675 676 677
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
678
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
679 680 681
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
682 683
}

684
void
JINMEI Tatuya's avatar
JINMEI Tatuya committed
685
updateConfig(AuthSrv* server, const char* const config_data,
686 687
             const bool expect_success)
{
688
    ConstElementPtr config_answer =
JINMEI Tatuya's avatar
JINMEI Tatuya committed
689
        server->updateConfig(Element::fromJSON(config_data));
690 691 692
    EXPECT_EQ(Element::map, config_answer->getType());
    EXPECT_TRUE(config_answer->contains("result"));

693
    ConstElementPtr result = config_answer->get("result");
694
    EXPECT_EQ(Element::list, result->getType());
695
    EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
696 697 698 699
}

// Install a Sqlite3 data source with testing data.
TEST_F(AuthSrvTest, updateConfig) {
700
    updateConfig(&server, CONFIG_TESTDB, true);
701 702 703 704

    // query for existent data in the installed data source.  The resulting
    // response should have the AA flag on, and have an RR in each answer
    // and authority section.
705
    createDataFromFile("examplequery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
706 707
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
708
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
709 710 711 712
                QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}

TEST_F(AuthSrvTest, datasourceFail) {
713
    updateConfig(&server, CONFIG_TESTDB, true);
714 715 716 717 718

    // This query will hit a corrupted entry of the data source (the zoneload
    // tool and the data source itself naively accept it).  This will result
    // in a SERVFAIL response, and the answer and authority sections should
    // be empty.
719
    createDataFromFile("badExampleQuery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
720 721
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
722
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
723
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
724
}
725 726 727 728 729 730 731 732 733

TEST_F(AuthSrvTest, updateConfigFail) {
    // First, load a valid data source.
    updateConfig(&server, CONFIG_TESTDB, true);

    // Next, try to update it with a non-existent one.  This should fail.
    updateConfig(&server, BADCONFIG_TESTDB, false);

    // The original data source should still exist.
734
    createDataFromFile("examplequery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
735 736
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
737
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
738 739
                QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
JINMEI Tatuya's avatar
JINMEI Tatuya committed
740

741
TEST_F(AuthSrvTest, updateWithInMemoryClient) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
742 743 744 745
    // Test configuring memory data source.  Detailed test cases are covered
    // in the configuration tests.  We only check the AuthSrv interface here.

    // By default memory data source isn't enabled
746
    EXPECT_EQ(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
747 748 749
    updateConfig(&server,
                 "{\"datasources\": [{\"type\": \"memory\"}]}", true);
    // after successful configuration, we should have one (with empty zoneset).
750 751
    ASSERT_NE(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
    EXPECT_EQ(0, server.getInMemoryClient(rrclass)->getZoneCount());
Jerry's avatar
Jerry committed
752

753
    // The memory data source is empty, should return REFUSED rcode.
Jerry's avatar
Jerry committed
754
    createDataFromFile("examplequery_fromWire.wire");
755 756 757 758 759 760 761
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
    headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
}

762
TEST_F(AuthSrvTest, chQueryWithInMemoryClient) {
763 764 765 766 767 768 769 770 771 772 773
    // Configure memory data source for class IN
    updateConfig(&server, "{\"datasources\": "
                 "[{\"class\": \"IN\", \"type\": \"memory\"}]}", true);

    // This shouldn't affect the result of class CH query
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("version.bind"),
                                       RRClass::CH(), RRType::TXT());
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);
774
    EXPECT_TRUE(dnsserv.hasAnswer());
775 776
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
                opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
777 778
}

JINMEI Tatuya's avatar
JINMEI Tatuya committed
779 780 781 782 783 784 785 786 787
TEST_F(AuthSrvTest, cacheSlots) {
    // simple check for the get/set operations
    server.setCacheSlots(10);    // 10 = arbitrary choice
    EXPECT_EQ(10, server.getCacheSlots());

    // 0 is a valid size
    server.setCacheSlots(0);
    EXPECT_EQ(00, server.getCacheSlots());
}
788

789 790 791
// Submit UDP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterUDPNormal) {
    // The counter should be initialized to 0.
792
    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
793 794 795 796 797 798 799
    // Create UDP message and process.
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);
800
    // After processing UDP query, the counter should be 1.
801
    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
802 803
}

804 805 806
// Submit TCP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPNormal) {
    // The counter should be initialized to 0.
807
    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
808 809 810 811 812 813 814
    // Create TCP message and process.
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer,
                          &dnsserv);
815
    // After processing TCP query, the counter should be 1.
816
    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
817 818 819 820 821
}

// Submit TCP AXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
    // The counter should be initialized to 0.
822
    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
823 824 825 826
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
                         Name("example.com"), RRClass::IN(), RRType::AXFR());
    createRequestPacket(request_message, IPPROTO_TCP);
    // On success, the AXFR query has been passed to a separate process,
Jelte Jansen's avatar
Jelte Jansen committed
827
    // so auth itself shouldn't respond.
828
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
Jelte Jansen's avatar
Jelte Jansen committed
829
    EXPECT_FALSE(dnsserv.hasAnswer());
830
    // After processing TCP AXFR query, the counter should be 1.
831
    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
832 833
}

834 835 836
// Submit TCP IXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
    // The counter should be initialized to 0.
837
    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
838 839 840
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
                         Name("example.com"), RRClass::IN(), RRType::IXFR());
    createRequestPacket(request_message, IPPROTO_TCP);
Jelte Jansen's avatar
Jelte Jansen committed
841 842
    // On success, the IXFR query has been passed to a separate process,
    // so auth itself shouldn't respond.
843
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
Jelte Jansen's avatar
Jelte Jansen committed
844 845
    EXPECT_FALSE(dnsserv.hasAnswer());
    // After processing TCP IXFR query, the counter should be 1.
846
    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
847 848
}

849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
TEST_F(AuthSrvTest, queryCounterOpcodes) {
    for (int i = 0; i < 16; ++i) {
        // The counter should be initialized to 0.
        EXPECT_EQ(0, server.getCounter(Opcode(i)));

        // For each possible opcode, create a request message and send it
        UnitTestUtil::createRequestMessage(request_message, Opcode(i),
                                           default_qid, Name("example.com"),
                                           RRClass::IN(), RRType::NS());
        createRequestPacket(request_message, IPPROTO_UDP);

        // "send" the request N-th times where N is i + 1 for i-th code.
        // we intentionally use different values for each code
        for (int j = 0; j <= i; ++j) {
            parse_message->clear(Message::PARSE);
            server.processMessage(*io_message, parse_message, response_obuffer,
                                  &dnsserv);
        }

        // Confirm the counter.
        EXPECT_EQ(i + 1, server.getCounter(Opcode(i)));
    }
}

873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
// class for queryCounterUnexpected test
// getProtocol() returns IPPROTO_IP
class DummyUnknownSocket : public IOSocket {
public:
    DummyUnknownSocket() {}
    virtual int getNative() const { return (0); }
    virtual int getProtocol() const { return (IPPROTO_IP); }
};

// function for queryCounterUnexpected test
// returns a reference to a static object of DummyUnknownSocket
IOSocket&
getDummyUnknownSocket() {
    static DummyUnknownSocket socket;
    return (socket);
}

890
// Submit unexpected type of query and check it throws isc::Unexpected
891
TEST_F(AuthSrvTest, queryCounterUnexpected) {
892 893 894 895
    // This code isn't exception safe, but we'd rather keep the code
    // simpler and more readable as this is only for tests and if it throws
    // the program would immediately terminate anyway.

896
    // Create UDP query packet.
897 898 899 900
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
    createRequestPacket(request_message, IPPROTO_UDP);
901

902
    // Modify the message.