Subject: [P2PSIP] My notes on draft-matthews-p2psip-dsip-nat-traversal-00

From: Spencer Dawkins <[email-masked]>
Date: Tue, 06 Mar 2007 20:05:21 -0600

Hi, Eric/Philip/David/Bruce,

This draft is really pretty clear (note that I haven't read the dSIP core 
spec yet - I'm working my way that direction). Nice work.

I have some questions and comments, of course.

Thanks,

Spencer

1.  Introduction

   This approach works well if a large percentage of peers are not
   behind NATs.  However, in some of the use-cases [P2PSIP-Use-Cases]
   identified for P2PSIP, the percentage of peers not behind NATs may be
   very small.  For example, a P2PSIP system in a "Managed, Private

Spencer (nit) - "very small - in some use-cases, all the peers are behind 
NATs". We could discuss the shape of the decay curve that shows how well 
superpeers work as the percentage of peers behind a NAT rises, but the 
critical point is that if you have all your peers behind NATs, you fail.

Spencer (nit) - this text would be easier to understand if it was stated 
with less negation - "if all, or even most, peers have public addresses", 
"the percentage of peers behind NATs may be very large", and so forth.

Spencer - I find myself wishing that we had agreed-upon Use Cases, of 
course... that's not for this draft to fix, but it is for the working group 
to think about.

   Network Environment" may consist of a number of peers, each one of
   which is behind its own NAT.  In these cases, the ordinary peer /
   super peer approach scales poorly or breaks down entirely.

2.2.  ICE

   ICE is an especially attractive technique because it does not require
   the configuration of network devices and allows end-to-end encryption
   to be used.  ICE has the added benefit of working in complex network
   topologies that may include multiple NATs.

Spencer: this is "multiple NATs between two endpoints", isn't it?

   ICE-enabled peers collect a number of addresses that might be useful
   for communicating with other peers.  These addresses, referred to as
   candidates, commonly include the address of the peer's network
   interface as well as the publicly reachable address of the NAT the
   peer is behind (discovered via STUN [STUN-bis]).  These candidates
   are exchanged with remote peers via an existing communication
   channel.  Each peer then combines its own candidates with the remote
   candidates to create an ordered list of candidate pairs.  The pairs
   are then tested in order until a working network path is discovered.

2.3.  Connection Table

   In addition to the routing table entries required by the DHT
   algorithm, the connection table described in [dSIP-Base] contains
   additional connections.  These additional connections arise because a
   peer has connections that it originates to other peers (in its

Spencer: this is somewhat confusing - the routing table connections aren't 
"additional" connections, are they? Suggest "contains additional 
connections, which arise because a peer also has connections that other 
peers originate to it..."?

   routing table), connections that other peers originate to it (in
   their routing table), and temporarily connections made to perform
   resource registrations and queries.  Since connections are bi-
   directional, we do not distinguish between these two types of
   connections when routing requests.  For example, Chord specifies that
   each peer stores routing table entries to other peers in the first
   half of the ring starting from itself [dSIP-Chord].  In practice,
   however, the connection table will provide connections to peers
   distributed across the entire ring.  Keep-alive traffic must be sent
   on all the entries in the connection table to ensure that NATs
   between the peers will not discard the overlay traffic.

2.4.1.  Iterative Routing

   As mentioned above, ICE requires an existing (usually indirect)
   communication channel to exchange candidate addresses and establish a
   new (direct) channel.  In order for peer X to successfully transmit a
   SIP request to peer V, it must enlist the help of peer U (which has
   established dSIP connections to both X and V).  For this to work,
   peer U must proxy the INVITE for the new dSIP connection on to peer
   V. Peer U must not respond to the INVITE with a 302 as it did for the
   original SIP request.  Therefore, dSIP connection establishment
   dictates that even if the overlay is using iterative routing for
   requests, it must support two-hop proxying (recursive routing) for
   INVITEs that set up dSIP connections.  Assuming that U is willing to
   proxy the INVITE, X and V can perform ICE connectivity checks to

Spencer: I'm struggling a little with the notion that peers proxying INVITEs 
for another peer with credentials to join the overlay might be optional 
here... do we need that much flexibility?

   create a new dSIP connection.  Peer X is then free to use the new
   dSIP connection to deliver its query to peer V. This entire process
   can then repeat until a dSIP connection has been established to the
   target of the request.  Clearly the efficiency and effectiveness of
   the iterative routing technique are greatly affected by the presence
   of NATs.

2.4.3.  Relative Costs

   Because iterative and recursive routing both have advantages in
   different situations, and because in a heavily-NATed network, even
   when using iterative routing a significant amount of two-hop
   recursive routing is needed for each new dSIP connection, it is
   possible for both techniques to be used within the same operation to
   balance the costs and benefits of the two techniques.

Spencer: we almost certainly have an opportunity for simulation here... :-)

3.  Establishing and Maintaining dSIP Connections

   The details of this procedure are almost identical to the details of
   the procedure for setting of a control connection between a joining
   peer and an admitting peer specified in [Bootstrap].  Rather than
   repeating that procedure, we simply describe the necessary
   modifications.

Spencer: does the following paragraph repeat the unmodified procedure? :-) 
The second paragraph down clearly points out a modification ("except that").

   Peer X begins by constructing a SIP INVITE message.  The To: header
   is set to the URI of peer Y, and the From: and Contact: headers are
   set to the URI of peer X. Both URIs MUST be constructed according to
   the rules of [dSIP-Base] and include the "peerid" parameter.

   The SDP offer and answer are constructed as specified in section 6.4
   of [Bootstrap], except that, in the "m" line, the "media" parameter
   is set to "application" and the "fmt" parameter set to "sip".  This
   specifies that the Peer Protocol for the new connection will be SIP.

   Keep-alives must be run on the control connection to maintain it in
   the presence of NATs.  To do this, control connections SHOULD use the

Spencer: is this "SHOULD, unless you're sure there is no NAT on the control 
connection path"? ("Why not MUST?")

   STUN Binding Indication method described in ICE [ICE].  These
   procedures require STUN [STUN-bis] and SIP [RFC3261] to be
   multiplexed on the same connection: at the far end, the two types of
   packets can be distinguished because the STUN packets contain the
   magic cookie 0x2112A442, and these characters cannot occur in a SIP
   packet at this location.

   If the two peers at each end of a connection can somehow learn that
   there are no NATs between them, then the keep-alives MAY be run at a

Spencer: Why run them at all? Is this dealing with other middleboxes that 
may ALSO express opinions about inactive connection cleanup? Or something 
else? It would be nice to say why.

   rate lower than that recommended in [ICE].  The procedures for making
   that determination are not specified here.

4.2.1.  Forming and Sending the Request

   Peer X SHOULD indicate the requested routing method by adding either
   "proxy" (for recursive routing) or "redirect" (for iterative routing)
   to a Request-Disposition header [RFC3841] in the request.

Spencer: is this "SHOULD, unless the peer is doing direct routing"? Also... 
in RFC 3841 Section 7.1, Proxies SHOULD route based on "Request-Disposition" 
IF the proxy is owner of the domain in the Request URI, and unless policy 
dictates otherwise. Do we need any additional guidance for 
Request-Disposition processing in P2PSIP? 4.2.1 and 4.2.2 seem to elevate 
this to MUST, if I understand correctly - might want to say this explicitly.

4.2.2.  Handling the Request at a Receiving Peer

   If no handling is specified, the handling of the request is
   undefined.

Spencer: umm, if I'm reading this correctly, this case happens when you do 
direct routing to the wrong peer? How did we get here? But it would be nice 
to provide a defined response here, because debugging undefined behavior in 
this case, in a P2PSIP overlay, does not sound like fun.

   The handling of a request addressed to peer U follows normal SIP
   processing rules [RFC3261].  In particular, any response is routed
   back along the path of the request.

Spencer: perhaps "along the path of the request, since peers Record-Route 
the dialog"?

5.  Examples

   In this section, we give three examples that illustrate the
   procedures defined above.

Spencer: I was a little confused why there is not a fourth example (setting 
up connections using iterative routing), just for completeness... of course, 
there was a 00 cutoff date :-)

5.1.  Routing a REGISTER Request using Recursive Routing

   This first example shows the recursive routing of a SIP request
   message.  In this particular case, the request is a REGISTER message.

Spencer: this section title might be better as "Routing a SIP Request using 
Recursive Routing" - the first sentence gives the scope correctly, but the 
title seems to send the wrong signal ("REGISTER is a special case").

   In the figure, "REGISTER(To:M,R-D:proxy)" indicates a REGISTER
   message with a To header containing "M" and a Request-Disposition

Spencer: I'm probably stupid, but this would have been clearer as 
"Request-Disposition (R-D) header containing "proxy""... no need to expand 
this more than once, but it took longer than it should have to decode the 
REGISTER :-)

   header containing "proxy".  Not shown in the figure is the adding of
   Record-Route headers by peers U and V as they proxy the request.

5.2.  Setting up a dSIP Connection using Recursive Routing

   To compress the example, we show final BYE transaction with a single
   arrow labeled "BYE/200".

Spencer: perhaps the arrow could be bidirectional? I'm not sure this is 
worth saving three lines in the example, though... since it takes three 
lines to explain it :-)

     |                      |                  |                      |
     |                      |                  |         BYE / 200 OK |
     |<---------------------|<-----------------|<---------------------|
     |                      |                  |                      |

   Figure 1: Setting Up a dSIP Connection using Recursive Routing

5.3.  Routing a REGISTER Request using Iterative Routing

Spencer: again, this is "Routing a SIP Request using Iterative Routing", 
isn't it?

   Finally, peer X tears down it two temporary dSIP connections to Y and

Spencer (nit): "tears down it two" is garbled. "tears down its two"? But 
you'll know what you meant.

   V (in the reverse order that they were set up).

8.  IANA Considerations

   IANA considerations will be discussed in a future version of this
   document.

Spencer: are you anticipating any IANA work? That might be good to know... 

_______________________________________________
P2PSIP mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/p2psip

---

From: "Bruce Lowekamp" <[email-masked]>
Date: Wed, 7 Mar 2007 11:28:52 -0500

Spencer,

Thanks for your thorough reading and comments.  I wanted to respond to
a few questions, but obviously we'll try to address the others in a
future revision, as well.

> "the percentage of peers behind NATs may be very large", and so forth.

We debated about providing more detail here.  The techniques discussed
will actually work even when most/all of the peers are behind NATs, as
long as they are friendly NATs (rfc4787 endpoint independent mapping,
at least, and with endpoint independent filtering, it's almost not a
problem).  So the real issue becomes determining not only what
fraction are behind NATs but what fraction are behind different types
of NATs.  That probably needs to be done, but I think it will be out
of the main text of this draft just because of the complexity.  There
are also some documents talking about this same issue in the behave
wg.  Basically, we just glossed over the issue because it seemed like
it would make the draft more complicated to read.

> Spencer: this is "multiple NATs between two endpoints", isn't it?

yes.   specifically, it works even when a single peer is "doubly
natted" from the perspective of another peer.

> peers originate to it..."?

In the terminology we are trying to use with dSIP, the "routing table"
is the set of connections that the dht routing algorithm requires to
work.  That is the minimum set that every peer maintains that as a set
regardless of whether they're doing NAT traversal, TCP, etc.   The
"connection table" is a superset of that, because it also contains
other connections the peer happens to make for other reasons
(primarily receiving connections initiated by other peers and
connections used for resource queries/updates).  Without NATs and
using UDP, a peer doesn't necessarily have to remember that is has
other connections.

> here... do we need that much flexibility?

In the absence of NATs you don't need any proxying.  In the real
world, as soon as you have a nat with any sort of dependent behavior,
you need it.  The reason for not requiring it is a desire to support
the protocol in a totally internet-friendly state where there is no
way to ask another peer to do work on your behave other than storing
information.  You may be right that making one-hop proxying optional
is adding more complexity than it's worth, but that's the motivation.

> connection path"? ("Why not MUST?")

Good question.  Probably the right answer is they MUST run keep-alive,
but the exact form (STUN or refreshing the REGISTER) is somewhat more
of an open question.

> else? It would be nice to say why.

Yeah, seem to be a lot of non-NAT middleboxes that helpfully protect
your computer these days.

> this case, in a P2PSIP overlay, does not sound like fun.

I think that was intended to be if a message arrives without a
request-disposition, but you're right that a bit of cleanup and checks
with the other rfcs needs to be done.

> Spencer: are you anticipating any IANA work? That might be good to know...

I think we're hoping not to define any new methods in this draft.

Bruce

---

From: Philip Matthews <[email-masked]>
Date: Wed, 7 Mar 2007 12:58:52 -0500

I would just like to add a few things to what Bruce said.
See inline.

- Philip

> it would make the draft more complicated to read.

The mechanism described in the draft uses ICE to establish connections.
Describing the situations where ICE works
and does not work is complex, as anyone who was in the MMUSIC meeting
in Montreal last summer can attest. It depends on many things, include
network topology, the location and behaviors of the intervening NATs,
  the location of the STUN servers used, and whether or not
the STUN servers support the relay function. Moreover, starting with  
ICE-13,
there is now a mechanism to extend ICE, so people can add features to
ICE to make it work in situations where it did not work before.

Moreover, it turns out that the mechanism described is robust against  
ICE failing
to  establish a connection from time to time. In other words, if some  
of the
connections fail to be establish, the mechanism will still work and  
will simply
give reduced performance.

However, there are some "critical" connections that must work. In  
particular,
if a peer does not have a connection to its successor, then some lookup
and routing operations will fail.  It may be possible to  change the  
mechanism
to be robust against even these failure, but we have not investigated  
this.

We need to investigate and document this behavior in more  detail.

> is adding more complexity than it's worth, but that's the motivation.

When writing the document, the idea that a few peers might refuse to do
either recursive or iterative routing came up.  By the time it did,  
we did
not have enough time to really investigate the consequences of this  
idea.
We THINK we can get away with SHOULDs rather than MUSTs in various
cases, but have not yet done a full investigation.

> with the other rfcs needs to be done.

This is another case of not fully understanding the consequences of
SHOULD or even MAY instead of MUST.
We understand what happens if a peer DOES add a Request-Disposition  
header
and the proxy DOES do what the peer requested, but we don't understand
what happens if one of them does not. We could mandate this behavior,
but Request-Disposition is supposed to be just that: a request.

In other words, we need to think more about corner cases.

> I think we're hoping not to define any new methods in this draft.

The draft defines a way to use SDP to signal a SIP connection.
This will eventually require IANA action.
However, I suspect that this type of change is out-of-scope for P2PSIP,
and we will need to write a separate document for this work and push
it through another working group (MMUSIC?).

- Philip

---

From: Philip Matthews <[email-masked]>
Date: Wed, 7 Mar 2007 14:41:40 -0500

In addition to my previous reply that was tacked on to Bruce's reply,
here are replies to the remaining questions.

- Philip
On 6-Mar-07, at 21:05 , Spencer Dawkins wrote:

> This draft is really pretty clear (note that I haven't read the  
> dSIP core spec yet - I'm working my way that direction). Nice work.
>
> Spencer (nit) - "very small - in some use-cases, all the peers are  
> behind NATs". We could discuss the shape of the decay curve that  
> shows how well superpeers work as the percentage of peers behind a  
> NAT rises, but the critical point is that if you have all your  
> peers behind NATs, you fail.

Yes.

>
> Spencer (nit) - this text would be easier to understand if it was  
> stated with less negation - "if all, or even most, peers have  
> public addresses", "the percentage of peers behind NATs may be very  
> large", and so forth.
>
> Spencer - I find myself wishing that we had agreed-upon Use Cases,  
> of course... that's not for this draft to fix, but it is for the  
> working group to think about.

Totally agree. The lack of agreed on use-cases (or "usage scenarios",  
as I prefer to call them) is a major hinderance in our work. This  
came up many times over the last month or two in the work on the four  
documents that I am a co-author on.

> Spencer: this is "multiple NATs between two endpoints", isn't it?

It includes this case, but it also includes other cases, for example

			Internet
			    |
			   NAT
			    |
                      -----------------
                      |               |
                    Peer A           NAT
                                      |
                                    Peer B

> Spencer: this is somewhat confusing - the routing table connections  
> aren't "additional" connections, are they? Suggest "contains  
> additional connections, which arise because a peer also has  
> connections that other peers originate to it..."?
>
> Spencer: I'm struggling a little with the notion that peers  
> proxying INVITEs for another peer with credentials to join the  
> overlay might be optional here... do we need that much flexibility?
>

Yes. There has been some simulation already, but none directed  
towards this case.

> Spencer: does the following paragraph repeat the unmodified  
> procedure? :-) The second paragraph down clearly points out a  
> modification ("except that").

Note quite, since the bootstrap draft doesn't use the URI scheme of  
the dSIP draft.

Pointing at the Bootstrap draft is probably not the best way to organize
these documents. If the dSIP approach gets selected by the working  
group,
then some merging and re-organizing of  documents would  be highly  
desirable.
However, for various reasons, it seemed a bad idea to repeat much of  
the text
of the Bootstrap draft in this draft.

> Spencer: is this "SHOULD, unless you're sure there is no NAT on the  
> control connection path"? ("Why not MUST?")
>
> Spencer: Why run them at all? Is this dealing with other  
> middleboxes that may ALSO express opinions about inactive  
> connection cleanup? Or something else? It would be nice to say why.

Good question. We are still working out the details of the  
interaction between
the "expires" scheme in the base dSIP document  and the keep-alive  
mechanism.
> Spencer: is this "SHOULD, unless the peer is doing direct routing"?  
> Also... in RFC 3841 Section 7.1, Proxies SHOULD route based on  
> "Request-Disposition" IF the proxy is owner of the domain in the  
> Request URI, and unless policy dictates otherwise. Do we need any  
> additional guidance for Request-Disposition processing in P2PSIP?  
> 4.2.1 and 4.2.2 seem to elevate this to MUST, if I understand  
> correctly - might want to say this explicitly.

As I said in my previous message, we are still struggling with the  
degree
that things have to  be MUST vs SHOULD or even MAY.
Request-Disposition is supposed to indicate just a desire and not be  
binding
on the proxy, and this as an attempt to be consistent with that view,
but we haven't worked out the full implications of not including it
  or not following it yet.

> Spencer: umm, if I'm reading this correctly, this case happens when  
> you do direct routing to the wrong peer? How did we get here? But  
> it would be nice to provide a defined response here, because  
> debugging undefined behavior in this case, in a P2PSIP overlay,  
> does not sound like fun.
>
> Spencer: perhaps "along the path of the request, since peers Record- 
> Route the dialog"?

I believe that 3261 specifies that responses are ALWAYS routed back
along the path of the request, even if Record-Route is not specified.
Record-Route simply influences the path of subsequent requests in
the dialog.

> Spencer: I was a little confused why there is not a fourth example  
> (setting up connections using iterative routing), just for  
> completeness... of course, there was a 00 cutoff date :-)

Because it differed from the third example only
in the absence of the very last request/response exchange.

> Spencer: this section title might be better as "Routing a SIP  
> Request using Recursive Routing" - the first sentence gives the  
> scope correctly, but the title seems to send the wrong signal  
> ("REGISTER is a special case").

OK.

> "Request-Disposition (R-D) header containing "proxy""... no need to  
> expand this more than once, but it took longer than it should have  
> to decode the REGISTER :-)

OK

> Spencer: perhaps the arrow could be bidirectional? I'm not sure  
> this is worth saving three lines in the example, though... since it  
> takes three lines to explain it :-)

The arrow indicates the direction of the BYE message.
We introduce this notation here  because we use it in subsequent  
examples.
And, SIPPING should have a document on notational conventions to use
when indicating SIP call flows.

> Spencer: again, this is "Routing a SIP Request using Iterative  
> Routing", isn't it?

In general, yes, but the specific example uses REGISTER.

> Spencer (nit): "tears down it two" is garbled. "tears down its  
> two"? But you'll know what you meant.

Yup.