11#include <boost/test/unit_test.hpp>
16using namespace std::literals;
22 std::chrono::milliseconds
delay;
34 TestOp(std::chrono::milliseconds delay_in,
Op op_in,
const std::vector<uint8_t> &data_in,
int error_in):
47 const std::optional<CService> local_ipv4{
Lookup(
"192.168.0.6", 1,
false)};
48 const std::optional<CService> local_ipv6{
Lookup(
"2a10:1234:5678:9abc:def0:1234:5678:9abc", 1,
false)};
49 const std::optional<CService> gateway_ipv4{
Lookup(
"192.168.0.1", 1,
false)};
50 const std::optional<CService> gateway_ipv6{
Lookup(
"2a10:1234:5678:9abc:def0:0000:0000:0000", 1,
false)};
51 BOOST_REQUIRE(local_ipv4 && local_ipv6 && gateway_ipv4 && gateway_ipv6);
57 struct in_addr inaddr_any;
58 inaddr_any.s_addr = htonl(INADDR_ANY);
69 static constexpr PCPMappingNonce TEST_NONCE{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
100 assert(
false &&
"Move of Sock into PCPTestSock not allowed.");
104 ssize_t
Send(
const void*
data,
size_t len,
int)
const override {
106 std::span in_pkt = std::span(
static_cast<const uint8_t*
>(
data), len);
112 if (
CurOp().error)
return -1;
122 ssize_t
Recv(
void* buf,
size_t len,
int flags)
const override
127 if (
CurOp().error)
return -1;
129 const size_t consume_bytes{std::min(len, recv_pkt.size())};
130 std::memcpy(buf, recv_pkt.data(), consume_bytes);
131 if ((
flags & MSG_PEEK) == 0) {
134 return consume_bytes;
137 int Connect(
const sockaddr* sa, socklen_t sa_len)
const override {
152 int Bind(
const sockaddr* sa, socklen_t sa_len)
const override {
165 int Listen(
int)
const override {
return -1; }
167 std::unique_ptr<Sock>
Accept(sockaddr* addr, socklen_t* addr_len)
const override
172 int GetSockOpt(
int level,
int opt_name,
void* opt_val, socklen_t* opt_len)
const override
177 int SetSockOpt(
int,
int,
const void*, socklen_t)
const override {
return 0; }
189 bool Wait(std::chrono::milliseconds timeout,
191 Event* occurred =
nullptr)
const override
197 std::chrono::milliseconds delay = std::min(
m_time_left, timeout);
262 const std::vector<TestOp>
script{
272 0x00, 0x80, 0x00, 0x00,
273 0x66, 0xfd, 0xa1, 0xee,
274 0x01, 0x02, 0x03, 0x04,
280 0x00, 0x02, 0x00, 0x00,
281 0x04, 0xd2, 0x04, 0xd2,
282 0x00, 0x00, 0x03, 0xe8,
288 0x00, 0x82, 0x00, 0x00,
289 0x66, 0xfd, 0xa1, 0xee,
290 0x04, 0xd2, 0x04, 0xd2,
291 0x00, 0x00, 0x01, 0xf4,
296 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
297 return std::unique_ptr<PCPTestSock>();
303 BOOST_REQUIRE(mapping);
313 const std::vector<TestOp>
script{
317 0x02, 0x01, 0x00, 0x00,
318 0x00, 0x00, 0x03, 0xe8,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
320 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
321 0x06, 0x00, 0x00, 0x00,
322 0x04, 0xd2, 0x04, 0xd2,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
329 0x02, 0x81, 0x00, 0x00,
330 0x00, 0x00, 0x01, 0xf4,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
333 0x06, 0x00, 0x00, 0x00,
334 0x04, 0xd2, 0x04, 0xd2,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04,
340 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
341 return std::unique_ptr<PCPTestSock>();
347 BOOST_REQUIRE(mapping);
357 const std::vector<TestOp>
script{
361 0x02, 0x01, 0x00, 0x00,
362 0x00, 0x00, 0x03, 0xe8,
363 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
364 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
365 0x06, 0x00, 0x00, 0x00,
366 0x04, 0xd2, 0x04, 0xd2,
367 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
373 0x02, 0x81, 0x00, 0x00,
374 0x00, 0x00, 0x01, 0xf4,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
377 0x06, 0x00, 0x00, 0x00,
378 0x04, 0xd2, 0x04, 0xd2,
379 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
384 if (domain == AF_INET6 && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv6, default_gateway_ipv6,
script);
385 return std::unique_ptr<PCPTestSock>();
391 BOOST_REQUIRE(mapping);
401 const std::vector<TestOp>
script{};
403 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
404 return std::unique_ptr<PCPTestSock>();
421 const std::vector<TestOp>
script{
434 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
435 return std::unique_ptr<PCPTestSock>();
450 const std::vector<TestOp>
script{
454 0x02, 0x01, 0x00, 0x00,
455 0x00, 0x00, 0x03, 0xe8,
456 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
457 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
458 0x06, 0x00, 0x00, 0x00,
459 0x04, 0xd2, 0x04, 0xd2,
460 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
470 0x02, 0x01, 0x00, 0x00,
471 0x00, 0x00, 0x03, 0xe8,
472 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
473 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
474 0x06, 0x00, 0x00, 0x00,
475 0x04, 0xd2, 0x04, 0xd2,
476 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
482 0x02, 0x81, 0x00, 0x00,
483 0x00, 0x00, 0x01, 0xf4,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
486 0x06, 0x00, 0x00, 0x00,
487 0x04, 0xd2, 0x04, 0xd2,
488 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
493 if (domain == AF_INET6 && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv6, default_gateway_ipv6,
script);
494 return std::unique_ptr<PCPTestSock>();
508 const std::vector<TestOp>
script{
512 0x02, 0x01, 0x00, 0x00,
513 0x00, 0x00, 0x03, 0xe8,
514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
515 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
516 0x06, 0x00, 0x00, 0x00,
517 0x04, 0xd2, 0x04, 0xd2,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
524 0x02, 0x81, 0x00, 0x08,
525 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
528 0x06, 0x00, 0x00, 0x00,
529 0x04, 0xd2, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
536 return std::unique_ptr<PCPTestSock>();
549 const std::vector<TestOp>
script{
553 0x02, 0x01, 0x00, 0x00,
554 0x00, 0x00, 0x03, 0xe8,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
556 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
557 0x06, 0x00, 0x00, 0x00,
558 0x04, 0xd2, 0x04, 0xd2,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x81, 0x00, 0x01,
566 0x00, 0x00, 0x00, 0x00,
571 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
572 return std::unique_ptr<PCPTestSock>();
586 std::vector<TestOp>
script{
596 0x00, 0x80, 0x00, 0x42,
597 0x66, 0xfd, 0xa1, 0xee,
598 0x01, 0x02, 0x03, 0x04,
603 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
604 return std::unique_ptr<PCPTestSock>();
624 0x00, 0x80, 0x00, 0x00,
625 0x66, 0xfd, 0xa1, 0xee,
626 0x01, 0x02, 0x03, 0x04,
632 0x00, 0x02, 0x00, 0x00,
633 0x04, 0xd2, 0x04, 0xd2,
634 0x00, 0x00, 0x03, 0xe8,
640 0x00, 0x82, 0x00, 0x43,
641 0x66, 0xfd, 0xa1, 0xee,
642 0x04, 0xd2, 0x04, 0xd2,
643 0x00, 0x00, 0x01, 0xf4,
648 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
649 return std::unique_ptr<PCPTestSock>();
654 err = std::get_if<MappingError>(&res);
662 const std::vector<TestOp>
script{
666 0x02, 0x01, 0x00, 0x00,
667 0x00, 0x00, 0x03, 0xe8,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
669 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
670 0x06, 0x00, 0x00, 0x00,
671 0x04, 0xd2, 0x04, 0xd2,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
678 0x02, 0x81, 0x00, 0x42,
679 0x00, 0x00, 0x01, 0xf4,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
682 0x06, 0x00, 0x00, 0x00,
683 0x04, 0xd2, 0x04, 0xd2,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04,
689 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
690 return std::unique_ptr<PCPTestSock>();
A combination of a network address (CNetAddr) and a (TCP) port.
bool SetSockAddr(const struct sockaddr *paddr, socklen_t addrlen)
Set CService from a network sockaddr.
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
std::string ToStringAddrPort() const
A helper class for interruptible sleeps.
Simple scripted UDP server emulation for testing.
void ElapseTime(std::chrono::milliseconds duration) const
int GetSockName(sockaddr *name, socklen_t *name_len) const override
getsockname(2) wrapper.
int SetSockOpt(int, int, const void *, socklen_t) const override
setsockopt(2) wrapper.
int Bind(const sockaddr *sa, socklen_t sa_len) const override
bind(2) wrapper.
ssize_t Recv(void *buf, size_t len, int flags) const override
recv(2) wrapper.
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock &events_per_sock) const override
Same as Wait(), but wait on many sockets within the same timeout.
int Listen(int) const override
listen(2) wrapper.
PCPTestSock & operator=(Sock &&other) override
Move assignment operator, grab the socket from another object and close ours (if set).
bool SetNonBlocking() const override
Set the non-blocking option on the socket.
int GetSockOpt(int level, int opt_name, void *opt_val, socklen_t *opt_len) const override
getsockopt(2) wrapper.
std::chrono::milliseconds m_time
PCPTestSock(const CNetAddr &local_ip, const CNetAddr &gateway_ip, const std::vector< TestOp > &script)
bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const override
Wait for readiness for input (recv) or output (send).
const std::vector< TestOp > m_script
int Connect(const sockaddr *sa, socklen_t sa_len) const override
connect(2) wrapper.
bool AtEndOfScript() const
std::chrono::milliseconds m_time_left
bool IsSelectable() const override
Check if the underlying socket can be used for select(2) (or the Wait() method).
ssize_t Send(const void *data, size_t len, int) const override
send(2) wrapper.
std::unique_ptr< Sock > Accept(sockaddr *addr, socklen_t *addr_len) const override
accept(2) wrapper.
const TestOp & CurOp() const
bool IsConnected(std::string &) const override
Check if still connected.
Save the value of CreateSock and restore when the test ends.
CNetAddr default_gateway_ipv4
CNetAddr default_local_ipv4
CNetAddr default_gateway_ipv6
static constexpr PCPMappingNonce TEST_NONCE
CNetAddr default_local_ipv6
const decltype(CreateSock) m_create_sock_orig
PCPTestingSetup(const ChainType chainType=ChainType::MAIN, TestOpts opts={})
RAII helper class that manages a socket and closes it automatically when it goes out of scope.
static constexpr Event RECV
If passed to Wait(), then it will wait for readiness to read from the socket.
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
std::variant< MappingResult, MappingError > NATPMPRequestPortMap(const CNetAddr &gateway, uint16_t port, uint32_t lifetime, CThreadInterrupt &interrupt, int num_tries, std::chrono::milliseconds timeout_per_try)
Try to open a port using RFC 6886 NAT-PMP.
std::variant< MappingResult, MappingError > PCPRequestPortMap(const PCPMappingNonce &nonce, const CNetAddr &gateway, const CNetAddr &bind, uint16_t port, uint32_t lifetime, CThreadInterrupt &interrupt, int num_tries, std::chrono::milliseconds timeout_per_try)
Try to open a port using RFC 6887 Port Control Protocol (PCP).
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
std::vector< CService > Lookup(const std::string &name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
std::function< std::unique_ptr< Sock >(int, int, int)> CreateSock
Socket factory.
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
std::array< uint8_t, PCP_MAP_NONCE_SIZE > PCPMappingNonce
PCP mapping nonce. Arbitrary data chosen by the client to identify a mapping.
MappingError
Unsuccessful response to a port mapping.
@ PROTOCOL_ERROR
Any kind of protocol-level error, except unsupported version or no resources.
@ NO_RESOURCES
No resources available (port probably already mapped).
@ UNSUPP_VERSION
Unsupported protocol version.
@ NETWORK_ERROR
Any kind of network-level error.
static CThreadInterrupt g_interrupt
BOOST_AUTO_TEST_CASE(natpmp_ipv4)
Successful response to a port mapping.
CService external
External host:port.
uint32_t lifetime
Granted lifetime of binding (seconds).
CService internal
Internal host:port.
uint8_t version
Protocol version, one of NATPMP_VERSION or PCP_VERSION.
static void SetMockTime(mock_time_point::duration mock_time_in)
Set mock time for testing.
static constexpr mock_time_point::duration INITIAL_MOCK_TIME
static void ClearMockTime()
Clear mock time, go back to system steady clock.
UDP test server operation.
std::vector< uint8_t > data
TestOp(std::chrono::milliseconds delay_in, Op op_in, const std::vector< uint8_t > &data_in, int error_in)
std::chrono::milliseconds delay
#define ASSERT_DEBUG_LOG(message)