<?xml version="1.0" encoding="US-ASCII"?>

<!-- xml2rfc v2 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="no"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc rfcedstyle="yes"?>

<rfc category="std" number="6970" submissionType="IETF" consensus="yes"
     ipr="trust200902">

  <front>
    <title abbrev="UPnP IGD-PCP IWF">
Universal&nbsp;Plug&nbsp;and&nbsp;Play&nbsp;(UPnP) 
Internet&nbsp;Gateway&nbsp;Device&nbsp;-&nbsp;Port&nbsp;Control&nbsp;Protocol
Interworking&nbsp;Function (IGD-PCP IWF)</title>

    <author fullname="Mohamed Boucadair" initials="M." surname="Boucadair">
      <organization>France Telecom</organization>
      <address>
        <postal>
          <street></street>
          <city>Rennes</city>
          <code>35000</code>
          <country>France</country>
        </postal>
        <email>mohamed.boucadair@orange.com</email>
      </address>
    </author>

    <author fullname="Reinaldo Penno" initials="R." surname="Penno">
      <organization abbrev="Cisco">Cisco Systems, Inc.</organization>
      <address>
        <postal>
          <street>170 West Tasman Drive</street>
          <city>San Jose</city>
          <region>California</region>
          <code>95134</code>
          <country>USA</country>
        </postal>
        <email>repenno@cisco.com</email>
      </address>
    </author>

    <author fullname="Dan Wing" initials="D." surname="Wing">
      <organization abbrev="Cisco">Cisco Systems, Inc.</organization>
      <address>
        <postal>
          <street>170 West Tasman Drive</street>
          <city>San Jose</city>
          <region>California</region>
          <code>95134</code>
          <country>USA</country>
        </postal>
        <email>dwing@cisco.com</email>
      </address>
    </author>

    <date month="July" year="2013" />

    <workgroup>PCP Working Group</workgroup>

    <keyword>UPnP, pinhole, PCP, mapping, NAT control, interworking</keyword>

<!-- [rfced] FYI, we have used xml2rfc v2 (available from 
http://xml.resource.org) to convert this document to text. -->

    <abstract>
      <t>This document specifies the behavior of the Universal Plug and Play
      (UPnP) Internet Gateway Device - Port Control Protocol Interworking
      Function (IGD-PCP IWF). A UPnP IGD-PCP IWF is required to be embedded
      in Customer Premises (CP) routers to allow for transparent NAT control in
      environments where a UPnP IGD is used on the LAN side and PCP is used
      on the external side of the CP router.</t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
      <t>The Port Control Protocol (PCP) specification <xref target="RFC6887"></xref>
      discusses the implementation of NAT control features that rely
      upon Carrier Grade NAT devices such as a Dual-Stack Lite (DS-Lite)
      Address Family Transition Router (AFTR) <xref target="RFC6333"></xref>
      or NAT64 <xref target="RFC6146"></xref>. In
      environments where a Universal Plug and Play Internet Gateway Device
      (UPnP IGD) is used in the local network, an interworking function
      between the UPnP IGD and PCP is required to be
      embedded in the IGD (see the example illustrated in <xref
      target="iwf_example"></xref>).</t>

      <t><figure anchor="iwf_example" title="Flow Example">
          <preamble></preamble>

          <artwork><![CDATA[                         UPnP IGD-PCP
UPnP Control             Interworking
   Point                   Function                  PCP Server
     |                       IGD                          |
     |                        |                           |
     |  (1) AddPortMapping()  |                           |
     |----------------------->|                           |
     |                        |   (2) PCP MAP Request     |
     |                        |-------------------------->|
     |                        |                           |]]></artwork>

          <postamble></postamble>
        </figure></t>

      <t>Two configurations are considered within this document:<list
          style="symbols">
          <t>No NAT function is embedded in the IGD (<xref
          target="spec_no_nat"></xref>). This is required, for instance, in
          DS-Lite or NAT64 deployments.</t>

          <t>The IGD embeds a NAT function (<xref target="spec_nat"></xref>).</t>
        </list></t>

      <t>The UPnP IGD-PCP Interworking Function (UPnP IGD-PCP IWF) maintains a
      local mapping table that stores all active mappings constructed by
      internal IGD Control Points. This design choice restricts the amount of
      PCP messages to be exchanged with the PCP server.</t>

      <t>Triggers for deactivating the UPnP IGD-PCP IWF from the IGD and
      relying on a PCP-only mode are out of scope for this document.</t>

      <t>Considerations related to co-existence of the UPnP IGD-PCP
      Interworking Function and a PCP Proxy <xref target="PCP-PROXY"></xref>
      are out of scope.</t>

      <section title="Requirements Language">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>
      </section>

    </section>

    <section title="Acronyms">
      <t>This document makes use of the following abbreviations:</t>

      <?rfc subcompact="yes"?>

      <t><list style="empty">
          <t>DS-Lite - Dual-Stack Lite</t>

          <t>IGD - Internet Gateway Device</t>

          <t>IGD:1 - UPnP Forum's nomenclature for version 1 of IGD <xref target="IGD1"/></t>

          <t>IGD:2 - UPnP Forum's nomenclature for version 2 of IGD <xref target="IGD2"/></t>

          <t>IWF - Interworking Function</t>

          <t>NAT - Network Address Translation</t>

          <t>PCP - Port Control Protocol</t>

          <t>UPnP - Universal Plug and Play</t>
        </list></t>

      <?rfc subcompact="no"?>
    </section>

    <section title="Architecture Model">
      <t>As a reminder, <xref target="igd_model"></xref> illustrates the
      architecture model as adopted by the UPnP Forum <xref
      target="IGD2"></xref>. In <xref target="igd_model"></xref>, the
      following UPnP terminology is used:<list style="symbols">
          <t>'Client' refers to a host located in the local network.</t>

          <t>'IGD Control Point' is a device using UPnP to control an IGD
          (Internet Gateway Device).</t>

          <t>'IGD' is a router supporting a UPnP IGD. It is typically a NAT or
          a firewall.</t>

          <t>'Host' is a remote peer reachable in the Internet.</t>
        </list></t>

      <t><figure align="center" anchor="igd_model" title="UPnP IGD Model">
          <preamble></preamble>

          <artwork><![CDATA[+-------------+
| IGD Control |
|   Point     |-----+
+-------------+     |   +-----+       +------+ 
                    +---|     |       |      |
                        | IGD |-------| Host |
                    +---|     |       |      |
+-------------+     |   +-----+       +------+
|   Client    |-----+
+-------------+
]]></artwork>

          <postamble></postamble>
        </figure></t>

      <t>This model is not valid when PCP is used to control, for instance, a
      Carrier Grade NAT (aka Provider NAT) while internal hosts continue
      to use a UPnP IGD. In such
      scenarios, <xref target="igdpcp"></xref> shows the updated model.</t>

      <t><figure align="center" anchor="igdpcp"
          title="UPnP IGD-PCP Interworking Model">
          <preamble></preamble>
          <artwork><![CDATA[+-------------+
| IGD Control |
|   Point     |----+
+-------------+    |   +-----+      +--------+               +------+
                   +---| IGD-|      |Provider|               |Remote|
                       | PCP |------|  NAT   |--<Internet>---| Host |
                   +---| IWF |      |        |               |      |
+-------------+    |   +-----+      +--------+               +------+
| Local Host  |----+
+-------------+ 
                     LAN Side  External Side              
<======UPnP IGD==============><=====PCP=====>
]]></artwork>
          <postamble></postamble>
        </figure></t>

      <t>In the updated model depicted in <xref target="igdpcp"></xref>, one
      or two levels of NAT can be encountered in the data path. Indeed, in
      addition to the Carrier Grade NAT, the IGD may embed a NAT function
      (<xref target="multinat"></xref>).</t>

      <t><figure align="center" anchor="multinat"
          title="Cascaded NAT Scenario">
          <preamble></preamble>
          <artwork><![CDATA[+-------------+
| IGD Control |
|   Point     |----+
+-------------+    |   +-----+      +--------+               +------+
                   +---| IGD-|      |Provider|               |Remote|
                       | PCP |------|  NAT   |--<Internet>---| Host |
                   +---| IWF |      |        |               |      |
+-------------+    |   +-----+      +--------+               +------+
| Local Host  |----+    NAT1           NAT2
+-------------+ 
]]></artwork>
          <postamble></postamble>
        </figure></t>

      <t>To ensure successful interworking between a UPnP IGD and PCP, an
      interworking function is embedded in the IGD. In the model defined in
      <xref target="igdpcp"></xref>, all UPnP IGD server-oriented functions, a
      PCP client <xref target="RFC6887"></xref>, and a UPnP IGD-PCP
      Interworking Function are embedded in the IGD. In the rest of the
      document, "IGD-PCP IWF" refers to the UPnP IGD-PCP Interworking Function,
      which includes PCP client functionality.</t>

      <t>Without the involvement of the IGD-PCP IWF, the IGD Control Point
      would retrieve an external IP address and port number that have limited
      scope and that cannot be used to communicate with hosts located beyond
      NAT2 (i.e., assigned by the IGD, and not those assigned by NAT2 as
      depicted in <xref target="multinat"></xref>).</t>

      <t>The UPnP IGD-PCP IWF is responsible for generating a well-formed PCP
      message from a received UPnP IGD message, and vice versa.</t>
    </section>

    <section title="UPnP IGD-PCP IWF: Overview">
      <t>Three tables are provided to specify the correspondence between
      a UPnP IGD and PCP:<list style="format (%d)">
          <t><xref target="variables"></xref> provides the mapping between
          WANIPConnection state variables and PCP parameters;</t>

          <t><xref target="methods"></xref> focuses on the correspondence
          between supported methods;</t>

          <t><xref target="errors"></xref> lists the PCP error messages and
          their corresponding IGD error messages.</t>
        </list></t>

      <t>Note that some enhancements have been integrated in WANIPConnection,
      as documented in <xref target="IGD2"></xref>.</t>

      <section anchor="variables" title="UPnP IGD-PCP: State Variables">
        <t>Below are listed only the UPnP IGD state variables applicable to
        the IGD-PCP IWF:</t>

        <t><list style="hanging">
            <t hangText="ExternalIPAddress:">External IP Address <vspace />
            Read-only variable with the value from the last PCP response, or
            the empty string if none was received yet. This state is stored on
            a per-IGD-Control-Point basis.</t>

            <t hangText="PortMappingNumberOfEntries:">Managed locally by the
            UPnP IGD-PCP IWF.</t>

            <t hangText="PortMappingEnabled:"><vspace /> PCP does not support
            deactivating the dynamic NAT mapping, since the initial goal of PCP
            is to ease the traversal of Carrier Grade NAT. Supporting such
            per-subscriber function may overload the Carrier Grade NAT.
            <vspace /> Only "1" is allowed: i.e., the UPnP IGD-PCP
            Interworking Function MUST send back an error if a value different
            from 1 is signaled.</t>

            <t hangText="PortMappingLeaseDuration:">Requested Mapping Lifetime
            <vspace /> In IGD:1 <xref target="IGD1"></xref>, the value 0 means
            infinite; in IGD:2, it is remapped to the IGD maximum of 604800
            seconds <xref target="IGD2"></xref>. PCP allows for a maximum
            value of 4294967296 seconds. <vspace /> The UPnP IGD-PCP
            Interworking Function simulates long and even infinite lifetimes
            using renewals (see <xref target="renewal"></xref>). The behavior
            of the UPnP IGD-PCP IWF in the case of a failing renewal is
            currently undefined (see <xref target="renewal"></xref>).
            <vspace /> IGD:1 doesn't define the behavior in the case of state
            loss; IGD:2 doesn't require that state be kept in stable storage,
            i.e., to allow the state to survive resets/reboots. The UPnP
            IGD-PCP Interworking Function MUST support IGD:2 behavior.</t>

            <t hangText="RemoteHost:">Remote Peer IP Address <vspace /> Note
            that IGD:2 allows a domain name, which has to be resolved to an IP
            address. Mapped to the Remote Peer IP Address field of the FILTER
            option.</t>

            <t hangText="ExternalPort:">External Port Number <vspace /> Mapped
            to the Suggested External Port field in MAP messages.</t>

            <t hangText="InternalPort:">Internal Port Number <vspace /> Mapped
            to the Internal Port field in MAP messages.</t>

            <t hangText="PortMappingProtocol:">Protocol <vspace /> Mapped to
            the Protocol field in MAP messages. Note that a UPnP IGD only
            supports TCP and UDP.</t>

            <t hangText="InternalClient:">Internal IP Address <vspace /> Note
            that IGD:2 allows a domain name, which has to be resolved to an IP
            address. Mapped to the Internal IP Address field of the THIRD_PARTY
            option.</t>

            <t hangText="PortMappingDescription:">Not supported in base
            PCP.<vspace /> If the local PCP client supports a PCP option to
            convey the description (e.g., <xref
            target="PCP-DESCR-OPT"></xref>), this option
            SHOULD be used to relay the mapping description.</t>

            <t hangText="SystemUpdateID (IGD:2 only):">Managed locally by the
            UPnP IGD-PCP IWF.</t>

            <t hangText="A_ARG_TYPE_PortListing (IGD:2 only):">Managed locally
            by the UPnP IGD-PCP IWF.</t>
          </list></t>
      </section>

      <section anchor="methods" title="IGD-PCP: Methods">
        <t>IGD:1 and IGD:2 methods applicable to the UPnP IGD-PCP
        Interworking Function are both listed here. <list style="hanging">
            <t hangText="GetGenericPortMappingEntry():">This request is not
            relayed to the PCP server. <vspace />The IGD-PCP Interworking
            Function maintains a list of active mappings instantiated in the
            PCP server by internal hosts. See <xref target="list"></xref> for
            more information.</t>

            <t hangText="GetSpecificPortMappingEntry():">MAP with
            PREFER_FAILURE option.<vspace />
            This request is relayed to the PCP server by
            issuing a MAP request with the PREFER_FAILURE option. It is
            RECOMMENDED to use a short lifetime (e.g., 60 seconds).</t>

            <t hangText="AddPortMapping():">MAP <vspace /> See <xref
            target="addportmapping"></xref>.</t>

            <t hangText="AddAnyPortMapping() (IGD:2 only):">MAP <vspace /> See
            <xref target="addanyportmapping"></xref>.</t>

            <t hangText="DeletePortMapping():">MAP with Requested Lifetime set
            to 0. <vspace /> See <xref target="delete"></xref>.</t>

            <t hangText="DeletePortMappingRange() (IGD:2 only):">MAP with
            Requested Lifetime set to 0. <vspace /> Individual requests are
            issued by the IGD-PCP IWF. See <xref target="delete"></xref> for
            more details.</t>

            <t hangText="GetExternalIPAddress():">MAP <vspace /> This can be
            learned from any active mapping. If there are no active mappings,
            the IGD-PCP IWF MAY request a short-lived mapping (e.g., to the
            Discard service (TCP/9 or UDP/9) or some other port). However,
            once that mapping expires, a subsequent implicit or explicit
            dynamic mapping might be mapped to a different external IP
            address. See Section 11.6 of <xref target="RFC6887"></xref>
            for more discussion.</t>

            <t hangText="GetListOfPortMappings():">See <xref
            target="list"></xref> for more information.<vspace /> The IGD-PCP
            Interworking Function maintains a list of active mappings
            instantiated in the PCP server. The IGD-PCP Interworking Function
            handles this request locally.</t>
          </list></t>
      </section>

      <section anchor="errors" title="UPnP IGD-PCP: Errors">
        <t>This section lists PCP error codes and the corresponding UPnP IGD
        codes. Error codes specific to IGD:2 are tagged accordingly.</t>

        <t><list hangIndent="3" style="hanging">
            <t hangText="1 UNSUPP_VERSION:">501 "ActionFailed"</t>

            <t hangText="2 NOT_AUTHORIZED:">IGD:1 718 "ConflictInMappingEntry"
            / IGD:2 606 "Action not authorized"</t>

            <t hangText="3 MALFORMED_REQUEST:">501 "ActionFailed"</t>

            <t hangText="4 UNSUPP_OPCODE:">501 "ActionFailed" <vspace /> <xref
            target="RFC6887"></xref> allows the PCP server to be
            configured to disable support for the MAP Opcode, but the IGD-PCP
            IWF cannot work in this situation.</t>

            <t hangText="5 UNSUPP_OPTION:">501 "ActionFailed" <vspace /> This
            error code can be received if PREFER_FAILURE is not supported on
            the PCP server. Note that PREFER_FAILURE is not mandatory to
            support, but AddPortMapping() cannot be implemented without
            it.</t>

            <t hangText="6 MALFORMED_OPTION:">501 "ActionFailed"</t>

            <t hangText="7 NETWORK_FAILURE:">501 "ActionFailed"</t>

            <t hangText="8 NO_RESOURCES:">IGD:1 501 "ActionFailed" / IGD:2 728
            <vspace /> "NoPortMapsAvailable" <vspace /> Cannot be
            distinguished from USER_EX_QUOTA.</t>

            <t hangText="9 UNSUPP_PROTOCOL:">501 "ActionFailed"</t>

            <t hangText="10 USER_EX_QUOTA:">IGD:1 501 "ActionFailed" / IGD:2
            728 <vspace /> "NoPortMapsAvailable" <vspace /> Cannot be
            distinguished from NO_RESOURCES.</t>

            <t hangText="11 CANNOT_PROVIDE_EXTERNAL:">718
            "ConflictInMappingEntry" (see <xref target="addportmapping"/>)
            or 714 "NoSuchEntryInArray" (see <xref target="delete"/>).</t>

            <t hangText="12 ADDRESS_MISMATCH:">501 "ActionFailed"</t>

            <t hangText="13 EXCESSIVE_REMOTE_PEERS:">501 "ActionFailed" </t>
          </list></t>
      </section>
    </section>

    <section title="Specification of the IGD-PCP IWF">
      <t>This section covers scenarios with or without NAT in the IGD.</t>

      <t>This specification assumes that the PCP server is configured to accept
      the MAP Opcode.</t>

      <t>The IGD-PCP IWF handles the "Mapping Nonce" the same way as any
      PCP client <xref target="RFC6887"></xref>.</t>

      <section anchor="discovery" title="PCP Server Discovery">
        <t>The IGD-PCP IWF implements one of the discovery methods identified
        in <xref target="RFC6887"></xref> (e.g., DHCP <xref
        target="PCP-DHCP-OPT"></xref>). The IGD-PCP Interworking Function
        behaves as a PCP client when communicating with provisioned
        PCP server(s).</t>

        <t>If no IPv4 address/IPv6 prefix is assigned to the IGD or the IGD
        is unable to determine whether it should contact an upstream
        PCP server, the IGD-PCP Interworking Function MUST NOT be invoked.</t>

        <t>If the IGD determines that it should establish communication with
        an upstream PCP server (e.g., because of DHCP configuration or having
        previously communicated with a PCP server), a "501 ActionFailed" error
        message is returned to the requesting IGD Control Point if the
        IGD-PCP IWF fails to establish communication with that PCP server.
        Note that the IGD-PCP IWF proceeds to PCP message validation and
        retransmission the same way as any PCP client <xref
        target="RFC6887"></xref>.</t>
      </section>

      <section title="Control of the Firewall">
        <t>In order to configure security policies to be applied to inbound
        and outbound traffic, a UPnP IGD can be used to control a local
        firewall engine. No IGD-PCP IWF is therefore required for that
        purpose.</t>

        <t>The use of the IGD-PCP IWF to control an upstream PCP-controlled
        firewall is out of scope for this document.</t>
      </section>

      <section title="Port Mapping Table">
        <t>The IGD-PCP IWF MUST store locally all the mappings instantiated by
        internal IGD Control Points in the PCP server. All mappings SHOULD be
        stored in permanent storage.</t>

        <t>Upon receipt of a PCP MAP response from the PCP server, the IGD-PCP
        Interworking Function MUST extract the enclosed mapping and MUST store
        it in the local mapping table. The local mapping table is an image of
        the mapping table as maintained by the PCP server for a given
        subscriber.</t>

        <t>Each mapping entry stored in the local mapping table is associated
        with a lifetime as discussed in <xref
        target="RFC6887"></xref>. Additional considerations specific
        to the IGD-PCP Interworking Function are discussed in <xref
        target="renewal"></xref>.</t>
      </section>

      <section anchor="spec_no_nat"
               title="Interworking Function without NAT in the IGD"
               toc="default">
        <t>When no NAT is embedded in the IGD, the contents of received
        WANIPConnection and PCP messages are not altered by the IGD-PCP
        Interworking Function (i.e., the contents of WANIPConnection messages
        are mapped to PCP messages (and mapped back), according to <xref
        target="variables"></xref>).</t>
      </section>

      <section anchor="spec_nat" title="NAT Embedded in the IGD" toc="default">
        <t>When NAT is embedded in the IGD, the IGD-PCP IWF updates the
        contents of mapping messages received from the IGD Control Point. These
        messages will contain an IP address and/or port number that belong to
        an internal host. The IGD-PCP IWF MUST update such messages with the
        IP address and/or port number belonging to the external interface of
        the IGD (i.e., after the NAT1 operation as depicted in <xref
        target="multinat"></xref>).</t>

        <t>The IGD-PCP IWF intercepts all WANIPConnection messages issued by
        the IGD Control Point. For each such message, the IGD-PCP IWF then
        generates one or more corresponding requests
        (see Sections <xref target="variables" format="counter"></xref>,
        <xref target="methods" format="counter"></xref>, and <xref
        target="errors" format="counter"></xref>) and sends them to the
        provisioned PCP server.</t>

        <t>Each request sent by the IGD-PCP IWF to the PCP server MUST reflect
        the mapping information as enforced in the first NAT. Particularly,
        the internal IP address and/or port number of the requests are
        replaced with the IP address and/or port number as assigned by the NAT
        of the IGD. For the reverse path, the IGD-PCP IWF intercepts PCP
        response messages and generates WANIPConnection response messages. The
        contents of the generated WANIPConnection response messages are set as
        follows:</t>

        <t><list style="symbols">
            <t>The internal IP address and/or port number as initially set by
            the IGD Control Point and stored in the IGD NAT are used to update
            the corresponding fields in received PCP responses.</t>

            <t>The external IP address and port number are not altered by the
            IGD-PCP Interworking Function.</t>

            <t>The NAT mapping entry in the IGD is updated with the result of
            each PCP request.</t>
          </list></t>

        <t>The lifetime of the mappings instantiated in the IGD SHOULD be the
        one assigned by the terminating PCP server. In any case, the lifetime
        MUST NOT be lower than the one assigned by the terminating
        PCP server.</t>
      </section>

      <section title="Creating a Mapping">
        <t>Two methods can be used to create a mapping: AddAnyPortMapping() and
        AddPortMapping().</t>

        <section anchor="addanyportmapping" title="AddAnyPortMapping()">
          <t>When an IGD Control Point issues an AddAnyPortMapping() call, this
          request is received by the IGD. The request is then relayed to the
          IGD-PCP IWF, which generates a PCP MAP request (see <xref
          target="variables"></xref> for mapping between WANIPConnection and
          PCP parameters).</t>

          <t>If the IGD-PCP IWF fails to send the MAP request to its
          PCP server, it follows the behavior defined in <xref
          target="discovery"></xref>.</t>

          <t>Upon receipt of a PCP MAP response from the PCP server, the
          corresponding UPnP IGD method is returned to the requesting IGD
          Control Point (the contents of the messages follow the
          recommendations listed in <xref target="spec_nat"></xref> or <xref
          target="spec_no_nat"></xref>, according to the deployed scenario). A
          flow example is depicted in <xref target="igd2"></xref>.</t>

          <t>If a PCP error is received from the PCP server, a corresponding
          WANIPConnection error code (see <xref target="errors"></xref>) is
          generated by the IGD&nbhy;PCP IWF and sent to the requesting IGD
          Control Point. If a short-lifetime error is returned (e.g.,
          NETWORK_FAILURE, NO_RESOURCES), the PCP IWF MAY resend the same
          request to the PCP server after 30&nbsp;seconds. If a negative answer
          is received, the error is then relayed to the requesting IGD
          Control Point.</t>


          <t><list style="empty">
              <t>Discussion: Some applications (e.g., uTorrent, Vuze, eMule)
              wait 90 seconds or more for a response after sending a UPnP
              request. If a short-lifetime error occurs, resending the request
              may lead to a positive response from the PCP server. IGD Control
              Points are therefore not aware of transient errors.</t>
            </list></t>

          <t><figure anchor="igd2"
              title="Flow Example: AddAnyPortMapping()">
              <preamble></preamble>
              <artwork><![CDATA[                            UPnP-PCP
UPnP Control              Interworking
   Point                    Function                    PCP Server
     |                         |                             |
     | (1) AddAnyPortMapping() |                             |
     |    ExternalPort=8080    |                             |
     |------------------------>|                             |
     |                         |   (2) PCP MAP Request       |
     |                         |Suggested External Port=8080 |
     |                         |---------------------------->|
     |                         |                             |
     |                         |   (3) PCP MAP Response      |
     |                         | Assigned External Port=6598 |
     |                         |<----------------------------|
     | (4) AddAnyPortMapping() |                             |
     |    ReservedPort=6598    |                             |
     |<------------------------|                             |
]]></artwork>
              <postamble></postamble>
            </figure></t>

        </section>

        <section anchor="addportmapping" title="AddPortMapping()">
          <t>A dedicated option called "PREFER_FAILURE" is defined in <xref
          target="RFC6887"></xref> to toggle the behavior in a PCP
          request message. This option is inserted by the IGD-PCP IWF when
          issuing its requests to the PCP server only if a specific external
          port is requested by the IGD Control Point.</t>

          <t>Upon receipt of AddPortMapping() from an IGD Control Point, the
          IGD&nbhy;PCP IWF MUST generate a PCP MAP request with all requested
          mapping information as indicated by the IGD Control Point if no NAT
          is embedded in the IGD or updated as specified in <xref
          target="spec_nat"></xref>. In addition, the IGD-PCP IWF MUST insert
          a PREFER_FAILURE option in the generated PCP request.</t>

          <t>If the IGD-PCP IWF fails to send the MAP request to its
          PCP server, it follows the behavior defined in <xref
          target="discovery"></xref>.</t>

          <t>If the requested external port is not available, the PCP server
          will send a CANNOT_PROVIDE_EXTERNAL error response: <list
              style="numbers">
              <t>If a short-lifetime error is returned, the IGD-PCP IWF MAY
              resend the same request to the PCP server after 30 seconds
              without relaying the error to the IGD Control Point. The IGD-PCP
              IWF MAY repeat this process until a positive answer is received
              or some maximum retry limit is reached. When the maximum retry
              limit is reached, the IGD-PCP IWF relays a negative message to
              the IGD Control Point with ConflictInMappingEntry as the error
              code. The maximum retry limit is implementation-specific; its
              default value is 2.</t>

              <t>If a long-lifetime error is returned, the IGD-PCP IWF relays
              a negative message to the IGD Control Point with
              ConflictInMappingEntry as the error code.</t>
            </list></t>

          <t>The IGD Control Point may issue a new request with a different
          requested external port number. This process is typically repeated
          by the IGD Control Point until a positive answer is received or some
          maximum retry limit is reached.</t>

          <t>If the PCP server is able to create or renew a mapping with the
          requested external port, it sends a positive response to the IGD-PCP
          IWF. Upon receipt of the response from the PCP server, the IGD-PCP
          IWF stores the returned mapping in its local mapping table and
          sends the corresponding positive answer to the requesting IGD
          Control Point. This answer terminates the exchange.</t>

          <t><xref target="positive"></xref> shows an example of the flow
          exchange that occurs when the PCP server satisfies the request from
          the IGD-PCP IWF. <xref target="negative"></xref> shows the message
          exchange when the requested external port is not available.</t>

          <t><figure anchor="positive" title="Flow Example (Positive Answer)">
              <preamble></preamble>

              <artwork><![CDATA[                           UPnP-PCP
UPnP Control             Interworking
   Point                   Function                    PCP Server
     |                        |                             |
     |  (1) AddPortMapping()  |                             |
     |    ExternalPort=8080   |                             |
     |----------------------->|                             |
     |                        |   (2) PCP MAP Request       |
     |                        |Suggested External Port=8080 |
     |                        |       PREFER_FAILURE        |
     |                        |---------------------------->|
     |                        |                             |
     |                        |   (3) PCP MAP Response      |
     |                        | Assigned External Port=8080 |
     |                        |<----------------------------|
     |  (4) AddPortMapping()  |                             |
     |    ExternalPort=8080   |                             |
     |<-----------------------|                             |
]]></artwork>

              <postamble></postamble>
            </figure></t>

          <t><figure anchor="negative" title="Flow Example (Negative Answer)">
              <preamble></preamble>

              <artwork><![CDATA[                           UPnP-PCP
UPnP Control             Interworking
   Point                   Function                    PCP Server
     |                        |                             |
     |  (1) AddPortMapping()  |                             |
     |    ExternalPort=8080   |                             |
     |----------------------->|                             |
     |                        |   (2) PCP MAP Request       |
     |                        |Suggested External Port=8080 |
     |                        |       PREFER_FAILURE        |
     |                        |---------------------------->|
     |                        |   (3) PCP MAP Response      |
     |                        |   CANNOT_PROVIDE_EXTERNAL   | 
     |                        |<----------------------------|
     |      (4) Error:        |                             |
     | ConflictInMappingEntry |                             |
     |<-----------------------|                             |
     |  (5) AddPortMapping()  |                             |
     |    ExternalPort=5485   |                             |
     |----------------------->|                             |
     |                        |   (6) PCP MAP Request       |
     |                        |Suggested External Port=5485 |
     |                        |       PREFER_FAILURE        |
     |                        |---------------------------->|
     |                        |   (7) PCP MAP Response      |
     |                        |   CANNOT_PROVIDE_EXTERNAL   |
     |                        |<----------------------------|
     |      (8) Error:        |                             |
     | ConflictInMappingEntry |                             |
     |<-----------------------|                             |
                              ....
     |  (a) AddPortMapping()  |                             |
     |    ExternalPort=6591   |                             |
     |----------------------->|                             |
     |                        |   (b) PCP MAP Request       |
     |                        |Suggested External Port=6591 |
     |                        |       PREFER_FAILURE        |
     |                        |---------------------------->|
     |                        |   (c) PCP MAP Response      |
     |                        |   CANNOT_PROVIDE_EXTERNAL   |
     |                        |<----------------------------|
     |      (d) Error:        |                             |
     | ConflictInMappingEntry |                             |
     |<-----------------------|                             |
]]></artwork>

              <postamble></postamble>
            </figure><list style="empty">
              <t>Note: According to some experiments, some UPnP 1.0 Control
              Point implementations, e.g., uTorrent, simply try the same
              external port a number of times (usually 4 times) and then fail
              if the port is in use. Also note that some applications use
              GetSpecificPortMappingEntry() to determine whether a mapping
              exists.</t>
            </list></t>
        </section>
      </section>

      <section anchor="list" title="Listing One or a Set of Mappings">
        <t>In order to list active mappings, an IGD Control Point may issue
        GetGenericPortMappingEntry(), GetSpecificPortMappingEntry(), or
        GetListOfPortMappings().</t>

        <t>GetGenericPortMappingEntry() and GetListOfPortMappings() methods
        MUST NOT be proxied to the PCP server, since a local mapping is
        maintained by the IGD-PCP IWF.</t>

        <t>Upon receipt of GetSpecificPortMappingEntry() from an IGD Control
        Point, the IGD-PCP IWF MUST check first to see if the external
        port number is
        used by the requesting IGD Control Point. If the external port is
        already in use by the requesting IGD Control Point, the IGD&nbhy;PCP
        IWF MUST send back the mapping entry matching the request. If not, the
        IGD-PCP IWF MUST relay to the PCP server a MAP request, with short
        lifetime (e.g., 60 seconds), including a PREFER_FAILURE option. If the
        IGD-PCP IWF fails to send the MAP request to its PCP server, it
        follows the behavior defined in <xref target="discovery"></xref>. If
        the requested external port is in use, a PCP error message will be
        sent by the PCP server to the IGD-PCP IWF indicating
        CANNOT_PROVIDE_EXTERNAL as the error cause. Then, the IGD-PCP IWF
        relays a negative message to the IGD Control Point. If the port is not
        in use, the mapping will be created by the PCP server and a positive
        response will be sent back to the IGD-PCP IWF. Once received by the
        IGD-PCP IWF, it MUST relay a negative message to the IGD Control Point
        indicating NoSuchEntryInArray as the error code so that the IGD
        Control Point knows the queried mapping doesn't exist. </t>
      </section>

      <section anchor="delete"
               title="Delete One or a Set of Mappings: DeletePortMapping() or DeletePortMappingRange()">
        <t>An IGD Control Point requests the deletion of one or a list of
        mappings by issuing DeletePortMapping() or
        DeletePortMappingRange().</t>

        <t>In IGD:2, we assume that the IGD applies the appropriate security
        policies to determine whether a Control Point has the rights to delete
        one or a set of mappings. When authorization fails, the "606 Action
        Not Authorized" error code is returned to the requesting Control
        Point.</t>

        <t>When DeletePortMapping() or DeletePortMappingRange() is received by
        the IGD-PCP IWF, it first checks if the requested mappings to be
        removed are present in the local mapping table. If no mapping matching
        the request is found in the local table, an error code is sent back to
        the IGD Control Point: "714 NoSuchEntryInArray" for
        DeletePortMapping() or "730 PortMappingNotFound" for
        DeletePortMappingRange().</t>

        <t><xref target="local_delete"></xref> shows an example of an IGD
        Control Point asking to delete a mapping that is not instantiated in
        the local table of the IWF.</t>

        <figure anchor="local_delete" title="Local Delete (IGD-PCP IWF)">
          <preamble></preamble>

          <artwork><![CDATA[                            UPnP-PCP
UPnP Control              Interworking
   Point                    Function                  PCP Server
     |                         |                           |
     | (1) DeletePortMapping() |                           |
     |------------------------>|                           |
     |                         |                           |
     |       (2) Error:        |                           |
     |    NoSuchEntryInArray   |                           |
     |<------------------------|                           |
     |                         |                           |
]]></artwork>

          <postamble></postamble>
        </figure>

        <t></t>

        <t>If a mapping matches in the local table, a PCP MAP delete request
        is generated. If no NAT is enabled in the IGD, the IGD-PCP IWF uses
        the input arguments as included in DeletePortMapping(). If a NAT is
        enabled in the IGD, the IGD-PCP IWF instead uses the corresponding IP
        address and port number as assigned by the local NAT.</t>

        <t>If the IGD-PCP IWF fails to send the MAP request to its PCP server,
        it follows the behavior defined in <xref
        target="discovery"></xref>.</t>

        <t>When a positive answer is received from the PCP server, the IGD-PCP
        IWF updates its local mapping table (i.e., removes the corresponding
        entry) and notifies the IGD Control Point of the result of the
        removal operation. Once the PCP MAP delete request is received by the
        PCP server, it removes the corresponding entry. A PCP MAP SUCCESS
        response is sent back if the removal of the corresponding entry was
        successful; if not, a PCP error message containing the corresponding
        error cause (see <xref target="errors"></xref>) is sent back to the
        IGD&nbhy;PCP IWF.</t>

        <t>If DeletePortMappingRange() is used, the IGD-PCP IWF does a lookup
        in its local mapping table to retrieve individual mappings,
        instantiated by the requesting Control Point (i.e., authorization
        checks), that match the signaled port range (i.e., the external port
        is within the "StartPort" and "EndPort" arguments of
        DeletePortMappingRange()). If no mapping is found, the "730
        PortMappingNotFound" error code is sent to the IGD Control Point
        (<xref target="delete_range_error"></xref>). If one or more mappings
        are found, the IGD-PCP IWF generates individual PCP MAP delete
        requests corresponding to these mappings (see the example shown in
        <xref target="delete_range"></xref>).</t>

        <t>The IGD-PCP IWF MAY send a positive answer to the requesting IGD
        Control Point without waiting to receive all the answers from the
        PCP server.</t>

        <t><figure anchor="delete_range_error"
            title="Flow Example: Error Encountered when Processing DeletePortMappingRange()">
            <preamble></preamble>
            <artwork><![CDATA[                                 UPnP-PCP
UPnP Control                   Interworking
   Point                         Function                 PCP Server
     |                              |                          |
     | (1) DeletePortMappingRange() |                          |
     |       StartPort=8596         |                          |
     |       EndPort  =9000         |                          |
     |       Protocol =UDP          |                          |
     |----------------------------->|                          |
     |                              |                          |
     |       (2) Error:             |                          |
     |   PortMappingNotFound        |                          |
     |<-----------------------------|                          |
     |                              |                          |
]]></artwork>
            <postamble></postamble>
          </figure></t>

<t>
<xref target="delete_range"/> illustrates the exchanges that occur when
the IWF receives DeletePortMappingRange().  In this example, only
two mappings having the external port number in the 6000-6050
range are maintained in the local table. The IWF issues two MAP
requests to delete these mappings.
</t>
        <t><figure anchor="delete_range"
            title="Example of DeletePortMappingRange()">
            <artwork><![CDATA[                                 UPnP-PCP
UPnP Control                   Interworking
   Point                         Function                 PCP Server
     |                              |                          |
     | (1) DeletePortMappingRange() |                          |
     |     StartPort=6000           |                          |
     |     EndPort  =6050           |                          |
     |     Protocol =UDP            |                          |
     |----------------------------->|                          |
     |                              |                          |
     |                              |   (2a) PCP MAP Request   |
     |                              |       Protocol=UDP       |
     |                              |   internal-ip-address    |
     |                              |      internal-port       |
     |                              |   external-ip-address    |
     |                              |   external-port=6030     |
     |                              |   Requested-lifetime=0   |
     |                              |------------------------->|
     |                              |                          |
     |                              |   (2b) PCP MAP Request   |
     |                              |       Protocol=UDP       |
     |                              |   internal-ip-address    |
     |                              |      internal-port       |
     |                              |   external-ip-address    |
     |                              |   external-port=6045     |
     |                              |   Requested-lifetime=0   |
     |                              |------------------------->|
     |                              |                          |
     |     (3) Positive answer      |                          |
     |<-----------------------------|                          |
     |                              |                          |
]]></artwork>

            <postamble></postamble>
          </figure></t>

      </section>

      <section anchor="renewal" title="Renewing a Mapping">
        <t>Because of the incompatibility of mapping lifetimes between 
        a UPnP IGD and PCP, the IGD-PCP IWF MUST simulate long and even
        infinite lifetimes. Indeed, for requests having a requested infinite
        PortMappingLeaseDuration, the IGD-PCP IWF MUST set the Requested
        Lifetime of the corresponding PCP request to 4294967296. If
        PortMappingLeaseDuration is not infinite, the IGD-PCP IWF MUST set the
        Requested Lifetime of the corresponding PCP request to the same value
        as PortMappingLeaseDuration. Furthermore, the IGD-PCP Interworking
        Function MUST maintain an additional timer set to the initial
        requested PortMappingLeaseDuration. Upon receipt of a positive answer
        from the PCP server, the IGD-PCP IWF relays the corresponding UPnP IGD
        response to the requesting IGD Control Point with
        PortMappingLeaseDuration set to the same value as that of the
        initial request. Then, the IGD-PCP IWF MUST periodically renew the
        constructed PCP mapping until the expiry of PortMappingLeaseDuration.
        Responses received when renewing the mapping MUST NOT be relayed to
        the IGD Control Point.</t>

        <t>If an error is encountered during mapping renewal, the IGD-PCP
        Interworking Function has no means of informing the IGD Control
        Point of the error.</t>
      </section>

      <section title="Rapid Recovery">
        <t>When the IGD-PCP IWF is co-located with the DHCP server, the state
        maintained by the IGD-PCP IWF MUST be updated using the state in the
        local DHCP server. Particularly, if an IP address expires or is
        released by an internal host, the IGD-PCP IWF MUST delete all the
        mappings bound to that internal IP address.</t>

        <t>Upon change of the external IP address of the IGD-PCP IWF, the
        IGD&nbhy;PCP IWF MAY renew the mappings it maintained. This can be
        achieved
        only if a full state table is maintained by the IGD-PCP IWF. If the
        port quota is not exceeded in the PCP server, the IGD-PCP IWF will
        receive a new external IP address and port numbers. The IGD-PCP IWF
        has no means of notifying internal IGD Control Points of the change
        of the external IP address and port numbers. Stale mappings will be maintained
        by the PCP server until their lifetime expires. <list style="empty">
            <t>Note: If an address change occurs, protocols that are sensitive
            to address changes (e.g., TCP) will experience disruption.</t>
          </list></t>

        <t><xref target="RFC6887"></xref> defines a procedure for
        the PCP server to notify PCP clients of changes related to the
        mappings it maintains. When an unsolicited ANNOUNCE is received, the
        IGD-PCP IWF makes one or more MAP requests with the PREFER_FAILURE
        option to re-install its mappings. If the PCP server cannot create the
        requested mappings (signaled with the CANNOT_PROVIDE_EXTERNAL error
        response), the IGD&nbhy;PCP IWF has no means of notifying internal IGD
        Control Points of any changes of the external IP address and port
        numbers.</t>

        <t>Unsolicited PCP MAP responses received from a PCP server are
        handled as any normal MAP response. If a response indicates that the
        external IP address or port has changed, the IGD-PCP IWF has no means
        of notifying the internal IGD Control Point of this change.</t>

        <t>Further analysis of PCP failure scenarios for the IGD-PCP
        Interworking Function are discussed in <xref target="PCP-FAILURE"></xref>.</t>
      </section>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>IGD:2 access control requirements and authorization levels SHOULD be
      applied by default <xref target="IGD2"></xref>. When IGD:2 is used,
      operation on behalf of a third party SHOULD be allowed only if
      authentication and authorization are used <xref target="IGD2"></xref>.
      When only IGD:1 is available, operation on behalf of a third party
      SHOULD NOT be allowed.</t>

      <t>This document defines a procedure to create PCP mappings for
      third-party devices belonging to the same subscriber. The means for
      preventing a malicious user from creating mappings on behalf of a third
      party must be enabled as discussed in
      Section 13.1 of <xref target="RFC6887"></xref>. In particular, the
      THIRD_PARTY option MUST NOT be enabled unless the network on which the
      PCP messages are to be sent is fully trusted -- for example,
      access control lists (ACLs) installed on the PCP client, the PCP server,
      and the network between them, so that those ACLs allow only
      communications from a trusted PCP client to the PCP server.</t>

      <t>An IGD Control Point that issues AddPortMapping(),
      AddAnyPortMapping(), or GetSpecificPortMappingEntry() requests in a
      shorter time frame will create a lot of mapping entries on the PCP
      server. The means for avoiding the exhaustion of port resources
      (e.g., port quota, as discussed in Section 17.2 of <xref
      target="RFC6887"></xref>) SHOULD be enabled.</t>

      <t>The security considerations discussed in <xref
      target="RFC6887"></xref> and <xref target="Sec_DCP"></xref>
      should be taken into account.</t>
    </section>

    <section title="Acknowledgments">
      <t>The authors would like to thank F.&nbsp;Fontaine, C.&nbsp;Jacquenet,
      X.&nbsp;Deng, G.&nbsp;Montenegro, D.&nbsp;Thaler, R.&nbsp;Tirumaleswar,
      P.&nbsp;Selkirk, T.&nbsp;Lemon, V.&nbsp;Gurbani, and P.&nbsp;Yee
      for their review and comments.</t>

      <t>F.&nbsp;Dupont contributed to previous versions of this document.
      Thanks go to him for his thorough reviews and contributions.</t>
    </section>
  </middle>

  <back>
  <?rfc rfcedstyle="no"?>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119"?>

<!-- draft-ietf-pcp-base (RFC 6887, published April 2013) -->
      <?rfc include="reference.RFC.6887"?>

      <reference anchor="IGD2" target="http://upnp.org/specs/gw/UPnP-gw-WANIPConnection-v2-Service.pdf">
        <front>
          <title>WANIPConnection:2 Service</title>
          <author fullname="UPnP Forum">
            <organization>UPnP Forum</organization>
          </author>
          <date month="September" year="2010" />
        </front>
      </reference>

      <reference anchor="IGD1" target="http://upnp.org/specs/gw/UPnP-gw-WANIPConnection-v1-Service.pdf">
        <front>
          <title>WANIPConnection:1 Service Template Version 1.01</title>
          <author fullname="UPnP Forum">
            <organization>UPnP Forum</organization>
          </author>
          <date month="November" year="2001" />
        </front>
      </reference>
    </references>

    <references title="Informative References">
      <?rfc include='reference.RFC.6333'?>

      <?rfc include='reference.RFC.6146'?>

<!-- draft-boucadair-pcp-failure (I-D Exists) -->
<reference anchor='PCP-FAILURE'>
<front>
<title>Analysis of Port Control Protocol (PCP) Failure Scenarios</title>
<author initials='M' surname='Boucadair' fullname='Mohamed Boucadair'>
    <organization />
</author>
<author initials='R' surname='Penno' fullname='Reinaldo Penno'>
    <organization />
</author>
<date month='May' year='2013' />
</front>
<seriesInfo name='Work in' value='Progress' />
</reference>

<!-- draft-ietf-pcp-description-option (I-D Exists) -->
<reference anchor='PCP-DESCR-OPT'>
<front>
<title>PCP Description Option</title>
<author initials='M' surname='Boucadair' fullname='Mohamed Boucadair'>
    <organization />
</author>
<author initials='R' surname='Penno' fullname='Reinaldo Penno'>
    <organization />
</author>
<author initials='D' surname='Wing' fullname='Dan Wing'>
    <organization />
</author>
<date month='May' year='2013' />
</front>
<seriesInfo name='Work in' value='Progress' />
</reference>

<!-- draft-ietf-pcp-proxy (I-D Exists) -->
<reference anchor='PCP-PROXY'>
<front>
<title>Port Control Protocol (PCP) Proxy Function</title>
<author initials='M' surname='Boucadair' fullname='Mohamed Boucadair'>
    <organization />
</author>
<author initials='R' surname='Penno' fullname='Reinaldo Penno'>
    <organization />
</author>
<author initials='D' surname='Wing' fullname='Dan Wing'>
    <organization />
</author>
<date month='June' year='2013' />
</front>
<seriesInfo name='Work in' value='Progress' />
</reference>

<!-- draft-ietf-pcp-dhcp (I-D Exists) -->
<reference anchor='PCP-DHCP-OPT'>
<front>
<title>DHCP Options for the Port Control Protocol (PCP)</title>
<author initials='M' surname='Boucadair' fullname='Mohamed Boucadair'>
    <organization />
</author>
<author initials='R' surname='Penno' fullname='Reinaldo Penno'>
    <organization />
</author>
<author initials='D' surname='Wing' fullname='Dan Wing'>
    <organization />
</author>
<date month='March' year='2013' />
</front>
<seriesInfo name='Work in' value='Progress' />
</reference>

      <reference anchor="Sec_DCP" target="http://upnp.org/specs/gw/UPnP-gw-DeviceProtection-v1-Service.pdf">
        <front>
          <title>Device Protection:1 Service</title>
          <author fullname="UPnP Forum">
            <organization>UPnP Forum</organization>
          </author>
          <date month="February" year="2011" />
        </front>
      </reference>
    </references>
 <?rfc rfcedstyle="yes"?>
  </back>
</rfc>
