Subject: [pcp] UNSUPP_FAMILY error code

From: Stuart Cheshire <[email-masked]>
Date: Tue, 21 May 2013 19:08:13 -0700

In prototyping some PCP server code I ran into the following situation:

In a PCP request, the type of address in the Suggested External Address field controls whether an external IPv4 or IPv6 address is allocated. See page 31:

   if the PCP client ... 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

A NAT gateway that only implements IPv4 can support requests for an external IPv4 address (::FFFF:0.0.0.0 in the Suggested External Address field), but not requests for an external IPv6 address (:: in the Suggested External Address field).

Hence, it needs to return an error code if it receives a request with the all-zeros IPv6 address in the Suggested External Address field.

What error code? The closest I can see is UNSUPP_PROTOCOL (9), but that's not ideal. It would be better to have an explicit code for this. I propose:

UNSUPP_FAMILY, with value 14.

Comments?

Do other agree that we should have an explicit error code for this case?

Stuart Cheshire

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Wed, 22 May 2013 04:35:05 +0000

Agreed.

On 5/21/13 11:08 PM, "Stuart Cheshire" <[email-masked]> wrote:

>In a PCP request, the type of address in the Suggested External Address
>field controls whether an external IPv4 or IPv6 address is allocated. See
>page 31:
>
>A NAT gateway that only implements IPv4 can support requests for an
>external IPv4 address (::FFFF:0.0.0.0 in the Suggested External Address
>field), but not requests for an external IPv6 address (:: in the
>Suggested External Address field).
>
>Hence, it needs to return an error code if it receives a request with the
>all-zeros IPv6 address in the Suggested External Address field.
>
>What error code? The closest I can see is UNSUPP_PROTOCOL (9), but that's
>not ideal. It would be better to have an explicit code for this. I
>propose:
>
>_______________________________________________
>pcp mailing list
>[email-masked]
>https://www.ietf.org/mailman/listinfo/pcp

---

From: Simon Perreault <[email-masked]>
Date: Wed, 22 May 2013 10:20:48 +0200

> Agreed.

+1

Simon

---

From: Stuart Cheshire <[email-masked]>
Date: Tue, 28 May 2013 11:37:15 -0700

> Le 2013-05-22 06:35, Reinaldo Penno (repenno) a écrit :

Okay. A question for our chairs and AD:

19.3.  Result Codes

   IANA has created a new registry for PCP result codes, numbered 0-255,
   initially populated with the result codes from Section 7.4.  The
   value 255 is Reserved and may be assigned via Standards Action
   [RFC5226].

   The values in the range 14-127 can be assigned via Standards Action
   [RFC5226]

What is required for us to request IANA to allocate UNSUPP_FAMILY with value 14? An entire RFC? IETF-wide consensus? WG consensus?

Stuart Cheshire

---

From: Ted Lemon <[email-masked]>
Date: Tue, 28 May 2013 18:58:41 +0000

> What is required for us to request IANA to allocate UNSUPP_FAMILY with value 14? An entire RFC? IETF-wide consensus? WG consensus?

Oops, to be clear, a standards-track document has to be published by the IETF.   It could be quite short; if the working group can agree on it quickly, you could probably have it before Berlin.

---

From: Stuart Cheshire <[email-masked]>
Date: Tue, 28 May 2013 16:24:09 -0700

> Oops, to be clear, a standards-track document has to be published by the IETF.   It could be quite short; if the working group can agree on it quickly, you could probably have it before Berlin.

Here you go:

<http://tools.ietf.org/html/draft-cheshire-pcp-unsupp-family-00>

WG participants, please review and comment, and if there are no objections we can issue a WGLC.

For your convenience, the text is below.

2.  Introduction

   The Port Control Protocol [RFC6887] allows clients to request
   mappings in NAT gateways and firewalls.  A client can request a
   mapping to an external IPv4 address or to an external IPv6 address.
   The client signifies which family of external address it desires by
   the type of address it puts into the Suggested External Address
   field.

   If the client wants an external IPv4 address, then it populates the
   Suggested External Address field with an IPv4-mapped IPv6 address
   (the first 80 bits set to zero, the next 16 set to one).  This
   includes the case of the all-zeros IPv4 address (::ffff:0:0).

   If the client wants an external IPv6 address, then it populates the
   Suggested External Address field with a native IPv6 address.  This
   includes the case of the all-zeros IPv6 address (::).

   However, some devices may not be able to provide the requested
   external address family.  For example, an IPv4-only NAT cannot
   provide an external IPv6 address.

   In the event that the device cannot provide the requested external
   address family, it MUST return a PCP error reply containing the
   UNSUPP_FAMILY error code.

3.  IANA Considerations

   IANA should allocate the following PCP Result Code:

   14 UNSUPP_FAMILY: Unsupported external address family, e.g., IPv6 in
      a NAT that handles only IPv4.  This is a long lifetime error.

Stuart Cheshire

---

From: Simon Perreault <[email-masked]>
Date: Wed, 29 May 2013 10:40:49 +0200

> WG participants, please review and comment, and if there are no objections we can issue a WGLC.

No objection.

It could be useful to point out that the set of supported external 
address families depends on the internal address family. That is, 
sending the same request over IPv4 and IPv6 could yield different results.

Simon

---

From: Dan Wing <[email-masked]>
Date: Wed, 29 May 2013 10:33:24 -0700

On May 29, 2013, at 1:40 AM, Simon Perreault <[email-masked]> wrote:

> It could be useful to point out that the set of supported external address families depends on the internal address family. That is, sending the same request over IPv4 and IPv6 could yield different results.

Yes, something like:

  The external addresses supported on a network depend on the external connectivity and address family translators (e.g., NAT64) on the network.  After receiving an UNSUPP_FAMILY error, a PCP client SHOULD try sending a new PCP request from an interface with a different address family.

-d

---

From: Stuart Cheshire <[email-masked]>
Date: Wed, 29 May 2013 20:52:14 -0700

> It could be useful to point out that the set of supported external address families depends on the internal address family. That is, sending the same request over IPv4 and IPv6 could yield differen…

Good point. How about this updated text?

   Note that while the specific address placed in the Suggested External
   Address field is merely a suggestion that the PCP server is free to
   ignore, the address family is not.  If the suggested address *family*
   cannot be provided by this PCP server, then it MUST return a PCP
   error reply containing the UNSUPP_FAMILY error code.

   The ability to provide the requested external address family may
   depend on the client's internal address.  For example, a gateway that
   supports traditional NAT44, and native IPv6, but not NAT64, is able
   to provide mappings from an internal IPv4 address to an external IPv4
   address, and mappings from an internal IPv6 address to an external
   IPv6 address, but not mappings from an internal IPv6 address to an
   external IPv4 address.  When such a gateway receives a request to map
   an internal IPv4 address to an external IPv4 address it MUST return
   an external IPv4 address, if available, but when it receives a
   request to map an internal IPv6 address to an external IPv4 address
   it MUST return an UNSUPP_FAMILY error.

Stuart Cheshire

---

From: <[email-masked]>
Date: Thu, 30 May 2013 08:32:06 +0200

Hi Stuart, all,

The behavior you are proposing here recalls me what we had in earlier versions of the pcp specification (version 00 to version 03, PINxy OpCodes) and (version 04 to version 13, MAP4 and MAP6 OpCodes). The consensus of the wg was to remove that design. 

This particular text in your proposal:

>   ignore, the address family is not.  

is clearly a revival of the MAPx/PEERx opcides.

Cheers,
Med

>-----Message d'origine-----
>De : [email-masked] [mailto:[email-masked]] De la part de
>Stuart Cheshire
>Envoyé : jeudi 30 mai 2013 05:52
>À : Simon Perreault
>Cc : [email-masked]
>Objet : Re: [pcp] UNSUPP_FAMILY error code
>
>address families depends on the internal address family. That is, sending
>the same request over IPv4 and IPv6 could yield different results.
>

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 11:53:18 +0200

> is clearly a revival of the MAPx/PEERx opcides.

This is not quite right. MAPx/PEERx were transformed into MAP/PEER 
precisely because the external address type, which was encoded in the 
opcode, is now encoded in the suggested external address field. The 
semantics have not changed. Only the syntax has.

Simon
-- 
DTN made easy, lean, and smart --> http://postellation.viagenie.ca
NAT64/DNS64 open-source        --> http://ecdysis.viagenie.ca
STUN/TURN server               --> http://numb.viagenie.ca

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 11:58:36 +0200

>     error reply containing the UNSUPP_FAMILY error code.

This is important. And I think it is right. I cannot imagine a use case 
where a client doesn't know or care about the external address family.

>     depend on the client's internal address.

internal address *family*.

>     For example, a gateway that

s/MUST/MAY/

Quotas, local policy, the weather, etc. may all impact the server's 
willingness to serve that request.

>     it MUST return an UNSUPP_FAMILY error.

Good.

Simon

---

From: <[email-masked]>
Date: Thu, 30 May 2013 13:30:13 +0200

Simon, 

I disagree.

The client does not know in advance the capabilities of the PCP-controlled devices. A client does not know what type(s) of address(es) it will need to establish communications with remotes peers (e.g., application using referrals). A client may gather all external addresses/ports from pcp servers it is aware of, and signal them to remote peers.

Unlike MAP4/MAP6, the server receiving a MAP request is not obliged to return an IP address following the indication included in the suggested external IP address field. It will try to best accommodate it, but if not, it would be fine if it returns another AF address; then it is up to the client to make use of it or not. 

In another words: we should not use Suggested IP Address as PREFER_AF option ;-)

Cheers,
Med

>De : Simon Perreault [mailto:[email-masked]]
>Envoyé : jeudi 30 mai 2013 11:53
>À : BOUCADAIR Mohamed OLNC/OLN
>Cc : Stuart Cheshire; [email-masked]
>> The behavior you are proposing here recalls me what we had in earlier
>versions of the pcp specification (version 00 to version 03, PINxy OpCodes)
>and (version 04 to version 13, MAP4 and MAP6 OpCodes). The consensus of the
>wg was to remove that design.
>>

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 13:54:15 +0200

Le 2013-05-30 13:30, [email-masked] a écrit :
> The client does not know in advance the capabilities of the
> PCP-controlled devices. A client does not know what type(s) of
> address(es) it will need to establish communications with remotes
> peers (e.g., application using referrals). A client may gather all
> external addresses/ports from pcp servers it is aware of, and signal
> them to remote peers.

So then it needs to send two MAP requests, one for an IPv4 external 
address and another for an IPv6 external address. Just sending one 
request and letting the server decide the external address family will 
yield one mapping of one family, not all of them.

> Unlike MAP4/MAP6, the server receiving a MAP request is not obliged
> to return an IP address following the indication included in the
> suggested external IP address field. It will try to best accommodate
> it, but if not, it would be fine if it returns another AF address;
> then it is up to the client to make use of it or not.

What use case do you have in mind? I can't understand why you would want 
the server to behave this way.

Simon

---

From: <[email-masked]>
Date: Thu, 30 May 2013 13:59:59 +0200

Re-,

Please see inline.

Cheers,
Med

>De : [email-masked] [mailto:[email-masked]] De la part de Simon
>Perreault
>Envoyé : jeudi 30 mai 2013 11:59
>À : Stuart Cheshire
>Cc : [email-masked]

[Med] That's not the question. The question is how an application can maximize the chances to establish successful sessions. Take the example of a WebRTC agent behind a NAT64 and NPTv6: should this agent request only an IPv6 address because it is IPv6-enabled? For me it should not. It should contact PCP-enabled devices it is aware of and retrieve the external addresses managed by those devices (e.g., an IPv4 address form a NAT64, an IPv6 address for a NPTv6); all these external addresses will be signaled to remote WebRTC agents. ALL @ses should be signaled because a local agent does not know in advance the capabilities of the remote webRTC agent.

So repeating myself:
* the client can indicate a preferred AF 
* the server can accept to honor it or not the preference. If the preferred AF is not available, the server can return another address of distinct AF.
* the client is free to make use of the information returned by the server

No need for defining a new error code because the client is able to make a local decision.

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 14:10:58 +0200

Le 2013-05-30 13:59, [email-masked] a écrit :
> * the server can accept to honor it or not the preference. If the preferred
> AF is not available, the server can return another address of
> distinct AF.

So a client that asks for two mappings, one IPv6 and one IPv4, and gets, 
for example, two IPv4 mappings and would deduce that IPv6 is not 
supported. It would then delete one mapping and just go on its way. 
Hmmm... That would work I suppose, but there's a inefficiency: a useless 
mapping was created, and the client has to delete it. It seems to me 
that an error code would be cleaner.

Simon

---

From: <[email-masked]>
Date: Thu, 30 May 2013 14:29:52 +0200

Re-,

Please see inline.

>Envoyé : jeudi 30 mai 2013 14:11
>for example, two IPv4 mappings
[Med] If the same internal port is indicated in both requests, only one mapping will be created not two.

 and would deduce that IPv6 is not
>supported.
[Med] Yes.

 It would then delete one mapping and just go on its way.
[Med] If two internal ports are indicated in the two requests, then yes.

>that an error code would be cleaner.

[Med] The cleaner way IMHO is to extend pcp with the capability to discover PCP server capabilities.

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 14:36:05 +0200

> [Med] If the same internal port is indicated in both requests, only one mapping will be created not two.

Right, which is why the client will *not* use the same internal 
address+port for the two mappings. In your use case, the client *wants* 
to get two mappings, one IPv4 and the other IPv6, so that it can 
maximize its reachability.

Simon

---

From: <[email-masked]>
Date: Thu, 30 May 2013 14:59:09 +0200

Why?
The client can use the same internal port for both MAP requests: the only diff is the AF zero address indicated in the suggested external address.
The server will return the same result for both requests if it does support only one AF.
No error message. No port quota consumption.

>Envoyé : jeudi 30 mai 2013 14:36

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 15:02:39 +0200

> The server will return the same result for both requests if it does support only one AF.

What if the server supports two AFs? That's the whole point...

Simon

---

From: <[email-masked]>
Date: Thu, 30 May 2013 15:11:03 +0200

I guess it will honor the suggested AF in each requests; unless it can't (e.g., port quota). 

>Envoyé : jeudi 30 mai 2013 15:03
>> The client can use the same internal port for both MAP requests: the only
>diff is the AF zero address indicated in the suggested external address.

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 15:42:18 +0200

> I guess it will honor the suggested AF in each requests; unless it can't (e.g., port quota).

Exactly.

Please allow me to summarize what we have agreed on so far.

We have a client that wants to maximize its reachability. It requests 
two mappings, one with suggested external AF IPv4 and the other IPv6. 
The requests will have different internal port so that they don't 
conflict. The client will advertise whatever it gets (could be zero, 
one, or two external AFs) to its peer.

Now we have two server behaviour proposals. To requests containing an 
unsupported suggested external AF, the server will either...

a) reply with UNSUPP_FAMILY,

or

b) allocate a mapping with an external AF that it does support.

Both proposals make it possible for the client to discover the set of 
supported external AFs. However, when an AF is not supported b) creates 
a useless mapping that needs to be deleted by the client.

Is this correct?

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 13:52:09 +0000

On 5/30/13 10:42 AM, "Simon Perreault" <[email-masked]> wrote:

>conflict. 

Why they can not conflict? There are two different address families.

>The client will advertise whatever it gets (could be zero,

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 15:55:43 +0200

> Why they can not conflict? There are two different address families.

Consider an IPv4-only client. It will send two requests to the PCP 
server, over IPv4, trying to get an IPv4 and an IPv6 external addresses. 
The internal IPv4 port must be different for the two requets otherwise 
there will be a conflict, even if the external AFs are different.

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 14:01:28 +0000

Sorry, I'm probably missing something. Let's suppose the IPv4-ony client
gets two external IP:ports, one IPv4 and another IPv6. When the source
IPv6 incoming connection gets translated to an IPv4 source address, if it
does not conflict with any other IPv4 native session, there is no
conflict, right? From the client perspective it is just a bunch of
incoming IPv4 connections.

---

From: <[email-masked]>
Date: Thu, 30 May 2013 16:04:25 +0200

Agree modulo the following minor precision: 
* two mappings are created only if distinct internal ports are indicated in both MAP requests. 

If pcp supports capability discovery: 
* The extra mapping can be avoided 
* useless MAP requests can be avoided too: only one request will be sent to the server instead of two requests.

Now, where should we put the bar?

(1) no useless MAP requests?
(2) no extra mapping at all?
(3) combination of (1) and (3)

Cheers,
Med

>Envoyé : jeudi 30 mai 2013 15:42

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:10:57 +0200

> incoming IPv4 connections.

Assuming the 44 and 46 mappings have the same internal port... (which I 
assert is impossible but let's try it anyway)

There will be a conflict when the internal host sends a packet to the 
outside from this internal port. Will NAT44 or NAT46 be applied to the 
mapping? A mapping being endpoint-independent by PCP MAP definition, we 
can't use the destination to answer that question.

Simon

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:13:42 +0200

> * two mappings are created only if distinct internal ports are indicated in both MAP requests.

Yes.

But why would a client send different requests with the same internal port?

> (3) combination of (1) and (3)

If you just replace the useless MAP request with a capability discovery 
request, you haven't gained anything efficiency-wise but you have 
increased complexity a lot.

Simon

---

From: Ted Lemon <[email-masked]>
Date: Thu, 30 May 2013 14:14:29 +0000

On May 30, 2013, at 9:55 AM, Simon Perreault <[email-masked]> wrote:
> Consider an IPv4-only client. It will send two requests to the PCP server, over IPv4, trying to get an IPv4 and an IPv6 external addresses. The internal IPv4 port must be different for the two requets otherwise there will be a conflict, even if the external AFs are different.

In this particular use case packets arriving via IPv4 and IPv6 would both be delivered to the same port, which seems okay, not a conflict.

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:15:59 +0200

> In this particular use case packets arriving via IPv4 and IPv6 would both be delivered to the same port, which seems okay, not a conflict.

See my reply to Reinaldo. The conflict is in the other direction.

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 14:15:54 +0000

On 5/30/13 11:10 AM, "Simon Perreault" <[email-masked]> wrote:

>outside from this internal port.

[RP] The outside addresses will all be v4 address since incoming packets
will go through the NAT. V6 packets will become IPv4 packets. As long as
the source IP:port of these incoming packets do not conflict, the answer,
which will be directed to those will not conflict either.

> Will NAT44 or NAT46 be applied to the

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:18:34 +0200

> which will be directed to those will not conflict either.

Sorry, I can't make sense of this.

I think you misread. I'm talking about internal --> external packet flow.

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 14:29:49 +0000

Okay, client creates to MAP mappings

(1) 2000::1, 10000 -> 100.0.0.2:80

(2) 200.0.0.2, 10000 -> 100.0.0.2:80

Connections are started from the outside (this is a MAP mapping). A packet
from 2001::1 to 2000::1 will get translated to

10.0.0.2: 3000 (or some other IP address:port depending on translation
algorithm) -> 100.0.0.2:80

Host at 100:0.0.2:80 will send reply packets to 10.0.0.2:3000 which will
be translated to IPv6.

Public Internet Ipv4 hosts will send packets to 100.0.0.2:80 and its
source will not get translated, replies will be sent to the source address
of the packet.

Is that what you mean?

---

From: <[email-masked]>
Date: Thu, 30 May 2013 16:32:20 +0200

I won't discuss the capability complexity for now because I'd like we focus on the optimization we want to achieve, whether the use case is a valid one or not, whether a failure is experienced, etc.

>Envoyé : jeudi 30 mai 2013 16:14

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:35:16 +0200

> Okay, client creates to MAP mappings

(assuming left = external and right = internal)

> Connections are started from the outside (this is a MAP mapping).

Stop right here. A mapping created with MAP also applies to connections 
initiated from the inside. That's precisely why there's a conflict in 
the internal --> external direction.

Above, the arrows should be bidirectional.

> A packet

No. I'm not talking about reply packets, which could work if the NAT 
tracks sessions. I'm talking about packets not associated with an 
existing session, sent by the internal host to the outside, with 
100.0.0.2:80 as source. Where should those go? If the NAT doesn't track 
sessions, reply packet sourced from 100.0.0.2:80 are also concerned.

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 14:43:21 +0000

On 5/30/13 11:35 AM, "Simon Perreault" <[email-masked]> wrote:

>100.0.0.2:80 as source. Where should those go?

If destination is within the pool controlled by the NAT46, it goes there,
otherwise it goes through NAT44.

>If the NAT doesn't track

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 16:47:02 +0200

> otherwise it goes through NAT44.

No. This is what I meant by "A mapping being endpoint-independent by PCP 
MAP definition, we can't use the destination to answer that question."

    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.

Simon

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Thu, 30 May 2013 14:51:46 +0000

>MAP definition, we can't use the destination to answer that question."

There are two NATs, two mappings. EIM applies to the same NAT.

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 17:05:04 +0200

> There are two NATs, two mappings. EIM applies to the same NAT.

I'm not too sure what you mean by "two NATs". In our examples so far 
there is a single PCP-controlled device that performs multiple NATxy 
functions. In this particular one, the PCP-controlled device does NAT44 
and NAT46. It MUST NOT simultaneously map the same internal IPv4 port to 
an IPv4 and an IPv6 external ports. Otherwise, the PCP client has no 
idea where its packets will go.

In other words, going back to the numerical example:

(1) 2000::1, 10000 <-> 100.0.0.2:80
(2) 200.0.0.2, 10000 <-> 100.0.0.2:80

Those two mappings, having been handed out by the PCP server to the PCP 
client and therefore needing to obey the PCP protocol definition of what 
a mapping is, impose conflicting requirements on the PCP-controlled device:

(1) Packets sourced from 100.0.0.2:80 MUST be translated to 2000::1, 10000.
(2) Packets sourced from 100.0.0.2:80 MUST be translated to 200.0.0.2, 
10000.

There is no way the PCP-controlled device can simultaneously obey those 
two requirements.

Now, all this doesn't apply if there are two PCP-controlled devices.

Simon

---

From: Stuart Cheshire <[email-masked]>
Date: Thu, 30 May 2013 08:43:35 -0700

> In another words: we should not use Suggested IP Address as PREFER_AF option ;-)

RFC 6887 states that the client uses the appropriate all-zeros address in the Suggested External Address field to control what family of external address it gets:

   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.

and

   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.

We really need WG consensus on whether the external address family is a firm requirement or merely a hint, so client writers know what to expect.

I don't see any benefit in requiring client writers to handle the client unexpectedly getting an address family it doesn't want.

That's also a code path that's likely to be poorly tested. I can imagine lots of IPv4-only devices being tested with IPv4-only NATs and shipped today, and then, a couple of years from now, crashing the first time they unexpectedly get handed an IPv6 address.

We'll be shooting ourselves in the foot if we choose that path.

Stuart Cheshire

---

From: Stuart Cheshire <[email-masked]>
Date: Thu, 30 May 2013 08:54:09 -0700

On 30 May 2013, at 7:10 AM, Simon Perreault <[email-masked]> wrote:

> Assuming the 44 and 46 mappings have the same internal port... (which I assert is impossible but let's try it anyway)
> 
> There will be a conflict when the internal host sends a packet to the outside from this internal port. Will NAT44 or NAT46 be applied to the mapping? A mapping being endpoint-independent by PCP MAP definition, we can't use the destination to answer that question.

I see your concern here, but I think you're mistaken.

Example configuration:

PCP Client listens on 2620:...:403e port 80
PCP Client issues MAP request for external IPv6;
 gateway creates firewall mapping and returns 2620:...:403e port 80
PCP Client issues MAP request for external IPv4;
 gateway creates NAT mapping and returns 173.164.252.149 port 49152

Now, consider two scenarios:
1. Inbound IPv6 packet arrives from A:B, addressed to 2620:...:403e port 80
   Gateway delivers packet unmodified to internal host
   Internal host replies
   Gateway delivers reply unmodified to remote peer

2. Inbound IPv4 packet arrives from A:B, addressed to 173.164.252.149 port 49152
   NAT64 has to translate IPv4 packet to IPv6
   - IPv6 destination address becomes 2620:...:403e port 80
   - NAT64 has to make up a new source address, e.g. 64:ff9b::...
   Gateway delivers fabricated IPv6 packet to internal host
   Internal host replies
   Gateway recognizes that destination address 64:ff9b::... is a fabricated NAT64 address
   Gateway translates IPv6 packet back to IPv4
   Gateway delivers fabricated IPv4 reply to remote peer

So, a given internal address and port can have two external address families, because the destination address on the outbound packet tells the gateway what handling is required.

Superficially this may seem like it violates the requirement that a NAT gateway have endpoint address independent mappings, but I think in reality there's no such thing as endpoint address *family* independent mappings. We can require a NAT gateway to use the same external IPv4 address regardless of which remote IPv4 peer it is talking to, but there's no way to require it to use a single external address for both remote IPv4 peers and remote IPv6 peers. It simply has to use an external IPv4 address for remote IPv4 peers and an external IPv6 address for remote IPv6 peers.

Stuart Cheshire

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 17:57:08 +0200

+1

+1

+1

FWIW, the server implementation I helped create does not fallback on a 
different address type. To be honest, it never crossed my mind that this 
could be possible.

Simon

---

From: Stuart Cheshire <[email-masked]>
Date: Thu, 30 May 2013 09:01:45 -0700

On 30 May 2013, at 7:13 AM, Simon Perreault <[email-masked]> wrote:

> If you just replace the useless MAP request with a capability discovery request, you haven't gained anything efficiency-wise but you have increased complexity a lot.

I agree.

In general, the two-step process "Can you do X? Okay then, please do X" can often be collapsed into an atomic one-step "Please do X or give me an error code if not".

And since a robust client needs to handle the two-step scenario where the server says yes to step one and then fails step two, step one becomes redundant and can be skipped, which takes us back to the previously-described atomic one-step operation.

Stuart Cheshire

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 18:25:56 +0200

> So, a given internal address and port can have two external address families, because the destination address on the outbound packet tells the gateway what handling is required.

I appreciate you taking the time to craft a detailed example.

That example is very special because it uses the well-known NAT64 
prefix. Using the well-known NAT64 prefix means that we can reasonably 
expect the PCP client to figure out that IPv6 packets it sends to that 
prefix will preferably match the NAT64 mapping, even though they could 
also match the NAT66 mapping.

But we can't rely on the well-known NAT64 prefix being always present to 
disambiguate.

- What would happen if a network-specific NAT64 prefix is used? How can 
the PCP client know what will happen (NAT64 or NAT66) to packets it 
sends if it doesn't know about that prefix?

- What would happen in the NAT44 + NAT46 example we've been discussing? 
There is no well-known prefix to help disambiguate.

Note that I'm not considering only replies to connections initiated from 
the outside. I'm also interested in connections initiated from the 
inside, which MAP also covers.

I see that using PCP to run a dual-stack server is a good use case, but 
MAP doesn't enable it because it is symmetric. To do that we would need 
a kind of mapping that only applies to connections initiated from the 
outside.

> Superficially this may seem like it violates the requirement that a NAT gateway have endpoint address independent mappings, but I think in reality there's no such thing as endpoint address *family*…

I suppose I could be convinced that this is true. But it still doesn't 
change the fact that the client in general has no way of knowing which 
of two matching mappings will apply. That's the problem.

Simon

---

From: Stuart Cheshire <[email-masked]>
Date: Thu, 30 May 2013 09:30:18 -0700

On 30 May 2013, at 9:25, Simon Perreault wrote:

> - What would happen if a network-specific NAT64 prefix is used? How can the PCP client know what will happen (NAT64 or NAT66) to packets it sends if it doesn't know about that prefix?
> 
> - What would happen in the NAT44 + NAT46 example we've been discussing? There is no well-known prefix to help disambiguate.
> 
> Note that I'm not considering only replies to connections initiated from the outside. I'm also interested in connections initiated from the inside, which MAP also covers.

I agree that outbound connections (and packets) need to work.

I don't think the client needs to know what will happen. But the gateway does know. If the destination is a "real" address then the packet is sent to that address. If the destination address belongs to the address-family-translating gateway's address pool, then the gateway MUST translate it to the other address family, because the destination is not a "real" address and will go nowhere useful if sent as-is.

Stuart Cheshire

---

From: Simon Perreault <[email-masked]>
Date: Thu, 30 May 2013 19:05:36 +0200

> I don't think the client needs to know what will happen. But the gateway does know. If the destination is a "real" address then the packet is sent to that address. If the destination address belong…

Hmmm... I started replying to this with a counter-example where the 
client *needs* to know what will happen, but I could not make it work. 
What you're saying seems correct. I need to sleep on this.

Now, the second and somewhat less important reason that mappings cannot 
share the same internal port is that, as the RFC is currently written, 
two matchings do not involve the external address.

a) Servers match requests against existing mappings on the internal 
address + port. This happens before the suggested external address field 
is inspected. Section "11.3. Processing a MAP Request":

    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.

    [...]

    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:

    [...]

    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.

b) Clients match responses with requests on the internal address + port. 
Section "11.4. Processing a MAP Response":

    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.

Could these two things be updated in your draft? We would need to say 
basically that the suggested external address family is also part of the 
match tuple in both cases. There would be two consequences to that:

- The client would now be expected to set the suggested external address 
family correctly in refresh requests.

- The server could not reply with an external address family different 
from the one contained in the request.

Thanks all for the frenetic exchange!

Simon