Re: [BEHAVE] (no subject)

ivan c <ivan@cacaoweb.org> Thu, 20 June 2013 18:26 UTC

Return-Path: <ivan@cacaoweb.org>
X-Original-To: behave@ietfa.amsl.com
Delivered-To: behave@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 00B3021F871D for <behave@ietfa.amsl.com>; Thu, 20 Jun 2013 11:26:17 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.547
X-Spam-Level:
X-Spam-Status: No, score=-2.547 tagged_above=-999 required=5 tests=[AWL=0.052, BAYES_00=-2.599]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Nx+eR2deJeT7 for <behave@ietfa.amsl.com>; Thu, 20 Jun 2013 11:26:11 -0700 (PDT)
Received: from mail.cacaoweb.org (mail.cacaoweb.org [46.105.102.78]) by ietfa.amsl.com (Postfix) with ESMTP id 71FCF21F99D1 for <behave@ietf.org>; Thu, 20 Jun 2013 11:26:11 -0700 (PDT)
Received: from www-data by mail.cacaoweb.org with local (Exim 4.72) (envelope-from <ivan@cacaoweb.org>) id 1UpjZX-0004eK-B2 for behave@ietf.org; Thu, 20 Jun 2013 20:27:03 +0200
To: Behave <behave@ietf.org>
X-PHP-Originating-Script: 0:func.inc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Date: Thu, 20 Jun 2013 20:27:03 +0200
From: ivan c <ivan@cacaoweb.org>
Organization: cacaoweb
In-Reply-To: <51C1681A.5030909@viagenie.ca>
References: <CB1B483277FEC94E9B58357040EE5D02325A6E93@xmb-rcd-x15.cisco.com> <2f7dce8264c8a9a72640629502a44295@cacaoweb.org> <51C1681A.5030909@viagenie.ca>
Message-ID: <f8741fad1af1cee094de9c59408b7425@cacaoweb.org>
X-Sender: ivan@cacaoweb.org
User-Agent: RoundCube Webmail/0.3.1
Subject: Re: [BEHAVE] (no subject)
X-BeenThere: behave@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
Reply-To: ivan@cacaoweb.org
List-Id: mailing list of BEHAVE IETF WG <behave.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/behave>, <mailto:behave-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/behave>
List-Post: <mailto:behave@ietf.org>
List-Help: <mailto:behave-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/behave>, <mailto:behave-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 20 Jun 2013 18:26:17 -0000

On Wed, 19 Jun 2013 10:13:14 +0200, Simon Perreault
<simon.perreault@viagenie.ca> wrote:
> Le 2013-06-18 22:33, ivan c a écrit :
>> The discussion here is not about UDP. UDP port preservation should
>> generally not be implemented by NATs, as it could generate conflicts
>> when 2
>> internal hosts using the same local port, each with a session to the
same
>> endpoint. This would break end-to-end connectivity in rare cases, as
>> there
>> is no fallback mechanism (as opposed to TCP).
> 
> Please explain how TCP is not subject to the same problem.
> 

This question is really about Port Overloading and is the crux of the
discussion, so i'm giving a short answer and a longer, more detailed
answer.
I voluntarily leave the long answer on this mailing-list, so it can
provide raw material for the draft later on.


THE SHORT ANSWER:
Port overloading (UDP or TCP) introduces the small possibility of a
non-deterministic behavior of the NAT: the fallback on EDM in the event of
a 5-tuple conflict.
It's a rare event, and only affects p2p applications, who are already
prepared to deal with it. After all, a large part of NATs in the wild
aren't cooperative, so p2p applications always have fallback mechanisms in
place. 
Beacause of the potential benefits of port overloading for CGNs, this
should be a no brainer.
In short, port overloading is fine for both UDP and TCP and won't break
any p2p application.
That been said, the use case for NAT port overloading was always only TCP,
as applications do not need to create that many local endpoints for UDP. So
let's not even bother with the corner cases for UDP for simplicity sake and
tell the NAT not do port overloading for UDP.
Conclusion: 
- UDP port overloading is not particularly useful, Req 3 of RFC 4787 is
fine.
- TCP port overloading can be very useful, RFC 5382 should mention support
for it.


THE LONGER ANSWER:
There is one major difference between UDP and TCP from the application
point of view:

(1) one UDP socket (local endpoint) can have multiple communication
sessions. (with multiple remote endpoints)
(2) one TCP socket can have only one session.

Condition (2) is not implied by RFC 793, but is enforced by POSIX. This
originates from the fact that Unix had a special recv() function for
connected socket, as opposed to recvfrom() for general sockets. POSIX later
standardized on this Unix behavior. This Unix idiosyncrasy prevents
sessions multiplexing for connected sockets.

Consequence: 
Applications don't need to use more than one UDP local endpoint, but need
to use many TCP local endpoints.

The impact on applications behavior:
For UDP, a p2p application will tend to multiplex all its p2p sessions
over one UDP socket (actually, some use 2 or 3 sockets for convenience).
This is what you observe with Skype, uTorrent, etc. but is applicable to
virtually all applications: it saves scarce resources (ports) and is
considered good design.
Unfortunately, since POSIX doesn't support the same thing for TCP, and a
large number of TCP sockets will be created by the application, on many
local endpoints, as you have witnessed for most "torrent-like"
applications.

Consequence (1):
The use case for port overloading should be TCP, not UDP.


Back to NAT port overloading. A collision occurs when 2 sessions share the
same 5-tuple. It is usually a rare event. Let's look at the corner case of
when a collision occurs, with p being the probability of a collision:
- NAT fallbacks on EDM for this particular session (note:
non-deterministic behavior from the application pov, with probability p)
- two possible outcomes for the application:
  1) session initiation succeeds, OK.
  2) session initiation fails, application fallbacks on the following:
     * create a new socket (with a new local endpoint) and restart.
Probability of success increases exponentially in (1-p^n) at each re-try.
     * use another fallback mechanism (UPnP, relaying, etc.), but this is
out of scope and not part of the TCP Hole Punching protocol.

Note 1: The session usually often succeeds when NAT fallbacks to EDM. It
only fails in the case where the remote endpoint is also behind a NAT.

Note 2: Here, the slight probability of failure for a connection attempt
is corrected by the TCP Hole Punching protocol as a whole.
(Analogy with TCP: the non-deterministic behavior introduced by packet
loss is abstracted away by the TCP layer, by resending the lost packets)

The failure case when the session fails is dealt with by the more
complicated code path in 2). Here the application creates a new socket.
What it implies, in both UDP and TCP cases:
UDP: creating a new socket for UDP is ok, but an annoyance. Goes against
good design practices.
TCP: creating a new socket is ok, this is what the application is doing
anyway for each new session.


Conclusion:
UDP: there is not much of a case for port overloading, and the more
complicated behavior path could possibly go against application good design
practices.
TCP: port overloading fits well with the TCP Hole Punching protocol.


In my opinion, although we can leave the requirements for UDP as they are
for the sake of simplicity, we need to write about the possibility of port
overloading for TCP in the documents.



-- 
_Ivan Chollet_