Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501LogWarning("pcp: Response to wrong command\n");502return false; // Wasn't response to what we expected, try receiving next packet.503}504// Handle MAP opcode response. See RFC6887 Figure 10.505// Check that returned mapping nonce matches our request.506if (!std::ranges::equal(response.subspan(PCP_HDR_SIZE + PCP_MAP_NONCE_OFS, PCP_MAP_NONCE_SIZE), nonce)) {507LogWarning("pcp: Mapping nonce mismatch\n");508return false; // Wasn't response to what we expected, try receiving next packet.509}510uint8_t protocol = response[PCP_HDR_SIZE + 12];511uint16_t internal_port = ReadBE16(response.data() + PCP_HDR_SIZE + 16);512if (protocol != PCP_PROTOCOL_TCP || internal_port != port) {513LogWarning("pcp: Response protocol or port doesn't match request\n");514return false; // Wasn't response to what we expected, try receiving next packet.515}516return true;517},518interrupt);520if (!recv_res) {521return MappingError::NETWORK_ERROR;522}523if (is_natpmp) {524return MappingError::UNSUPP_VERSION;525}527const std::span<const uint8_t> response = *recv_res;528// If we get here, we got a valid MAP response to our request.529// Check to see if we got the result we expected.530Assume(response.size() >= (PCP_HDR_SIZE + PCP_MAP_SIZE));531uint8_t result_code = response[PCP_RESPONSE_HDR_RESULT_OFS];532uint32_t lifetime_ret = ReadBE32(response.data() + PCP_HDR_LIFETIME_OFS);533uint16_t external_port = ReadBE16(response.data() + PCP_HDR_SIZE + PCP_MAP_EXTERNAL_PORT_OFS);534CNetAddr external_addr{PCPUnwrapAddress(response.subspan(PCP_HDR_SIZE + PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE))};535if (result_code != PCP_RESULT_SUCCESS) {536if (result_code == PCP_RESULT_NOT_AUTHORIZED) {537static std::atomic<bool> warned{false};538if (!warned.exchange(true)) {539LogWarning("pcp: Mapping failed with result %s\n", PCPResultString(result_code));540} else {541LogDebug(BCLog::NET, "pcp: Mapping failed with result %s\n", PCPResultString(result_code));542}543} else {544LogWarning("pcp: Mapping failed with result %s\n", PCPResultString(result_code));545}546if (result_code == PCP_RESULT_NO_RESOURCES) {547return MappingError::NO_RESOURCES;548}549return MappingError::PROTOCOL_ERROR;550}552return MappingResult(PCP_VERSION, CService(internal, port), CService(external_addr, external_port), lifetime_ret);553}555std::string MappingResult::ToString() const556{557Assume(version == NATPMP_VERSION || version == PCP_VERSION);558return strprintf("%s:%s -> %s (for %ds)",559version == NATPMP_VERSION ? "natpmp" : "pcp",560external.ToStringAddrPort(),561internal.ToStringAddrPort(),562lifetime563);564}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.