12#include <boost/test/unit_test.hpp>
17using namespace std::literals;
23 std::chrono::milliseconds
delay;
35 TestOp(std::chrono::milliseconds delay_in,
Op op_in,
const std::vector<uint8_t> &data_in,
int error_in):
48 const std::optional<CService> local_ipv4{
Lookup(
"192.168.0.6", 1,
false)};
49 const std::optional<CService> local_ipv6{
Lookup(
"2a10:1234:5678:9abc:def0:1234:5678:9abc", 1,
false)};
50 const std::optional<CService> gateway_ipv4{
Lookup(
"192.168.0.1", 1,
false)};
51 const std::optional<CService> gateway_ipv6{
Lookup(
"2a10:1234:5678:9abc:def0:0000:0000:0000", 1,
false)};
52 BOOST_REQUIRE(local_ipv4);
53 BOOST_REQUIRE(local_ipv6);
54 BOOST_REQUIRE(gateway_ipv4);
55 BOOST_REQUIRE(gateway_ipv6);
61 struct in_addr inaddr_any;
62 inaddr_any.s_addr = htonl(INADDR_ANY);
73 static constexpr PCPMappingNonce TEST_NONCE{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
103 assert(
false &&
"Move of Sock into PCPTestSock not allowed.");
107 ssize_t
Send(
const void*
data,
size_t len,
int)
const override {
109 std::span in_pkt = std::span(
static_cast<const uint8_t*
>(
data), len);
115 if (
CurOp().error)
return -1;
125 ssize_t
Recv(
void* buf,
size_t len,
int flags)
const override
130 if (
CurOp().error)
return -1;
132 const size_t consume_bytes{std::min(len, recv_pkt.size())};
133 std::memcpy(buf, recv_pkt.data(), consume_bytes);
134 if ((
flags & MSG_PEEK) == 0) {
137 return consume_bytes;
140 int Connect(
const sockaddr* sa, socklen_t sa_len)
const override {
155 int Bind(
const sockaddr* sa, socklen_t sa_len)
const override {
168 int Listen(
int)
const override {
return -1; }
170 std::unique_ptr<Sock>
Accept(sockaddr* addr, socklen_t* addr_len)
const override
175 int GetSockOpt(
int level,
int opt_name,
void* opt_val, socklen_t* opt_len)
const override
180 int SetSockOpt(
int,
int,
const void*, socklen_t)
const override {
return 0; }
192 bool Wait(std::chrono::milliseconds timeout,
194 Event* occurred =
nullptr)
const override
200 std::chrono::milliseconds delay = std::min(
m_time_left, timeout);
259 const std::vector<TestOp>
script{
269 0x00, 0x80, 0x00, 0x00,
270 0x66, 0xfd, 0xa1, 0xee,
271 0x01, 0x02, 0x03, 0x04,
277 0x00, 0x02, 0x00, 0x00,
278 0x04, 0xd2, 0x04, 0xd2,
279 0x00, 0x00, 0x03, 0xe8,
285 0x00, 0x82, 0x00, 0x00,
286 0x66, 0xfd, 0xa1, 0xee,
287 0x04, 0xd2, 0x04, 0xd2,
288 0x00, 0x00, 0x01, 0xf4,
293 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
294 return std::unique_ptr<PCPTestSock>();
300 BOOST_REQUIRE(mapping);
310 const std::vector<TestOp>
script{
314 0x02, 0x01, 0x00, 0x00,
315 0x00, 0x00, 0x03, 0xe8,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
317 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
318 0x06, 0x00, 0x00, 0x00,
319 0x04, 0xd2, 0x04, 0xd2,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
326 0x02, 0x81, 0x00, 0x00,
327 0x00, 0x00, 0x01, 0xf4,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
330 0x06, 0x00, 0x00, 0x00,
331 0x04, 0xd2, 0x04, 0xd2,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04,
337 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
338 return std::unique_ptr<PCPTestSock>();
344 BOOST_REQUIRE(mapping);
354 const std::vector<TestOp>
script{
358 0x02, 0x01, 0x00, 0x00,
359 0x00, 0x00, 0x03, 0xe8,
360 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
361 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
362 0x06, 0x00, 0x00, 0x00,
363 0x04, 0xd2, 0x04, 0xd2,
364 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
370 0x02, 0x81, 0x00, 0x00,
371 0x00, 0x00, 0x01, 0xf4,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
374 0x06, 0x00, 0x00, 0x00,
375 0x04, 0xd2, 0x04, 0xd2,
376 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
381 if (domain == AF_INET6 && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv6, default_gateway_ipv6,
script);
382 return std::unique_ptr<PCPTestSock>();
388 BOOST_REQUIRE(mapping);
398 const std::vector<TestOp>
script{};
400 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
401 return std::unique_ptr<PCPTestSock>();
418 const std::vector<TestOp>
script{
431 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
432 return std::unique_ptr<PCPTestSock>();
447 const std::vector<TestOp>
script{
451 0x02, 0x01, 0x00, 0x00,
452 0x00, 0x00, 0x03, 0xe8,
453 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
454 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
455 0x06, 0x00, 0x00, 0x00,
456 0x04, 0xd2, 0x04, 0xd2,
457 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
467 0x02, 0x01, 0x00, 0x00,
468 0x00, 0x00, 0x03, 0xe8,
469 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
470 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
471 0x06, 0x00, 0x00, 0x00,
472 0x04, 0xd2, 0x04, 0xd2,
473 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
479 0x02, 0x81, 0x00, 0x00,
480 0x00, 0x00, 0x01, 0xf4,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
483 0x06, 0x00, 0x00, 0x00,
484 0x04, 0xd2, 0x04, 0xd2,
485 0x2a, 0x10, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
490 if (domain == AF_INET6 && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv6, default_gateway_ipv6,
script);
491 return std::unique_ptr<PCPTestSock>();
505 const std::vector<TestOp>
script{
509 0x02, 0x01, 0x00, 0x00,
510 0x00, 0x00, 0x03, 0xe8,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
512 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
513 0x06, 0x00, 0x00, 0x00,
514 0x04, 0xd2, 0x04, 0xd2,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
521 0x02, 0x81, 0x00, 0x08,
522 0x00, 0x00, 0x00, 0x00,
523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
525 0x06, 0x00, 0x00, 0x00,
526 0x04, 0xd2, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
533 return std::unique_ptr<PCPTestSock>();
546 const std::vector<TestOp>
script{
550 0x02, 0x01, 0x00, 0x00,
551 0x00, 0x00, 0x03, 0xe8,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
553 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
554 0x06, 0x00, 0x00, 0x00,
555 0x04, 0xd2, 0x04, 0xd2,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x81, 0x00, 0x01,
563 0x00, 0x00, 0x00, 0x00,
568 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
569 return std::unique_ptr<PCPTestSock>();
583 std::vector<TestOp>
script{
593 0x00, 0x80, 0x00, 0x42,
594 0x66, 0xfd, 0xa1, 0xee,
595 0x01, 0x02, 0x03, 0x04,
600 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
601 return std::unique_ptr<PCPTestSock>();
621 0x00, 0x80, 0x00, 0x00,
622 0x66, 0xfd, 0xa1, 0xee,
623 0x01, 0x02, 0x03, 0x04,
629 0x00, 0x02, 0x00, 0x00,
630 0x04, 0xd2, 0x04, 0xd2,
631 0x00, 0x00, 0x03, 0xe8,
637 0x00, 0x82, 0x00, 0x43,
638 0x66, 0xfd, 0xa1, 0xee,
639 0x04, 0xd2, 0x04, 0xd2,
640 0x00, 0x00, 0x01, 0xf4,
645 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
646 return std::unique_ptr<PCPTestSock>();
651 err = std::get_if<MappingError>(&res);
659 const std::vector<TestOp>
script{
663 0x02, 0x01, 0x00, 0x00,
664 0x00, 0x00, 0x03, 0xe8,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x06,
666 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
667 0x06, 0x00, 0x00, 0x00,
668 0x04, 0xd2, 0x04, 0xd2,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
675 0x02, 0x81, 0x00, 0x42,
676 0x00, 0x00, 0x01, 0xf4,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
679 0x06, 0x00, 0x00, 0x00,
680 0x04, 0xd2, 0x04, 0xd2,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04,
686 if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP)
return std::make_unique<PCPTestSock>(default_local_ipv4, default_gateway_ipv4,
script);
687 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.
Helper to initialize the global MockableSteadyClock, let a duration elapse, and reset it after use in...
Simple scripted UDP server emulation for testing.
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.
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 RecvEvent
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().
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
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()
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
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(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 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)