8. General PCP Operation
PCP messages MUST be sent over UDP [RFC0768]. Every PCP request generates at least one response, so PCP does not need to run over a reliable transport protocol. When receiving multiple identical requests, the PCP server will generally generate identical responses -- barring cases where the PCP server's state changes between those requests due to other activity. As an example of how such a state change could happen, a request could be received while the PCP-controlled device has no mappings
available, and the PCP server will generate an error response. If mappings become available and then another copy of that same request arrives (perhaps duplicated in transit in the network), the PCP server will allocate a mapping and generate a non-error response. A PCP client MUST handle such updated responses for any request it sends, most notably to support rapid recovery (Section 14). Also see the Protocol Design Note (Section 6).8.1. General PCP Client: Generating a Request
This section details operation specific to a PCP client, for any Opcode. Procedures specific to the MAP Opcode are described in Section 11, and procedures specific to the PEER Opcode are described in Section 12. Prior to sending its first PCP message, the PCP client determines which server to use. The PCP client performs the following steps to determine its PCP server: 1. if a PCP server is configured (e.g., in a configuration file or via DHCP), that single configuration source is used as the list of PCP server(s), else 2. the default router list (for IPv4 and IPv6) is used as the list of PCP server(s). Thus, if a PCP client has both an IPv4 and IPv6 address, it will have an IPv4 PCP server (its IPv4 default router) for its IPv4 mappings, and an IPv6 PCP server (its IPv6 default router) for its IPv6 mappings. For the purposes of this document, only a single PCP server address is supported. Should future specifications define configuration methods that provide a longer list of PCP server addresses, those specifications will define how clients select one or more addresses from that list. With that PCP server address, the PCP client formulates its PCP request. The PCP request contains a PCP common header, PCP Opcode and payload, and (possibly) options. As with all UDP client software on any operating system, when several independent PCP clients exist on the same host, each uses a distinct source port number to disambiguate their requests and replies. The PCP client's source port SHOULD be randomly generated [RFC6056]. The PCP client MUST include the source IP address of the PCP message in the PCP request. This is typically its own IP address; see Section 16.4 for how this can be coded. This is used to detect an unexpected NAT on the path between the PCP client and the PCP-controlled NAT or firewall device, to avoid wasting resources on
the PCP-controlled NAT creating pointless non-functional mappings. When such an intervening non-PCP-aware inner NAT is detected, mappings must first be created by some other means in the inner NAT, before mappings can be usefully created in the outer PCP-controlled NAT. Having created mappings in the inner NAT by some other means, the PCP client should then use the inner NAT's external address as the client IP address, to signal to the outer PCP-controlled NAT that the client is aware of the inner NAT, and has taken steps to create mappings in it by some other means, so that mappings created in the outer NAT will not be a pointless waste of resources.8.1.1. PCP Client Retransmission
PCP clients are responsible for reliable delivery of PCP request messages. If a PCP client fails to receive an expected response from a server, the client must retransmit its message. The retransmissions MUST use the same Mapping Nonce value (see Sections 11.1 and 12.1). The client begins the message exchange by transmitting a message to the server. The message exchange continues for as long as the client wishes to maintain the mapping, and terminates when the PCP client is no longer interested in the PCP transaction (e.g., the application that requested the mapping is no longer interested in the mapping) or (optionally) when the message exchange is considered to have failed according to the retransmission mechanism described below. The client retransmission behavior is controlled and described by the following variables: RT: Retransmission timeout, calculated as described below IRT: Initial retransmission time, SHOULD be 3 seconds MRC: Maximum retransmission count, SHOULD be 0 (0 indicates no maximum) MRT: Maximum retransmission time, SHOULD be 1024 seconds MRD: Maximum retransmission duration, SHOULD be 0 (0 indicates no maximum) RAND: Randomization factor, calculated as described below With each message transmission or retransmission, the client sets RT according to the rules given below. If RT expires before a response is received, the client retransmits the request and computes a new RT.
Each of the computations of a new RT include a new randomization factor (RAND), which is a random number chosen with a uniform distribution between -0.1 and +0.1. The randomization factor is included to minimize synchronization of messages transmitted by PCP clients. The algorithm for choosing a random number does not need to be cryptographically sound. The algorithm SHOULD produce a different sequence of random numbers from each invocation of the PCP client. The RT value is initialized based on IRT: RT = (1 + RAND) * IRT RT for each subsequent message transmission is based on the previous value of RT, subject to the upper bound on the value of RT specified by MRT. If MRT has a value of 0, there is no upper limit on the value of RT, and MRT is treated as "infinity". The new value of RT is calculated as shown below, where RTprev is the current value of RT: RT = (1 + RAND) * MIN (2 * RTprev, MRT) MRC specifies an upper bound on the number of times a client may retransmit a message. Unless MRC is zero, the message exchange fails once the client has transmitted the message MRC times. MRD specifies an upper bound on the length of time a client may retransmit a message. Unless MRD is zero, the message exchange fails once MRD seconds have elapsed since the client first transmitted the message. If both MRC and MRD are non-zero, the message exchange fails whenever either of the conditions specified in the previous two paragraphs are met. If both MRC and MRD are zero, the client continues to transmit the message until it receives a response or the client no longer wants a mapping. Once a PCP client has successfully received a response from a PCP server on that interface, it resets RT to a value randomly selected in the range 1/2 to 5/8 of the mapping lifetime, as described in Section 11.2.1, "Renewing a Mapping", and sends subsequent PCP requests for that mapping to that same server. Note: If the server's state changes between retransmissions and the server's response is delayed or lost, the state in the PCP client and server may not be synchronized. This is not unique to PCP, but also occurs with other network protocols (e.g., TCP). In the unlikely event that such de-synchronization occurs, PCP heals itself after lifetime seconds.
8.2. General PCP Server: Processing a Request
This section details operation specific to a PCP server. Processing SHOULD be performed in the order of the following paragraphs. A PCP server MUST only accept normal (non-THIRD_PARTY) PCP requests from a client on the same interface from which it would normally receive packets from that client, and it MUST silently ignore PCP requests arriving on any other interface. For example, a residential NAT gateway accepts PCP requests only when they arrive on its (LAN) interface connecting to the internal network, and silently ignores any PCP requests arriving on its external (WAN) interface. A PCP server that supports THIRD_PARTY requests MAY be configured to accept THIRD_PARTY requests on other configured interfaces (see Section 13.1 for details on the THIRD_PARTY Option). Upon receiving a request, the PCP server parses and validates it. A valid request contains a valid PCP common header, one valid PCP Opcode, and zero or more options (which the server might or might not comprehend). If an error is encountered during processing, the server generates an error response that is sent back to the PCP client. Processing of an Opcode and its options is specific to each Opcode. Error responses have the same packet layout as success responses, with certain fields from the request copied into the response, and other fields assigned by the PCP server set as indicated in Figure 3. Copying request fields into the response is important because this is what enables a client to identify to which request a given response pertains. For Opcodes that are understood by the PCP server, it follows the requirements of that Opcode to copy the appropriate fields. For Opcodes that are not understood by the PCP server, it simply generates the UNSUPP_OPCODE response and copies fields from the PCP header and copies the rest of the PCP payload as is (without attempting to interpret it). All responses (both error and success) contain the same Opcode as the request, but with the "R" bit set. Any error response has a non-zero result code, and is created by: o Copying the entire UDP payload, or 1100 octets, whichever is less, and zero-padding the response to a multiple of 4 octets if necessary o Setting the R bit o Setting the result code o Setting the Lifetime, Epoch Time, and Reserved fields
o Updating other fields in the response, as indicated by 'set by the server' in the PCP response field description A success response has a zero result code, and is created by: o Copying the first 4 octets of request packet header o Setting the R bit o Setting the result code to zero o Setting the Lifetime, Epoch Time, and Reserved fields o Possibly setting Opcode-specific response data if appropriate o Adding any processed options to the response message If the received PCP request message is less than 2 octets long, it is silently dropped. If the R bit is set, the message is silently dropped. If the first octet (version) is a version that is not supported, a response is generated with the UNSUPP_VERSION result code, and the Version Negotiation steps detailed in Section 9 are followed. Otherwise, if the version is supported but the received message is shorter than 24 octets, the message is silently dropped. If the server is overloaded by requests (from a particular client or from all clients), it MAY simply silently discard requests, as the requests will be retried by PCP clients, or it MAY generate the NO_RESOURCES error response. If the length of the message exceeds 1100 octets, is not a multiple of 4 octets, or is too short for the Opcode in question, it is invalid and a MALFORMED_REQUEST response is generated, and the response message is truncated to 1100 octets. The PCP server compares the source IP address (from the received IP header) with the field PCP Client IP Address. If they do not match, the error ADDRESS_MISMATCH MUST be returned. This is done to detect and prevent accidental use of PCP where a non-PCP-aware NAT exists between the PCP client and PCP server. If the PCP client wants such a mapping, it needs to ensure that the PCP field matches its apparent IP address from the perspective of the PCP server.8.3. General PCP Client: Processing a Response
The PCP client receives the response and verifies that the source IP address and port belong to the PCP server of a previously sent PCP request. If not, the response is silently dropped.
If the received PCP response message is less than 4 octets long, it is silently dropped. If the R bit is clear, the message is silently dropped. If the error code is UNSUPP_VERSION, Version Negotiation processing continues as described in Section 9. Responses shorter than 24 octets, longer than 1100 octets, or not a multiple of 4 octets are invalid and ignored. The PCP client then validates that the Opcode matches a previous PCP request. If the response does not match a previous PCP request, the response is ignored. The response is further matched by comparing fields in the response Opcode-specific data to fields in the request Opcode-specific data, as described by the processing for that Opcode. If that fails, the response is ignored. After these matches are successful, the PCP client checks the Epoch Time field (see Section 8.5) to determine if it needs to restore its state to the PCP server. A PCP client SHOULD be prepared to receive multiple responses from the PCP server at any time after a single request is sent. This allows the PCP server to inform the client of mapping changes such as an update or deletion. For example, a PCP server might send a SUCCESS response and, after a configuration change on the PCP server, later send a NOT_AUTHORIZED response. A PCP client MUST be prepared to receive responses for requests it never sent (which could have been sent by a previous PCP instance on this same host, or by a previous host that used the same client IP address, or by a malicious attacker) by simply ignoring those unexpected messages. If the error ADDRESS_MISMATCH is received, it indicates the presence of a NAT between the PCP client and PCP server. Procedures to resolve this problem are beyond the scope of this document. For both success and error responses, a Lifetime value is returned. The lifetime indicates how long this response should be considered valid by the client (i.e for success results, how long the mapping will last, and for failure results how long the same failure condition should be expected to persist). The PCP client SHOULD impose an upper limit on this returned value (to protect against absurdly large values, e.g., 5 years), detailed in Section 15, "Mapping Lifetime and Deletion". If the result code is 0 (SUCCESS), the request succeeded.
If the result code is not 0, the request failed, and the PCP client SHOULD NOT resend the same request for the indicated lifetime of the error (as limited by the sanity checking detailed in Section 15). If the PCP client has discovered a new PCP server (e.g., connected to a new network), the PCP client MAY immediately begin communicating with this PCP server, without regard to hold times from communicating with a previous PCP server.8.4. Multi-Interface Issues
Hosts that desire a PCP mapping might be multi-interfaced (i.e., own several logical/physical interfaces). Indeed, a host can be configured with several IPv4 addresses (e.g., WiFi and Ethernet) or dual-stacked. These IP addresses may have distinct reachability scopes (e.g., if IPv6, they might have global reachability scope as is the case for a Global Unicast Address (GUA) [RFC3587] or limited scope as is the case for a Unique Local Address (ULA) [RFC4193]). IPv6 addresses with global reachability (e.g., GUAs) SHOULD be used as the source address when generating a PCP request. IPv6 addresses without global reachability (e.g., ULAs) SHOULD NOT be used as the source interface when generating a PCP request. If IPv6 privacy addresses [RFC4941] are used for PCP mappings, a new PCP request will need to be issued whenever the IPv6 privacy address is changed. This PCP request SHOULD be sent from the IPv6 privacy address itself. It is RECOMMENDED that the client delete its mappings to the previous privacy address after it no longer needs those old mappings. Due to the ubiquity of IPv4 NAT, IPv4 addresses with limited scope (e.g., private addresses [RFC1918]) MAY be used as the source interface when generating a PCP request.8.5. Epoch
Every PCP response sent by the PCP server includes an Epoch Time field. This time field increments by one every second. Anomalies in the received Epoch Time value provide a hint to PCP clients that a PCP server state loss may have occurred. Clients respond to such state loss hints by promptly renewing their mappings, so as to quickly restore any lost state at the PCP server. If the PCP server resets or loses the state of its explicit dynamic mappings (that is, those mappings created by PCP requests), due to reboot, power failure, or any other reason, it MUST reset its Epoch time to its initial starting value (usually zero) to provide this hint to PCP clients. After resetting its Epoch time, the PCP server resumes incrementing the Epoch Time value by one every second.
Similarly, if the external IP address(es) of the NAT (controlled by the PCP server) changes, the Epoch time MUST be reset. A PCP server MAY maintain one Epoch Time value for all PCP clients or MAY maintain distinct Epoch Time values (per PCP client, per interface, or based on other criteria); this choice is implementation-dependent. Whenever a client receives a PCP response, the client validates the received Epoch Time value according to the procedure below, using integer arithmetic: o If this is the first PCP response the client has received from this PCP server, the Epoch Time value is treated as necessarily valid, otherwise * If the current PCP server Epoch time (curr_server_time) is less than the previously received PCP server Epoch time (prev_server_time) by more than one second, then the client treats the Epoch time as obviously invalid (time should not go backwards). The server Epoch time apparently going backwards by *up to* one second is not deemed invalid, so that minor packet reordering on the path from PCP server to PCP client does not trigger a cascade of unnecessary mapping renewals. If the server Epoch time passes this check, then further validation checks are performed: + The client computes the difference between its current local time (curr_client_time) and the time the previous PCP response was received from this PCP server (prev_client_time): client_delta = curr_client_time - prev_client_time; + The client computes the difference between the current PCP server Epoch time (curr_server_time) and the previously received Epoch time (prev_server_time): server_delta = curr_server_time - prev_server_time; + If client_delta+2 < server_delta - server_delta/16 or server_delta+2 < client_delta - client_delta/16, then the client treats the Epoch Time value as invalid, else the client treats the Epoch Time value as valid. o The client records the current time values for use in its next comparison: prev_client_time = curr_client_time prev_server_time = curr_server_time
If the PCP client determined that the Epoch Time value it received was invalid, then it concludes that the PCP server may have lost state, and promptly renews all its active port mapping leases following the mapping recreation procedure described in Section 16.3.1. Notes: o The client clock MUST never go backwards. If curr_client_time is found to be less than prev_client_time, then this is a client bug, and how the client deals with this client bug is implementation specific. o The calculations above are constructed to allow client_delta and server_delta to be computed as unsigned integer values. o The "+2" in the calculations above is to accommodate quantization errors in client and server clocks (up to one-second quantization error each in server and client time intervals). o The "/16" in the calculations above is to accommodate inaccurate clocks in low-cost devices. This allows for a total discrepancy of up to 1/16 (6.25%) to be considered benign; e.g., if one clock were to run too fast by 3% while the other clock ran too slow by 3%, then the client would not consider this difference to be anomalous or indicative of a restart having occurred. This tolerance is strict enough to be effective at detecting reboots, while not being so strict as to generate false alarms.9. Version Negotiation
A PCP client sends its requests using PCP version number 2. Should later updates to this document specify different message formats with a version number greater than 2, it is expected that PCP servers will still support version 2 in addition to the newer version(s). However, in the event that a server returns a response with result code UNSUPP_VERSION, the client MAY log an error message to inform the user that it is too old to work with this server. Should later updates to this document specify different message formats with a version number greater than 2, and backwards compatibility be desired, this first octet can be used for forward and backward compatibility.
If future PCP versions greater than 2 are specified, version negotiation proceeds as follows: 1. The client sends its first request using the highest (i.e., presumably 'best') version number it supports. 2. If the server supports that version, it responds normally. 3. If the server does not support that version, it replies giving a result containing the result code UNSUPP_VERSION, and the closest version number it does support (if the server supports a range of versions higher than the client's requested version, the server returns the lowest of that supported range; if the server supports a range of versions lower than the client's requested version, the server returns the highest of that supported range). 4. If the client receives an UNSUPP_VERSION result containing a version it does support, it records this fact and proceeds to use this message version for subsequent communication with this PCP server (until a possible future UNSUPP_VERSION response if the server is later updated, at which point the version negotiation process repeats). If the version number in the UNSUPP_VERSION response is zero then that means this is a NAT-PMP server [RFC6886], and a client MAY choose to communicate with it using the older NAT-PMP protocol, as described in Appendix A. 5. If the client receives an UNSUPP_VERSION result containing a version it does not support, then the client SHOULD try the next- lower version supported by the client. The attempt to use the next-lower version repeats until the client has tried version 2. If using version 2 fails, the client MAY log an error message to inform the user that it is too old to work with this server, and the client SHOULD set a timer to retry its request in 30 minutes or the returned Lifetime value, whichever is smaller. By automatically retrying in 30 minutes, the protocol accommodates an upgrade of the PCP server.10. Introduction to MAP and PEER Opcodes
There are four uses for the MAP and PEER Opcodes defined in this document: o a host operating a server and wanting an incoming connection (Section 10.1); o a host operating a client and server on the same port (Section 10.2);
o a host operating a client and wanting to optimize the application keepalive traffic (Section 10.3); and o a host operating a client and wanting to restore lost state in its NAT (Section 10.4). These are discussed in the following sections, and a (non-normative) state diagram is provided in Section 16.5. When operating a server (see Sections 10.1 and 10.2), the PCP client knows if it wants an IPv4 listener, IPv6 listener, or both on the Internet. The PCP client also knows if it has an IPv4 address or IPv6 address configured on one of its interfaces. It takes the union of this knowledge to decide to which of its PCP servers to send the request (e.g., an IPv4 address or an IPv6 address), and whether to send one or two MAP requests for each of its interfaces (e.g., if the PCP client has only an IPv4 address but wants both IPv6 and IPv4 listeners, it sends a MAP request containing the all-zeros IPv6 address in the Suggested External Address field, and sends a second MAP request containing the all-zeros IPv4 address in the Suggested External Address field). If the PCP client has both an IPv4 and IPv6 address, and only wants an IPv4 listener, it sends one MAP request from its IPv4 address (if the PCP server supports NAT44 or IPv4 firewall) or one MAP request from its IPv6 address (if the PCP server supports NAT64). The PCP client can simply request the desired mapping to determine if the PCP server supports the desired mapping. Applications that embed IP addresses in payloads (e.g., FTP, SIP) will find it beneficial to avoid address family translation, if possible. The MAP and PEER requests include a Suggested External IP Address field. Some PCP-controlled devices, especially CGN but also multi- homed NPTv6 networks, have a pool of public-facing IP addresses. PCP allows the client to indicate if it wants a mapping assigned on a specific address of that pool or any address of that pool. Some applications will break if mappings are created on different IP addresses (e.g., active mode FTP), so applications should carefully consider the implications of using this capability. Static mappings for that internal address (e.g., those created by a command-line interface on the PCP server or PCP-controlled device) may exist to a certain external address, and if the suggested external IP address is the IPv4 or IPv6 all-zeros address, PCP SHOULD assign its mappings to the same external address, as this can also help applications using a mix of both static mappings and PCP-created mappings. If, on the other hand, the suggested external IP address contains a non-zero IP address the PCP server SHOULD create a mapping to that external address, even if there are other mappings from that same internal address to a different external address. Once an internal address
has no implicit dynamic mappings and no explicit dynamic mappings in the PCP-controlled device, a subsequent implicit or explicit mapping for that internal address MAY be assigned to a different External address. Generally, this reassignment would occur when a CGN device is load balancing newly seen internal addresses to its public pool of external addresses. The following table summarizes how various common PCP deployments use IPv6 and IPv4 addresses. The 'internal' address is implicitly the same as the source IP address of the PCP request, except when the THIRD_PARTY option is used. The 'external' address is the Suggested External Address field of the MAP or PEER request, and its address family is usually the same as the 'internal' address family, except when technologies like NAT64 are used. The 'remote peer' address is the remote peer IP address of the PEER request or the FILTER option of the MAP request, and is always the same address family as the 'internal' address, even when NAT64 is used. In NAT64, the IPv6 PCP client is not necessarily aware of the NAT64 or aware of the actual IPv4 address of the remote peer, so it expresses the IPv6 address from its perspective, as shown in Figure 5. internal external PCP remote peer actual remote peer -------- ------- --------------- ------------------ IPv4 firewall IPv4 IPv4 IPv4 IPv4 IPv6 firewall IPv6 IPv6 IPv6 IPv6 NAT44 IPv4 IPv4 IPv4 IPv4 NAT46 IPv4 IPv6 IPv4 IPv6 NAT64 IPv6 IPv4 IPv6 IPv4 NPTv6 IPv6 IPv6 IPv6 IPv6 Figure 5: Address Families with MAP and PEER Note that the internal address and the remote peer address are always the same address family, and the external address and the actual remote peer address are always the same address family.
10.1. For Operating a Server
A host operating a server (e.g., a web server) listens for traffic on a port, but the server never initiates traffic from that port. For this to work across a NAT or a firewall, the host needs to (a) create a mapping from a public IP address, protocol, and port to itself using the MAP Opcode, as described in Section 11; (b) publish that public IP address, protocol, and port via some sort of rendezvous server (e.g., DNS, a SIP message, or a proprietary protocol); and (c) ensure that any other non-PCP-speaking packet filtering middleboxes on the path (e.g., host-based firewall, network-based firewall, or other NATs) will also allow the incoming traffic. Publishing the public IP address and port is out of scope of this specification. To accomplish (a), the host follows the procedures described in this section. As normal, the application needs to begin listening on a port. Then, the application constructs a PCP message with the MAP Opcode, with the external address set to the appropriate all-zeros address, depending on whether it wants a public IPv4 or IPv6 address.
The following pseudocode shows how PCP can be reliably used to operate a server: /* start listening on the local server port */ int s = socket(...); bind(s, ...); listen(s, ...); getsockname(s, &internal_sockaddr, ...); bzero(&external_sockaddr, sizeof(external_sockaddr)); while (1) { /* Note: The "time_to_send_pcp_request()" check below includes: * 1. Sending the first request * 2. Retransmitting requests due to packet loss * 3. Resending a request due to impending lease expiration * 4. Resending a request due to server state loss * The PCP packet sent is identical in all four cases; from * the PCP server's point of view they are the same operation. * The suggested external address and port may be updated * repeatedly during the lifetime of the mapping. * Other fields in the packet generally remain unchanged. */ if (time_to_send_pcp_request()) pcp_send_map_request(internal_sockaddr.sin_port, internal_sockaddr.sin_addr, &external_sockaddr, /* will be zero the first time */ requested_lifetime, &assigned_lifetime); if (pcp_response_received()) update_rendezvous_server("Client Ident", external_sockaddr); if (received_incoming_connection_or_packet()) process_it(s); if (other_work_to_do()) do_it(); /* ... */ block_until_we_need_to_do_something_else(); } Figure 6: Pseudocode for Using PCP to Operate a Server
10.2. For Operating a Symmetric Client/Server
A host operating a client and server on the same port (e.g., Symmetric RTP [RFC4961] or SIP Symmetric Response Routing (rport) [RFC3581]) first establishes a local listener, (usually) sends the local and public IP addresses, protocol, and ports to a rendezvous service (which is out of scope of this document), and initiates an outbound connection from that same source address and same port. To accomplish this, the application uses the procedure described in this section. An application that is using the same port for outgoing connections as well as incoming connections MUST first signal its operation of a server using the PCP MAP Opcode, as described in Section 11, and receive a positive PCP response before it sends any packets from that port. Discussion: In general, a PCP client doesn't know in advance if it is behind a NAT or firewall. On detecting that the host has connected to a new network, the PCP client can attempt to request a mapping using PCP; if that succeeds, then the client knows it has successfully created a mapping. If, after multiple retries, it has received no PCP response, then either the client is *not* behind a NAT or firewall and has unfettered connectivity or the client *is* behind a NAT or firewall that doesn't support PCP (and the client may still have working connectivity by virtue of static mappings previously created manually by the user). Retransmitting PCP requests multiple times before giving up and assuming unfettered connectivity adds delay in that case. Initiating outbound TCP connections immediately without waiting for PCP avoids this delay, and will work if the NAT has endpoint- independent mapping (EIM) behavior, but may fail if the NAT has endpoint-dependent mapping (EDM) behavior. Waiting enough time to allow an explicit PCP MAP mapping to be created (if possible) first ensures that the same external port will then be used for all subsequent implicit dynamic mappings (e.g., TCP SYNs) sent from the specified internal address, protocol, and port. PCP supports both EIM and EDM NATs, so clients need to assume they may be dealing with an EDM NAT. In this case, the client will experience more reliable connectivity if it attempts explicit PCP MAP requests first, before initiating any outbound TCP connections from that internal address and port. For further information on using PCP with EDM NATs, see Section 16.1.
The following pseudocode shows how PCP can be used to operate a symmetric client and server: /* start listening on the local server port */ int s = socket(...); bind(s, ...); listen(s, ...); getsockname(s, &internal_sockaddr, ...); bzero(&external_sockaddr, sizeof(external_sockaddr)); while (1) { /* Note: The "time_to_send_pcp_request()" check below includes: * 1. Sending the first request * 2. Retransmitting requests due to packet loss * 3. Resending a request due to impending lease expiration * 4. Resending a request due to server state loss */ if (time_to_send_pcp_request()) pcp_send_map_request(internal_sockaddr.sin_port, internal_sockaddr.sin_addr, &external_sockaddr, /* will be zero the first time */ requested_lifetime, &assigned_lifetime); if (pcp_response_received()) update_rendezvous_server("Client Ident", external_sockaddr); if (received_incoming_connection_or_packet()) process_it(s); if (need_to_make_outgoing_connection()) make_outgoing_connection(s, ...); if (data_to_send()) send_it(s); if (other_work_to_do()) do_it(); /* ... */ block_until_we_need_to_do_something_else(); } Figure 7: Pseudocode for Using PCP to Operate a Symmetric Client/Server
10.3. For Reducing NAT or Firewall Keepalive Messages
A host operating a client (e.g., XMPP client, SIP client) sends from a port, and may receive responses, but never accepts incoming connections from other remote peers on this port. It wants to ensure that the flow to its remote peer is not terminated (due to inactivity) by an on-path NAT or firewall. To accomplish this, the application uses the procedure described in this section. Middleboxes, such as NATs or firewalls, generally need to see occasional traffic or they will terminate their session state, causing application failures. To avoid this, many applications routinely generate keepalive traffic for the primary (or sole) purpose of maintaining state with such middleboxes. Applications can reduce such application keepalive traffic by using PCP. Note: For reasons beyond NAT, an application may find it useful to perform application-level keepalives, such as to detect a broken path between the client and server, keep state alive on the remote peer, or detect a powered-down client. These keepalives are not related to maintaining middlebox state, and PCP cannot do anything useful to reduce those keepalives. To use PCP for this function, the application first connects to its server, as normal. Afterwards, it issues a PCP request with the PEER Opcode as described in Section 12 to learn and/or extend the lifetime of its mapping.
The following pseudocode shows how PCP can be reliably used with a dynamic socket, for the purposes of reducing application keepalive messages: /* make outgoing connection to server */ int s = socket(...); connect(s, &remote_peer, ...); getsockname(s, &internal_sockaddr, ...); bzero(&external_sockaddr, sizeof(external_sockaddr)); while (1) { /* Note: The "time_to_send_pcp_request()" check below includes: * 1. Sending the first request * 2. Retransmitting requests due to packet loss * 3. Resending a request due to impending lease expiration * 4. Resending a request due to server state loss */ if (time_to_send_pcp_request()) pcp_send_peer_request(internal_sockaddr.sin_port, internal_sockaddr.sin_addr, &external_sockaddr, /* will be zero the first time */ remote_peer, requested_lifetime, &assigned_lifetime); if (data_to_send()) send_it(s); if (received_incoming_data()) process_it(s); if (other_work_to_do()) do_it(); /* ... */ block_until_we_need_to_do_something_else(); } Figure 8: Pseudocode Using PCP with a Dynamic Socket10.4. For Restoring Lost Implicit TCP Dynamic Mapping State
After a NAT loses state (e.g., because of a crash or power failure), it is useful for clients to re-establish TCP mappings on the NAT. This allows servers on the Internet to see traffic from the same IP address and port, so that sessions can be resumed exactly where they were left off. This can be useful for long-lived connections
(e.g., instant messaging) or for connections transferring a lot of data (e.g., FTP). This can be accomplished by first establishing a TCP connection normally and then sending a PEER request/response and remembering the external address and external port. Later, when the NAT has lost state, the client can send a PEER request with the suggested external port and suggested external address remembered from the previous session, which will create a mapping in the NAT that functions exactly as an implicit dynamic mapping. The client then resumes sending TCP data to the server. Note: This procedure works well for TCP, provided: (i) the NAT creates a new implicit dynamic outbound mapping only for outbound TCP segments with the SYN bit set (i.e., the newly booted NAT silently drops outbound data segments from the client when the NAT does not have an active mapping for those segments), and (ii) the newly booted NAT does not send a TCP RST in response to receiving unexpected inbound TCP segments. This procedure works less well for UDP, because as soon as outbound UDP traffic is seen by the NAT, a new UDP implicit dynamic outbound mapping will be created (probably on a different port).11. MAP Opcode
This section defines an Opcode that controls inbound forwarding from a NAT (or firewall) to an internal host. MAP: Create an explicit dynamic mapping between an Internal Address + Port and an External Address + Port. PCP servers SHOULD provide a configuration option to allow administrators to disable MAP support if they wish. Mappings created by PCP MAP requests are, by definition, endpoint- independent mappings (EIMs) with endpoint-independent filtering (EIF) (unless the FILTER option is used), even on a NAT that usually creates endpoint-dependent mapping (EDM) or endpoint-dependent filtering (EDF) for outgoing connections, since the purpose of an (unfiltered) MAP mapping is to receive inbound traffic from any remote endpoint, not from only one specific remote endpoint. Note also that all NAT mappings (created by PCP or otherwise) are by necessity bidirectional and symmetric. For any packet going in one direction (in or out) that is translated by the NAT, a reply going in
the opposite direction needs to have the corresponding opposite translation done so that the reply arrives at the right endpoint. This means that if a client creates a MAP mapping, and then later sends an outgoing packet using the mapping's internal address, protocol, and port, the NAT should translate that packet's internal address and port to the mapping's external address and port, so that replies addressed to the external address and port are correctly translated back to the mapping's internal address and port. On operating systems that allow multiple listening servers to bind to the same internal address, protocol, and port, servers MUST ensure that they have exclusive use of that internal address, protocol, and port (e.g., by binding the port using INADDR_ANY, or using SO_EXCLUSIVEADDRUSE or similar) before sending their PCP MAP request, to ensure that no other PCP clients on the same machine are also listening on the same internal protocol and internal port. As a side effect of creating a mapping, ICMP messages associated with the mapping MUST be forwarded (and also translated, if appropriate) for the duration of the mapping's lifetime. This is done to ensure that ICMP messages can still be used by hosts, without application programmers or PCP client implementations needing to use PCP separately to create ICMP mappings for those flows. The operation of the MAP Opcode is described in this section.11.1. MAP Operation Packet Formats
The MAP Opcode has a similar packet layout for both requests and responses. If the assigned external IP address and port in the PCP response always match the internal IP address and port from the PCP request, then the functionality is purely a firewall; otherwise, the functionality is a Network Address Translator that might also perform firewall-like functions.
The following diagram shows the format of the Opcode-specific information in a request for the MAP Opcode. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Mapping Nonce (96 bits) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Protocol | Reserved (24 bits) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internal Port | Suggested External Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Suggested External IP Address (128 bits) | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 9: MAP Opcode Request These fields are described below: Requested lifetime (in common header): Requested lifetime of this mapping, in seconds. The value 0 indicates "delete". Mapping Nonce: Random value chosen by the PCP client. See Section 11.2, "Generating a MAP Request". Zero is a legal value (but unlikely, occurring in roughly one in 2^96 requests). Protocol: Upper-layer protocol associated with this Opcode. Values are taken from the IANA protocol registry [proto_numbers]. For example, this field contains 6 (TCP) if the Opcode is intended to create a TCP mapping. This field contains 17 (UDP) if the Opcode is intended to create a UDP mapping. The value 0 has a special meaning for 'all protocols'. Reserved: 24 reserved bits, MUST be sent as 0 and MUST be ignored when received. Internal Port: Internal port for the mapping. The value 0 indicates 'all ports', and is legal when the lifetime is zero (a delete request), if the protocol does not use 16-bit port numbers, or the client is requesting 'all ports'. If the protocol is zero (meaning 'all protocols'), then internal port MUST be zero on transmission and MUST be ignored on reception.
Suggested External Port: Suggested external port for the mapping. This is useful for refreshing a mapping, especially after the PCP server loses state. If the PCP client does not know the external port, or does not have a preference, it MUST use 0. Suggested External IP Address: Suggested external IPv4 or IPv6 address. This is useful for refreshing a mapping, especially after the PCP server loses state. If the PCP client does not know the external address, or does not have a preference, it MUST use the address-family-specific all-zeros address (see Section 5). The internal address for the request is the source IP address of the PCP request message itself, unless the THIRD_PARTY option is used. The following diagram shows the format of Opcode-specific information in a response packet for the MAP Opcode: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Mapping Nonce (96 bits) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Protocol | Reserved (24 bits) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internal Port | Assigned External Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Assigned External IP Address (128 bits) | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 10: MAP Opcode Response These fields are described below: Lifetime (in common header): On an error response, this indicates how long clients should assume they'll get the same error response from the PCP server if they repeat the same request. On a success response, this indicates the lifetime for this mapping, in seconds. Mapping Nonce: Copied from the request. Protocol: Copied from the request.
Reserved: 24 reserved bits, MUST be sent as 0 and MUST be ignored when received. Internal Port: Copied from the request. Assigned External Port: On a success response, this is the assigned external port for the mapping. On an error response, the suggested external port is copied from the request. Assigned External IP Address: On a success response, this is the assigned external IPv4 or IPv6 address for the mapping. An IPv4 address is encoded using IPv4-mapped IPv6 address. On an error response, the suggested external IP address is copied from the request.11.2. Generating a MAP Request
This section describes the operation of a PCP client when sending requests with the MAP Opcode. The request MAY contain values in the Suggested External Port and Suggested External IP Address fields. This allows the PCP client to attempt to rebuild lost state on the PCP server, which improves the chances of existing connections surviving, and helps the PCP client avoid having to change information maintained at its rendezvous server. Of course, due to other activity on the network (e.g., by other users or network renumbering), the PCP server may not be able to grant the suggested external IP address, protocol, and port, and in that case it will assign a different external IP address and port. A PCP client MUST be written assuming that it may *never* be assigned the external port it suggests. In the case of recreating state after a NAT gateway crash, the suggested external port, being one that was previously allocated to this client, is likely to be available for this client to continue using. In all other cases, the client MUST assume that it is unlikely that its suggested external port will be granted. For example, when many subscribers are sharing a Carrier- Grade NAT, popular ports such as 80, 443, and 8080 are likely to be in high demand. At most one client can have each of those popular ports for each external IP address, and all the other clients will be assigned other, dynamically allocated, external ports. Indeed, some ISPs may, by policy, choose not to grant those external ports to *anyone*, so that none of their clients are *ever* assigned external ports 80, 443, or 8080. If the protocol does not use 16-bit port numbers (e.g., RSVP, IP protocol number 46), the port number MUST be zero. This will cause all traffic matching that protocol to be mapped.
If the client wants all protocols mapped, it uses protocol 0 (zero) and internal port 0 (zero). The Mapping Nonce value is randomly chosen by the PCP client, following accepted practices for generating unguessable random numbers [RFC4086], and is used as part of the validation of PCP responses (see below) by the PCP client, and validation for mapping refreshes by the PCP server. The client MUST use a different mapping nonce for each PCP server it communicates with, and it is RECOMMENDED to choose a new random mapping nonce whenever the PCP client is initialized. The client MAY use a different mapping nonce for every mapping.11.2.1. Renewing a Mapping
An existing mapping SHOULD have its lifetime extended by the PCP client for as long as the client wishes to have that mapping continue to exist. To do this, the PCP client sends a new MAP request indicating the internal port. The PCP MAP request SHOULD also include the currently assigned external IP address and port in the Suggested External IP Address and Suggested External Port fields, so if the PCP server has lost state it can recreate the lost mapping with the same parameters. The PCP client SHOULD renew the mapping before its expiry time; otherwise, it will be removed by the PCP server (see Section 15, "Mapping Lifetime and Deletion"). To reduce the risk of inadvertent synchronization of renewal requests, a random jitter component should be included. It is RECOMMENDED that PCP clients send a single renewal request packet at a time chosen with uniform random distribution in the range 1/2 to 5/8 of expiration time. If no SUCCESS response is received, then the next renewal request should be sent 3/4 to 3/4 + 1/16 to expiration, and then another 7/8 to 7/8 + 1/32 to expiration, and so on, subject to the constraint that renewal requests MUST NOT be sent less than four seconds apart (a PCP client MUST NOT send a flood of ever-closer-together requests in the last few seconds before a mapping expires).11.3. Processing a MAP Request
This section describes the operation of a PCP server when processing a request with the MAP Opcode. Processing SHOULD be performed in the order of the following paragraphs. The Protocol, Internal Port, and Mapping Nonce fields from the MAP request are copied into the MAP response. The THIRD_PARTY option, if present, and processed by the PCP server, is also copied into the MAP response.
If the requested lifetime is non-zero, then: o If both the protocol and internal port are non-zero, it indicates a request to create a mapping or extend the lifetime of an existing mapping. If the PCP server or PCP-controlled device does not support the protocol, the UNSUPP_PROTOCOL error MUST be returned. o If the protocol is non-zero and the internal port is zero, it indicates a request to create or extend a mapping for all incoming traffic for that entire protocol -- a 'wildcard' (all-ports) mapping for that protocol. If this request cannot be fulfilled in its entirety, the UNSUPP_PROTOCOL error MUST be returned. o If both the protocol and internal port are zero, it indicates a request to create or extend a mapping for all incoming traffic for all protocols (commonly called a 'DMZ host'). If this request cannot be fulfilled in its entirety, the UNSUPP_PROTOCOL error MUST be returned. o If the protocol is zero and the internal port is non-zero, then the request is invalid and the PCP server MUST return a MALFORMED_REQUEST error to the client. If the requested lifetime is zero, it indicates a request to delete an existing mapping. Further processing of the lifetime is described in Section 15, "Mapping Lifetime and Deletion". If operating in the Simple Threat Model (Section 18.1), and the internal port, protocol, and internal address match an existing explicit dynamic mapping, but the mapping nonce does not match, the request MUST be rejected with a NOT_AUTHORIZED error with the lifetime of the error indicating duration of that existing mapping. The PCP server only needs to remember one Mapping Nonce value for each explicit dynamic mapping. This specification makes no statement about mapping nonce with the Advanced Threat Model. If the internal port, protocol, and internal address match an existing static mapping (which will have no nonce), then a PCP reply is sent giving the external address and port of that static mapping, using the nonce from the PCP request. The server does not record the nonce.
If an option with value less than 128 exists (i.e., mandatory to process) but that option does not make sense (e.g., the PREFER_FAILURE option is included in a request with lifetime=0), the request is invalid and generates a MALFORMED_OPTION error. If the PCP-controlled device is stateless (that is, it does not establish any per-flow state, and simply rewrites the address and/or port in a purely algorithmic fashion, including no rewriting), the PCP server simply returns an answer indicating the external IP address and port yielded by this stateless algorithmic translation. This allows the PCP client to learn its external IP address and port as seen by remote peers. Examples of stateless translators include stateless NAT64, 1:1 NAT44, and NPTv6 [RFC6296], all of which modify addresses but not port numbers, and pure firewalls, which modify neither the address nor the port. It is possible that a mapping might already exist for a requested internal address, protocol, and port. If so, the PCP server takes the following actions: 1. If the MAP request contains the PREFER_FAILURE option, but the suggested external address and port do not match the external address and port of the existing mapping, the PCP server MUST return CANNOT_PROVIDE_EXTERNAL. 2. If the existing mapping is static (created outside of PCP), the PCP server MUST return the external address and port of the existing mapping in its response and SHOULD indicate a lifetime of 2^32-1 seconds, regardless of the suggested external address and port in the request. 3. If the existing mapping is explicit dynamic inbound (created by a previous MAP request), the PCP server MUST return the existing external address and port in its response, regardless of the suggested external address and port in the request. Additionally, the PCP server MUST update the lifetime of the existing mapping, in accordance with Section 15, "Mapping Lifetime and Deletion". 4. If the existing mapping is dynamic outbound (created by outgoing traffic or a previous PEER request), the PCP server SHOULD create a new explicit inbound mapping, replicating the ports and addresses from the outbound mapping (but the outbound mapping continues to exist, and remains in effect if the explicit inbound mapping is later deleted). If no mapping exists for the internal address, protocol, and port, and the PCP server is able to create a mapping using the suggested
external address and port, it SHOULD do so. This is beneficial for re-establishing state lost in the PCP server (e.g., due to a reboot). There are, however, cases where the PCP server is not able to create a new mapping using the suggested external address and port: o The suggested external address, protocol, and port is already assigned to another existing explicit or implicit mapping (i.e., is already forwarding traffic to some other internal address and port). o The suggested external address, protocol, and port is already used by the NAT gateway for one of its own services, for example, TCP port 80 for the NAT gateway's own configuration web pages, or UDP ports 5350 and 5351, used by PCP itself. A PCP server MUST NOT create client mappings for external UDP ports 5350 or 5351. o The suggested external address, protocol, and port is otherwise prohibited by the PCP server's policy. o The suggested external IP address, protocol, or suggested port are invalid or invalid combinations (e.g., external address 127.0.0.1, ::1, a multicast address, or the suggested port is not valid for the protocol). o The suggested external address does not belong to the NAT gateway. o The suggested external address is not configured to be used as an external address of the firewall or NAT gateway. If the PCP server cannot assign the suggested external address, protocol, and port, then: o If the request contained the PREFER_FAILURE option, then the PCP server MUST return CANNOT_PROVIDE_EXTERNAL. o If the request did not contain the PREFER_FAILURE option, and the PCP server can assign some other external address and port for that protocol, then the PCP server MUST do so and return the newly assigned external address and port in the response. In no case is the client penalized for a 'poor' choice of suggested external address and port. The suggested external address and port may be used by the server to guide its choice of what external address and port to assign, but in no case do they cause the server to fail to allocate an external address and port where otherwise it would have succeeded. The presence of a non-zero suggested external address or port is merely a hint; it never does any harm.
A PCP-controlled device MUST NOT create mappings for a protocol not indicated in the request. For example, if the request was for a TCP mapping, an additional corresponding UDP mapping MUST NOT be automatically created. Mappings typically consume state on the PCP-controlled device, and it is RECOMMENDED that a per-host and/or per-subscriber limit be enforced by the PCP server to prevent exhausting the mapping state. If this limit is exceeded, the result code USER_EX_QUOTA is returned. If all of the preceding operations were successful (did not generate an error response), then the requested mapping is created or refreshed as described in the request and a SUCCESS response is built.11.4. Processing a MAP Response
This section describes the operation of the PCP client when it receives a PCP response for the MAP Opcode. After performing common PCP response processing, the response is further matched with a previously sent MAP request by comparing the internal IP address (the destination IP address of the PCP response, or other IP address specified via the THIRD_PARTY option), the protocol, the internal port, and the mapping nonce. Other fields are not compared, because the PCP server sets those fields. The PCP server will send a Mapping Update (Section 14.2) if the mapping changes (e.g., due to IP renumbering). If the result code is NO_RESOURCES and the request was for the creation or renewal of a mapping, then the PCP client SHOULD NOT send further requests for any new mappings to that PCP server for the (limited) value of the lifetime. If the result code is NO_RESOURCES and the request was for the deletion of a mapping, then the PCP client SHOULD NOT send further requests of *any kind* to that PCP server for the (limited) value of the lifetime. On a success response, the PCP client can use the external IP address and port as needed. Typically, the PCP client will communicate the external IP address and port to another host on the Internet using an application-specific rendezvous mechanism such as DNS SRV records. After a success response, for as long as renewal is desired, the PCP client MUST set a timer or otherwise schedule an event to renew the mapping before its lifetime expires. Renewing a mapping is performed by sending another MAP request, exactly as described in Section 11.2, except that the suggested external address and port SHOULD be set to the values received in the response. From the PCP server's point of
view a MAP request to renew a mapping is identical to a MAP request to create a new mapping, and is handled identically. Indeed, in the event of PCP server state loss, a renewal request from a PCP client will appear to the server to be a request to create a new mapping, with a particular suggested external address and port, which happen to be what the PCP server previously assigned. See also Section 16.3.1, "Recreating Mappings". On an error response, the client SHOULD NOT repeat the same request to the same PCP server within the lifetime returned in the response.11.5. Address Change Events
A customer premises router might obtain a new external IP address, for a variety of reasons including a reboot, power outage, DHCP lease expiry, or other action by the ISP. If this occurs, traffic forwarded to a host's previous address might be delivered to another host that now has that address. This affects all mapping types, whether implicit or explicit. This same problem already occurs today when a host's IP address is reassigned, without PCP and without an ISP-operated CGN. The solution is the same as today: the problems associated with host renumbering are caused by host renumbering, and are eliminated if host renumbering is avoided. PCP defined in this document does not provide machinery to reduce the host renumbering problem. When an internal host changes its internal IP address (e.g., by having a different address assigned by the DHCP server), the NAT (or firewall) will continue to send traffic to the old IP address. Typically, the internal host will no longer receive traffic sent to that old IP address. Assuming the internal host wants to continue receiving traffic, it needs to install new mappings for its new IP address. The Suggested External Port field will not be fulfilled by the PCP server, in all likelihood, because it is still being forwarded to the old IP address. Thus, a mapping is likely to be assigned a new external port number and/or external IP address. Note that such host renumbering is not expected to happen routinely on a regular basis for most hosts, since most hosts renew their DHCP leases before they expire (or re-request the same address after reboot) and most DHCP servers honor such requests and grant the host the same address it was previously using before the reboot. A host might gain or lose interfaces while existing mappings are active (e.g., Ethernet cable plugged in or removed, joining/leaving a WiFi network). Because of this, if the PCP client is sending a PCP request to maintain state in the PCP server, it SHOULD ensure that those PCP requests continue to use the same interface (e.g., when refreshing mappings). If the PCP client is sending a PCP request to
create new state in the PCP server, it MAY use a different source interface or different source address.11.6. Learning the External IP Address Alone
NAT-PMP [RFC6886] includes a mechanism to allow clients to learn the external IP address alone, without also requesting a port mapping. NAT-PMP was designed for residential NAT gateways, where such an operation makes sense because a typical residential NAT gateway has only one external IP address. PCP has broader scope, and also supports Carrier-Grade NATs (CGNs) that may have a pool of external IP addresses, not just one. A client may not be assigned any particular external IP address from that pool until it has at least one implicit, explicit, or static port mapping, and even then only for as long as that mapping remains valid. Client software that just wishes to display the user's external IP address for cosmetic purposes can achieve that by requesting a short-lived mapping (e.g., to the Discard service (TCP/9 or UDP/9) or some other port) and then displaying the resulting external IP address. However, once that mapping expires a subsequent implicit or explicit dynamic mapping might be mapped to a different external IP address.