Skip to content

Commit 0f716f2

Browse files
darosiorlaanwj
authored andcommitted
qa: cover PROTOCOL_ERROR variant in PCP unit tests
1 parent fc700bb commit 0f716f2

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

src/test/pcp_tests.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,5 +577,123 @@ BOOST_AUTO_TEST_CASE(pcp_ipv4_fail_unsupported_version)
577577
BOOST_CHECK_EQUAL(*err, MappingError::UNSUPP_VERSION);
578578
}
579579

580+
// NAT-PMP IPv4 protocol error scenarii.
581+
BOOST_AUTO_TEST_CASE(natpmp_protocol_error)
582+
{
583+
// First scenario: non-0 result code when requesting external IP.
584+
std::vector<TestOp> script{
585+
{
586+
0ms, TestOp::SEND,
587+
{
588+
0x00, 0x00, // version, opcode (request external IP)
589+
}, 0
590+
},
591+
{
592+
2ms, TestOp::RECV,
593+
{
594+
0x00, 0x80, 0x00, 0x42, // version, opcode (external IP), result code (*NOT* success)
595+
0x66, 0xfd, 0xa1, 0xee, // seconds sinds start of epoch
596+
0x01, 0x02, 0x03, 0x04, // external IP address
597+
}, 0
598+
},
599+
};
600+
CreateSock = [this, &script](int domain, int type, int protocol) {
601+
if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP) return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4, script);
602+
return std::unique_ptr<PCPTestSock>();
603+
};
604+
605+
auto res = NATPMPRequestPortMap(default_gateway_ipv4, 1234, 1000, 1, 200ms);
606+
607+
MappingError* err = std::get_if<MappingError>(&res);
608+
BOOST_REQUIRE(err);
609+
BOOST_CHECK_EQUAL(*err, MappingError::PROTOCOL_ERROR);
610+
611+
// First scenario: non-0 result code when requesting port mapping.
612+
script = {
613+
{
614+
0ms, TestOp::SEND,
615+
{
616+
0x00, 0x00, // version, opcode (request external IP)
617+
}, 0
618+
},
619+
{
620+
2ms, TestOp::RECV,
621+
{
622+
0x00, 0x80, 0x00, 0x00, // version, opcode (external IP), result code (success)
623+
0x66, 0xfd, 0xa1, 0xee, // seconds sinds start of epoch
624+
0x01, 0x02, 0x03, 0x04, // external IP address
625+
}, 0
626+
},
627+
{
628+
0ms, TestOp::SEND,
629+
{
630+
0x00, 0x02, 0x00, 0x00, // version, opcode (request map TCP)
631+
0x04, 0xd2, 0x04, 0xd2, // internal port, suggested external port
632+
0x00, 0x00, 0x03, 0xe8, // requested mapping lifetime in seconds
633+
}, 0
634+
},
635+
{
636+
2ms, TestOp::RECV,
637+
{
638+
0x00, 0x82, 0x00, 0x43, // version, opcode (mapped TCP)
639+
0x66, 0xfd, 0xa1, 0xee, // seconds sinds start of epoch
640+
0x04, 0xd2, 0x04, 0xd2, // internal port, mapped external port
641+
0x00, 0x00, 0x01, 0xf4, // mapping lifetime in seconds
642+
}, 0
643+
},
644+
};
645+
CreateSock = [this, &script](int domain, int type, int protocol) {
646+
if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP) return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4, script);
647+
return std::unique_ptr<PCPTestSock>();
648+
};
649+
650+
res = NATPMPRequestPortMap(default_gateway_ipv4, 1234, 1000, 1, 200ms);
651+
652+
err = std::get_if<MappingError>(&res);
653+
BOOST_REQUIRE(err);
654+
BOOST_CHECK_EQUAL(*err, MappingError::PROTOCOL_ERROR);
655+
}
656+
657+
// PCP IPv4 protocol error scenario.
658+
BOOST_AUTO_TEST_CASE(pcp_protocol_error)
659+
{
660+
const std::vector<TestOp> script{
661+
{
662+
0ms, TestOp::SEND,
663+
{
664+
0x02, 0x01, 0x00, 0x00, // version, opcode
665+
0x00, 0x00, 0x03, 0xe8, // lifetime
666+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06, // internal IP
667+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // nonce
668+
0x06, 0x00, 0x00, 0x00, // protocol (TCP), reserved
669+
0x04, 0xd2, 0x04, 0xd2, // internal port, suggested external port
670+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // suggested external IP
671+
}, 0
672+
},
673+
{
674+
250ms, TestOp::RECV, // 250ms delay before answer
675+
{
676+
0x02, 0x81, 0x00, 0x42, // version, opcode, result error
677+
0x00, 0x00, 0x01, 0xf4, // granted lifetime
678+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
679+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // nonce
680+
0x06, 0x00, 0x00, 0x00, // protocol (TCP), reserved
681+
0x04, 0xd2, 0x04, 0xd2, // internal port, assigned external port
682+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04, // assigned external IP
683+
}, 0
684+
},
685+
};
686+
CreateSock = [this, &script](int domain, int type, int protocol) {
687+
if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP) return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4, script);
688+
return std::unique_ptr<PCPTestSock>();
689+
};
690+
691+
auto res = PCPRequestPortMap(TEST_NONCE, default_gateway_ipv4, bind_any_ipv4, 1234, 1000, 1, 1000ms);
692+
693+
MappingError* err = std::get_if<MappingError>(&res);
694+
BOOST_REQUIRE(err);
695+
BOOST_CHECK_EQUAL(*err, MappingError::PROTOCOL_ERROR);
696+
}
697+
580698
BOOST_AUTO_TEST_SUITE_END()
581699

0 commit comments

Comments
 (0)