17#include <util/threadinterrupt.h>
103 {1,
"UNSUPP_VERSION"},
104 {2,
"NOT_AUTHORIZED"},
105 {3,
"NETWORK_FAILURE"},
107 {5,
"UNSUPP_OPCODE"},
168 {1,
"UNSUPP_VERSION"},
169 {2,
"NOT_AUTHORIZED"},
170 {3,
"MALFORMED_REQUEST"},
171 {4,
"UNSUPP_OPCODE"},
172 {5,
"UNSUPP_OPTION"},
173 {6,
"MALFORMED_OPTION"},
174 {7,
"NETWORK_FAILURE"},
176 {9,
"UNSUPP_PROTOCOL"},
177 {10,
"USER_EX_QUOTA"},
178 {11,
"CANNOT_PROVIDE_EXTERNAL"},
179 {12,
"ADDRESS_MISMATCH"},
180 {13,
"EXCESSIVE_REMOTE_PEER"},
208 }
else if (addr.
IsIPv6()) {
236 std::function<
bool(std::span<const uint8_t>)>
check_packet,
239 using namespace std::chrono;
249 if (sock.
Send(request.data(), request.size(), 0) !=
static_cast<ssize_t>(request.size())) {
258 if (interrupt)
return std::nullopt;
330 [&](
const std::span<const uint8_t>
response) ->
bool {
332 LogWarning(
"natpmp: Response too small\n");
336 LogWarning(
"natpmp: Response to wrong command\n");
368 [&](
const std::span<const uint8_t>
response) ->
bool {
370 LogWarning(
"natpmp: Response too small\n");
374 LogWarning(
"natpmp: Response to wrong command\n");
379 LogWarning(
"natpmp: Response port doesn't match request\n");
484 [&](
const std::span<const uint8_t>
response) ->
bool {
491 LogWarning(
"pcp: Response too small\n");
495 LogWarning(
"pcp: Response to wrong command\n");
507 LogWarning(
"pcp: Response protocol or port doesn't match request\n");
547 return strprintf(
"%s:%s -> %s (for %ds)",
#define Assume(val)
Assume is the identity function.
std::string ToStringAddr() const
bool GetIn6Addr(struct in6_addr *pipv6Addr) const
Try to get our IPv6 (or CJDNS) address.
bool GetInAddr(struct in_addr *pipv4Addr) const
Try to get our IPv4 address.
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.
std::string ToStringAddrPort() const
A helper class for interruptible sleeps.
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.
virtual ssize_t Send(const void *data, size_t len, int flags) const
send(2) wrapper.
virtual int Bind(const sockaddr *addr, socklen_t addr_len) const
bind(2) wrapper.
virtual bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const
Wait for readiness for input (recv) or output (send).
virtual int GetSockName(sockaddr *name, socklen_t *name_len) const
getsockname(2) wrapper.
virtual int Connect(const sockaddr *addr, socklen_t addr_len) const
connect(2) wrapper.
virtual ssize_t Recv(void *buf, size_t len, int flags) const
recv(2) wrapper.
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).
#define WSAGetLastError()
void WriteBE32(B *ptr, uint32_t x)
void WriteBE16(B *ptr, uint16_t x)
uint16_t ReadBE16(const B *ptr)
uint32_t ReadBE32(const B *ptr)
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
#define LogWarnThenDebug(category,...)
#define LogDebug(category,...)
bool HasPrefix(const T1 &obj, const std::array< uint8_t, PREFIX_LEN > &prefix)
Check whether a container begins with the given prefix.
constexpr size_t ADDR_IPV4_SIZE
Size of IPv4 address (in bytes).
constexpr size_t ADDR_IPV6_SIZE
Size of IPv6 address (in bytes).
constexpr std::array< uint8_t, 12 > IPV4_IN_IPV6_PREFIX
Prefix of an IPv6 address when it contains an embedded IPv4 address.
std::function< std::unique_ptr< Sock >(int, int, int)> CreateSock
Socket factory.
std::array< uint8_t, PCP_MAP_NONCE_SIZE > PCPMappingNonce
PCP mapping nonce. Arbitrary data chosen by the client to identify a mapping.
constexpr size_t PCP_MAP_NONCE_SIZE
Mapping nonce size in bytes (see RFC6887 section 11.1).
@ 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.
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Successful response to a port mapping.
CService external
External host:port.
uint32_t lifetime
Granted lifetime of binding (seconds).
CService internal
Internal host:port.
std::string ToString() const
Format mapping as string for logging.
uint8_t version
Protocol version, one of NATPMP_VERSION or PCP_VERSION.
static time_point now() noexcept
Return current system time or mocked time, if set.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.