auth_srv_unittest.cc 39 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 26 27 28 29
#include <gtest/gtest.h>

#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <dns/rdataclass.h>
30
#include <dns/tsig.h>
31

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

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

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

JINMEI Tatuya's avatar
JINMEI Tatuya committed
46
using namespace std;
47
using namespace isc::cc;
48
using namespace isc::dns;
49
using namespace isc::util;
50
using namespace isc::dns::rdata;
51
using namespace isc::data;
52
using namespace isc::xfr;
53 54
using namespace isc::asiodns;
using namespace isc::asiolink;
55
using namespace isc::testutils;
56
using namespace isc::server_common::portconfig;
Evan Hunt's avatar
Evan Hunt committed
57
using isc::UnitTestUtil;
58
using boost::shared_ptr;
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 74
        rrclass(RRClass::IN()),
        sock_requestor_(dnss_, address_store_, 53210)
75 76
    {
        server.setDNSService(dnss_);
77
        server.setXfrinSession(&notify_session);
78
        server.setStatisticsSession(&statistics_session);
79
    }
80 81 82 83
    virtual void processMessage() {
        server.processMessage(*io_message, parse_message, response_obuffer,
                              &dnsserv);
    }
84 85
    IOService ios_;
    DNSService dnss_;
86
    MockSession statistics_session;
87
    MockXfroutClient xfrout;
88
    AuthSrv server;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
89
    const RRClass rrclass;
90
    vector<uint8_t> response_data;
91
    AddressList address_store_;
92
    TestSocketRequestor sock_requestor_;
93 94
};

95 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
// 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,
163
                                     response_message,
164 165
                                     response_obuffer, &dnsserv);
    (*server.getDNSAnswerProvider())(*io_message, parse_message,
166
                                     response_message, response_obuffer);
167 168 169 170 171 172 173 174 175 176 177 178

    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,
179
                                     response_message,
180 181
                                     response_obuffer, &dnsserv);
    (*server.getDNSAnswerProvider())(*io_message, parse_message,
182
                                     response_message, response_obuffer);
183 184 185 186 187 188 189 190 191

    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());
}

192 193
// Unsupported requests.  Should result in NOTIMP.
TEST_F(AuthSrvTest, unsupportedRequest) {
194
    unsupportedRequest();
195
}
196 197 198

// Multiple questions.  Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
199
    multiQuestion();
200 201
}

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

// 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) {
211
    response();
212 213 214 215
}

// Query with a broken question
TEST_F(AuthSrvTest, shortQuestion) {
216
    shortQuestion();
217
}
218

219 220
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
221
    shortAnswer();
222 223
}

224 225
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
226
    ednsBadVers();
227 228
}

JINMEI Tatuya's avatar
JINMEI Tatuya committed
229
TEST_F(AuthSrvTest, AXFROverUDP) {
230
    axfrOverUDP();
JINMEI Tatuya's avatar
JINMEI Tatuya committed
231 232
}

233 234
TEST_F(AuthSrvTest, AXFRSuccess) {
    EXPECT_FALSE(xfrout.isConnected());
Evan Hunt's avatar
Evan Hunt committed
235
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
236 237
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
238
    createRequestPacket(request_message, IPPROTO_TCP);
239 240
    // 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
241 242
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
243
    EXPECT_TRUE(xfrout.isConnected());
244 245
}

246 247 248 249
// 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
250
    const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
251 252
    TSIGContext context(key);
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
253 254
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
255 256
    createRequestPacket(request_message, IPPROTO_UDP, &context);

257
    // Run the message through the server
258 259 260
    shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
    keyring->add(key);
    server.setTSIGKeyRing(&keyring);
261 262 263 264 265 266 267 268 269 270
    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);
271
    m.fromWire(ib);
272 273

    const TSIGRecord* tsig = m.getTSIGRecord();
274
    ASSERT_TRUE(tsig != NULL) << "Missing TSIG signature";
275 276 277 278 279 280 281 282
    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
283
TEST_F(AuthSrvTest, TSIGSignedBadKey) {
284 285 286
    TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
    TSIGContext context(key);
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
287 288
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
289 290 291
    createRequestPacket(request_message, IPPROTO_UDP, &context);

    // Process the message, but use a different key there
292 293
    shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
    server.setTSIGKeyRing(&keyring);
294 295 296 297 298 299 300 301 302
    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);
303
    m.fromWire(ib);
304 305

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

// 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
319 320
                                       Name("version.bind"), RRClass::CH(),
                                       RRType::TXT());
321 322
    createRequestPacket(request_message, IPPROTO_UDP, &context);

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

    EXPECT_TRUE(dnsserv.hasAnswer());
331
    headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
332 333 334 335
                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);
336
    m.fromWire(ib);
337 338

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

346 347 348 349 350 351 352 353 354 355 356 357 358
// 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);

359 360 361 362
    // Process the message, but use a different key there
    shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
    keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
    server.setTSIGKeyRing(&keyring);
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
    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";
}

382 383 384
TEST_F(AuthSrvTest, AXFRConnectFail) {
    EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
    xfrout.disableConnect();
Evan Hunt's avatar
Evan Hunt committed
385
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
386 387
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
388 389 390
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
391
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
392 393 394 395 396 397 398
                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
399
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
400 401
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
402 403
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
404
    EXPECT_TRUE(xfrout.isConnected());
405 406

    xfrout.disableSend();
407 408
    parse_message->clear(Message::PARSE);
    response_obuffer->clear();
Evan Hunt's avatar
Evan Hunt committed
409
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
410 411
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
412 413 414
    createRequestPacket(request_message, IPPROTO_TCP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
415
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
416 417 418 419 420 421 422 423 424 425 426
                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
427
    UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Jelte Jansen's avatar
Jelte Jansen committed
428 429
                                       Name("example.com"), RRClass::IN(),
                                       RRType::AXFR());
Evan Hunt's avatar
Evan Hunt committed
430
    createRequestPacket(request_message, IPPROTO_TCP);
431
    EXPECT_THROW(server.processMessage(*io_message, parse_message,
Evan Hunt's avatar
Evan Hunt committed
432
                                       response_obuffer, &dnsserv),
433 434 435 436 437 438 439
                 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();
}

440 441 442 443
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
444 445
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
446 447 448 449 450 451 452 453 454 455 456 457
    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
458 459
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
460 461 462 463 464 465 466 467
    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
468 469
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
    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
486 487
                                       Name("example.com"), RRClass::IN(),
                                       RRType::IXFR());
488 489 490 491 492 493 494 495 496 497
    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();
}

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

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

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

523
    // The question must be identical to that of the received notify
524
    ConstQuestionPtr question = *parse_message->beginQuestion();
525 526 527 528 529
    EXPECT_EQ(Name("example.com"), question->getName());
    EXPECT_EQ(RRClass::IN(), question->getClass());
    EXPECT_EQ(RRType::SOA(), question->getType());
}

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

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

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

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

TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
Jelte Jansen's avatar
Jelte Jansen committed
577 578 579
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
580
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
581 582 583
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
584
    headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
585 586 587 588 589
                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
590 591 592
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
Evan Hunt's avatar
Evan Hunt committed
593 594 595
    createRequestPacket(request_message, IPPROTO_UDP);
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
596
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
597 598 599 600
                Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}

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

613
TEST_F(AuthSrvTest, notifyWithoutSession) {
614
    server.setXfrinSession(NULL);
615

Jelte Jansen's avatar
Jelte Jansen committed
616 617 618
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
619
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
620
    createRequestPacket(request_message, IPPROTO_UDP);
621 622 623

    // we simply ignore the notify and let it be resent if an internal error
    // happens.
Evan Hunt's avatar
Evan Hunt committed
624 625
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
626 627 628 629 630
}

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

Jelte Jansen's avatar
Jelte Jansen committed
631 632 633
    UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::SOA());
634
    request_message.setHeaderFlag(Message::HEADERFLAG_AA);
Evan Hunt's avatar
Evan Hunt committed
635
    createRequestPacket(request_message, IPPROTO_UDP);
636

Evan Hunt's avatar
Evan Hunt committed
637 638
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_FALSE(dnsserv.hasAnswer());
639 640 641 642 643
}

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

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

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

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

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

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

678
void
JINMEI Tatuya's avatar
JINMEI Tatuya committed
679
updateConfig(AuthSrv* server, const char* const config_data,
680 681
             const bool expect_success)
{
682
    ConstElementPtr config_answer =
JINMEI Tatuya's avatar
JINMEI Tatuya committed
683
        server->updateConfig(Element::fromJSON(config_data));
684 685 686
    EXPECT_EQ(Element::map, config_answer->getType());
    EXPECT_TRUE(config_answer->contains("result"));

687
    ConstElementPtr result = config_answer->get("result");
688
    EXPECT_EQ(Element::list, result->getType());
689
    EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
690 691 692 693
}

// Install a Sqlite3 data source with testing data.
TEST_F(AuthSrvTest, updateConfig) {
694
    updateConfig(&server, CONFIG_TESTDB, true);
695 696 697 698

    // 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.
699
    createDataFromFile("examplequery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
700 701
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
702
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
703 704 705 706
                QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}

TEST_F(AuthSrvTest, datasourceFail) {
707
    updateConfig(&server, CONFIG_TESTDB, true);
708 709 710 711 712

    // 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.
713
    createDataFromFile("badExampleQuery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
714 715
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
716
    headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
717
                opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
718
}
719 720 721 722 723 724 725 726 727

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.
728
    createDataFromFile("examplequery_fromWire.wire");
Evan Hunt's avatar
Evan Hunt committed
729 730
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
    EXPECT_TRUE(dnsserv.hasAnswer());
731
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
732 733
                QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
JINMEI Tatuya's avatar
JINMEI Tatuya committed
734

735
TEST_F(AuthSrvTest, updateWithInMemoryClient) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
736 737 738 739
    // 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
740
    EXPECT_EQ(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
741 742 743
    updateConfig(&server,
                 "{\"datasources\": [{\"type\": \"memory\"}]}", true);
    // after successful configuration, we should have one (with empty zoneset).
744 745
    ASSERT_NE(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
    EXPECT_EQ(0, server.getInMemoryClient(rrclass)->getZoneCount());
Jerry's avatar
Jerry committed
746

747
    // The memory data source is empty, should return REFUSED rcode.
Jerry's avatar
Jerry committed
748
    createDataFromFile("examplequery_fromWire.wire");
749 750 751 752 753 754 755
    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);
}

756
TEST_F(AuthSrvTest, chQueryWithInMemoryClient) {
757 758 759 760 761 762 763 764 765 766 767
    // 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);
768
    EXPECT_TRUE(dnsserv.hasAnswer());
769 770
    headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
                opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
771 772
}

JINMEI Tatuya's avatar
JINMEI Tatuya committed
773 774 775 776 777 778 779 780 781
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());
}
782

783 784 785
// Submit UDP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterUDPNormal) {
    // The counter should be initialized to 0.
786
    EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
787 788 789 790 791 792 793
    // 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);
794
    // After processing UDP query, the counter should be 1.
795
    EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
796 797
}

798 799 800
// Submit TCP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPNormal) {
    // The counter should be initialized to 0.
801
    EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
802 803 804 805 806 807 808
    // 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);
809
    // After processing TCP query, the counter should be 1.
810
    EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
811 812 813 814 815
}

// Submit TCP AXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
    // The counter should be initialized to 0.
816
    EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
817 818 819 820
    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
821
    // so auth itself shouldn't respond.
822
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
Jelte Jansen's avatar
Jelte Jansen committed
823
    EXPECT_FALSE(dnsserv.hasAnswer());
824
    // After processing TCP AXFR query, the counter should be 1.
825
    EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
826 827
}

828 829 830 831 832 833 834
// Submit TCP IXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
    // The counter should be initialized to 0.
    EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
    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
835 836
    // On success, the IXFR query has been passed to a separate process,
    // so auth itself shouldn't respond.
837
    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
Jelte Jansen's avatar
Jelte Jansen committed
838 839
    EXPECT_FALSE(dnsserv.hasAnswer());
    // After processing TCP IXFR query, the counter should be 1.
840 841 842
    EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
}

843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
// 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);
}

860
// Submit unexpected type of query and check it throws isc::Unexpected
861
TEST_F(AuthSrvTest, queryCounterUnexpected) {
862 863 864 865
    // 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.

866
    // Create UDP query packet.
867 868 869 870
    UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                       default_qid, Name("example.com"),
                                       RRClass::IN(), RRType::NS());
    createRequestPacket(request_message, IPPROTO_UDP);
871

872
    // Modify the message.
873 874
    delete io_message;
    endpoint = IOEndpoint::create(IPPROTO_UDP,
875
                                  IOAddress(DEFAULT_REMOTE_ADDRESS), 53210);
876 877 878 879 880
    io_message = new IOMessage(request_renderer.getData(),
                               request_renderer.getLength(),
                               getDummyUnknownSocket(), *endpoint);

    EXPECT_THROW(server.processMessage(*io_message, parse_message,
881
                                       response_obuffer, &dnsserv),
882
                 isc::Unexpected);
883
}
884 885 886 887 888

TEST_F(AuthSrvTest, stop) {
    // normal case is covered in command_unittest.cc.  we should primarily
    // test it here, but the current design of the stop test takes time,
    // so we consolidate the cases in the command tests.
889 890
    // If/when the interval timer has finer granularity we'll probably add
    // our own tests here, so we keep this empty test case.
891
}
892 893

TEST_F(AuthSrvTest, listenAddresses) {
894
    isc::testutils::portconfig::listenAddresses(server);
895 896 897 898 899 900 901 902
    // Check it requests the correct addresses
    const char* tokens[] = {
        "TCP:127.0.0.1:53210:1",
        "UDP:127.0.0.1:53210:2",
        "TCP:::1:53210:3",
        "UDP:::1:53210:4",
        NULL
    };
903 904
    sock_requestor_.checkTokens(tokens, sock_requestor_.given_tokens_,
                                "Given tokens");
905 906
    // It returns back to empty set of addresses afterwards, so
    // they should be released