LCOV - code coverage report
Current view: top level - src/common - pcp.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 3 3
Test Date: 2026-08-09 07:13:22 Functions: 100.0 % 1 1

            Line data    Source code
       1              : // Copyright (c) 2024-present The Bitcoin Core developers
       2              : // Distributed under the MIT software license, see the accompanying
       3              : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       4              : 
       5              : #ifndef BITCOIN_COMMON_PCP_H
       6              : #define BITCOIN_COMMON_PCP_H
       7              : 
       8              : #include <netaddress.h>
       9              : #include <util/time.h>
      10              : 
      11              : #include <array>
      12              : #include <cstddef>
      13              : #include <cstdint>
      14              : #include <string>
      15              : #include <variant>
      16              : 
      17              : class CThreadInterrupt;
      18              : 
      19              : // RFC6886 NAT-PMP and RFC6887 Port Control Protocol (PCP) implementation.
      20              : // NAT-PMP and PCP use network byte order (big-endian).
      21              : 
      22              : //! Mapping nonce size in bytes (see RFC6887 section 11.1).
      23              : constexpr size_t PCP_MAP_NONCE_SIZE = 12;
      24              : 
      25              : //! PCP mapping nonce. Arbitrary data chosen by the client to identify a mapping.
      26              : typedef std::array<uint8_t, PCP_MAP_NONCE_SIZE> PCPMappingNonce;
      27              : 
      28              : //! Unsuccessful response to a port mapping.
      29              : enum class MappingError {
      30              :     NETWORK_ERROR,  ///< Any kind of network-level error.
      31              :     PROTOCOL_ERROR, ///< Any kind of protocol-level error, except unsupported version or no resources.
      32              :     UNSUPP_VERSION, ///< Unsupported protocol version.
      33              :     NO_RESOURCES,   ///< No resources available (port probably already mapped).
      34              : };
      35              : 
      36              : //! Successful response to a port mapping.
      37            8 : struct MappingResult {
      38            4 :     MappingResult(uint8_t version, const CService &internal_in, const CService &external_in, uint32_t lifetime_in):
      39            4 :         version(version), internal(internal_in), external(external_in), lifetime(lifetime_in) {}
      40              :     //! Protocol version, one of NATPMP_VERSION or PCP_VERSION.
      41              :     uint8_t version;
      42              :     //! Internal host:port.
      43              :     CService internal;
      44              :     //! External host:port.
      45              :     CService external;
      46              :     //! Granted lifetime of binding (seconds).
      47              :     uint32_t lifetime;
      48              : 
      49              :     //! Format mapping as string for logging.
      50              :     std::string ToString() const;
      51              : };
      52              : 
      53              : //! Try to open a port using RFC 6886 NAT-PMP. IPv4 only.
      54              : //!
      55              : //! * gateway: Destination address for PCP requests (usually the default gateway).
      56              : //! * port: Internal port, and desired external port.
      57              : //! * lifetime: Requested lifetime in seconds for mapping. The server may assign as shorter or longer lifetime. A lifetime of 0 deletes the mapping.
      58              : //! * num_tries: Number of tries in case of no response.
      59              : //!
      60              : //! Returns the external_ip:external_port of the mapping if successful, otherwise a MappingError.
      61              : std::variant<MappingResult, MappingError> NATPMPRequestPortMap(const CNetAddr &gateway, uint16_t port, uint32_t lifetime, CThreadInterrupt& interrupt, int num_tries = 3, std::chrono::milliseconds timeout_per_try = std::chrono::milliseconds(1000));
      62              : 
      63              : //! Try to open a port using RFC 6887 Port Control Protocol (PCP). Handles IPv4 and IPv6.
      64              : //!
      65              : //! * nonce: Mapping cookie. Keep this the same over renewals.
      66              : //! * gateway: Destination address for PCP requests (usually the default gateway).
      67              : //! * bind: Specific local bind address for IPv6 pinholing. Set this as INADDR_ANY for IPv4.
      68              : //! * port: Internal port, and desired external port.
      69              : //! * lifetime: Requested lifetime in seconds for mapping. The server may assign as shorter or longer lifetime. A lifetime of 0 deletes the mapping.
      70              : //! * num_tries: Number of tries in case of no response.
      71              : //!
      72              : //! Returns the external_ip:external_port of the mapping if successful, otherwise a MappingError.
      73              : 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 = 3, std::chrono::milliseconds timeout_per_try = std::chrono::milliseconds(1000));
      74              : 
      75              : #endif // BITCOIN_COMMON_PCP_H
        

Generated by: LCOV version 2.0-1