Subject: [tae] Fwd: dccp-natencap and port numbers

From: Bryan Ford <[email-masked]>
Date: Wed, 26 Nov 2008 00:19:37 +0100

UDP encapsulation discussion background, re-post 2 of 3...

Begin forwarded message:
> From: Bryan Ford <[email-masked]>
> Date: November 21, 2008 11:56:01 PM GMT+01:00
> To: "Phelan, Tom" <[email-masked]>
> Cc: [email-masked], [email-masked], [email-masked]
> Subject: Re: dccp-natencap and port numbers
>
> Hi Tom,
>
> On Nov 21, 2008, at 8:55 AM, Phelan, Tom wrote:
>> In the DCCP meeting you mentioned that a problem you have with
>> dccp-natencap is its preservation of the DCCP port numbers.  Let me  
>> give
>> you the thought train that led to preserving the port numbers and  
>> maybe
>> you can give me your thoughts on why they shouldn't be preserved.
>>
>> The idea behind preserving the port numbers is simple -- if there's  
>> only
>> one port space then there can be only one transport protocol per  
>> port.
>> For example, port 80 is currently allocated as HTTP for UDP, TCP and
>> SCTP.  HTTP over UDP is not really defined, but it is defined for  
>> both
>> TCP and SCTP.  If there's only one port space, how can a server tell
>> which transport protocol is intended?  Rely on accidental differences
>> between a TCP SYN and an SCTP INIT?  Only allow a server to serve one
>> transport?
>
> That was my line of thinking too at one point, until I started  
> thinking about how applications actually support multiple transports  
> at one in the current world, versus a world with a shared port  
> space.  The HotNets paper that my presentation was based on  
> ("Breaking Up the Transport Logjam") discusses this a bit in section  
> 2.2.3.
>
> The short answer is that with a shared port space, the application  
> to which a given UDP port number is assigned is ultimately  
> responsible for defining the wire format of packets using that port,  
> and if the application is designed to be able to run multiple  
> distinct transports on top of this same UDP port whose wire formats  
> are not "naturally" distinguishable from each other, then the  
> application may need to insert some suitable header (e.g., an 8-bit  
> or 32-bit "transport ID" field) underneath those respective  
> transport headers in order to make their packets distinguishable  
> from each other.  This may not sound very satisfying at first, but  
> then consider the options that such multi-transport applications  
> have now.
>
> In the current world, where the "transport selector" is embedded in  
> the protocol field in the IP header but the port numbers are in the  
> transport header, an application has to choose SOME transport before  
> it can start communicating in any fashion.  This means that an  
> application that supports multiple transports must either (a)  
> initiate a communication session on some "default" transport, use  
> that to negotiate the transport, and then (possibly) open a new  
> session using the transport that the application has decided it  
> wants to use; or (b) take a "shotgun" approach and initiate sessions  
> using all the transports it supports, see which one(s) actually  
> succeed (i.e., which ones the responder supports), and then close  
> all but the "most preferred" one.  Thus, the current architecture  
> forces multi-transport applications to choose between two evils:  
> incurring at least one unnecessary round-trip delay just to  
> negotiate the transport to use, or wastefully creating several  
> transport sessions in parallel, only one of which will actually be  
> used.
>
> If the application has only one port number, however (its assigned  
> UDP port), and multiplexes all of the transports it supports atop  
> that, then the application gets to control how it negotiates and  
> distinguishes among those transport protocols.  One thing it can do  
> (just an example, not a prescription) is first to ask each of the  
> transports it supports for a copy of the transport's SYN packet,  
> bundle all those SYN packets into one "Meta-SYN" packet to send to  
> the responder.  The responding application receives this Meta-SYN  
> bundle, picks out the SYN packet for the most preferred transport  
> that it supports, and passes it to the transport locally to start  
> the connection initiation.  The selected transport responds, and  
> communication proceeds using that transport with no unnecessary  
> round-trip delays and no unnecessary state built up for transports  
> that didn't actually get chosen.
>
> The main point, though, is that distinguishing and selecting between  
> multiple transports should be up to the application.  The IETF  
> already wisely decided to stop assigning multiple port numbers for  
> "SSL" and "non-SSL" versions, instead requiring that applications  
> negotiate such matters themselves on top of their (single) port  
> allocation.  I'm just saying that the same logic applies equally  
> well to transports themselves.
>
>> The problem gets worse with the recent IANA decision, due to  
>> depletion
>> of the port space, to allocate ports independently for each  
>> transport.
>> With this you can get a port that's a different application for each
>> transport.  This can exist even when the ports are nominally  
>> allocated
>> to the same application although it's less apparent.  There are
>> situations where the port is allocated to one application for UDP and
>> TCP, but the two transports provide different functions.  Often the  
>> UDP
>> port provides a discovery/registration service and the TCP port  
>> provides
>> a data transfer service.
>>
>> As far as I can see, draft-denis-udp-transport offers no remedy to  
>> this.
>> The "Meta-SYN" idea you discussed in tsvarea has possibilities.  It
>> could allow sharing a port between TCP/SCTP/DCCP but would rely on
>> having no existing UDP application that uses that port.  For a  
>> trivial
>> example, discard is defined as port 9 for all of the transport
>> protocols.  Even with a Meta-SYN, a listener wouldn't be able to
>> determine if the client meant plain-old-UDP or fancy-new-udp-encap.
>
> For an existing application that doesn't yet have a UDP port  
> allocation (or does but doesn't yet use it), there's no problem  
> since it can define whatever mechanism is needed to negotiate/ 
> differentiate the different transports it wants to run on that UDP  
> port.  If the application already has an existing UDP port  
> allocation and uses it, then we have to look at the existing  
> "application-over-UDP" protocol spec and find a way (necessarily  
> specific to that application protocol) to build a protocol spec for  
> "application-over-<transport>-over-UDP" such that the latter spec's  
> packets won't be confused with those of the former.  For example, if  
> we for some reason wanted to do DNS over TCP/SCTP/DCCP over UDP,  
> then we would have to look at the regular DNS over UDP spec and come  
> up with some (ideally short) header format to interpose between the  
> UDP header and the TCP/SCTP/DCCP header such that the resulting UDP  
> packets will never be confused with regular DNS over UDP packets.   
> It's a bit ugly and unfortunate that it's specific to the  
> application protocol, but legacy compatibility hacks unavoidably  
> tend to have those problems in any case.
>
> Cheers,
> Bryan
>
>> Tom P.
>

_______________________________________________
tae mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tae

---

From: Bryan Ford <[email-masked]>
Date: Wed, 26 Nov 2008 00:16:28 +0100

To bring another relevant discussion thread onto the TAE list, this  
and the following couple posts are the beginning of a discussion  
between Tom Phelan and I on UDP encapsulation of transports (e.g.,  
draft-phelan-dccp-natencap versus draft-denis-udp-transport), and the  
issues of having multiple transports share a single (e.g., UDP) port  
space.  This thread already appeared publicly on the DCCP list.

Begin forwarded message:
> From: "Phelan, Tom" <[email-masked]>
> Date: November 21, 2008 3:55:13 PM GMT+01:00
> To: "Bryan Ford" <[email-masked]>, <[email-masked]>, <[email-masked] 
> >
> Subject: dccp-natencap and port numbers
>
> Hi Bryan,
>
> one port space then there can be only one transport protocol per port.
> SCTP.  HTTP over UDP is not really defined, but it is defined for both
> The problem gets worse with the recent IANA decision, due to depletion
> of the port space, to allocate ports independently for each transport.
> transport.  This can exist even when the ports are nominally allocated
> having no existing UDP application that uses that port.  For a trivial

---

From: Bryan Ford <[email-masked]>
Date: Wed, 26 Nov 2008 00:22:52 +0100

UDP encapsulation discussion background, re-post 3 of 3...

Begin forwarded message:
> Date: November 24, 2008 4:55:16 PM GMT+01:00
> To: "Bryan Ford" <[email-masked]>
> Cc: <[email-masked]>, <[email-masked]>, <[email-masked] 
> >
> Subject: RE: dccp-natencap and port numbers
>
> Hi Bryan,
>
> OK, I see that line of reasoning.  However, that means that the  
> current
> version of denis-udp-transport barely scratches the surface of the
> subject.  The backward compatibility issues are large, and if we  
> ignore
> them then we're guilty of the same sort of thing that got us into this
> situation in the first place.
>
> It seems to me that denis-udp-transport needs to include the reasoning
> below, needs to define the Meta-SYN packet, needs to specify a generic
> mechanism for applications to do the transport disambiguation, needs  
> to
> specify generic mechanisms for signaling the UDP-encap transports and
> needs to specify how a few existing applications apply those generic
> mechanisms (SIP most importantly -- that already has widespread use of
> UDP, TCP and SCTP transports, simultaneously offered on many servers).
>
> Are you guys up for that much work?
>
> More inline...
>
> Tom P.
>
>> -----Original Message-----
>> From: Bryan Ford [mailto:[email-masked]]
>> Sent: Friday, November 21, 2008 5:56 PM
>> To: Phelan, Tom
>> Cc: [email-masked]; [email-masked];
>> [email-masked]
>> at one in the current world, versus a world with a shared port space.
>> The HotNets paper that my presentation was based on ("Breaking Up the
>> Transport Logjam") discusses this a bit in section 2.2.3.
>>
>> The short answer is that with a shared port space, the application to
>> which a given UDP port number is assigned is ultimately responsible
>> for defining the wire format of packets using that port, and if the
>> application is designed to be able to run multiple distinct  
>> transports
>> on top of this same UDP port whose wire formats are not "naturally"
>> distinguishable from each other, then the application may need to
>> insert some suitable header (e.g., an 8-bit or 32-bit "transport ID"
>> field) underneath those respective transport headers in order to make
>> their packets distinguishable from each other.  This may not sound
>> very satisfying at first, but then consider the options that such
>> multi-transport applications have now.
>>
>> initiate
>> a communication session on some "default" transport, use that to
>> negotiate the transport, and then (possibly) open a new session using
>> the transport that the application has decided it wants to use; or  
>> (b)
>> take a "shotgun" approach and initiate sessions using all the
>> transports it supports, see which one(s) actually succeed (i.e.,  
>> which
>> ones the responder supports), and then close all but the "most
>> preferred" one.  Thus, the current architecture forces multi- 
>> transport
>> applications to choose between two evils: incurring at least one
>> unnecessary round-trip delay just to negotiate the transport to use,
>> or wastefully creating several transport sessions in parallel, only
>> one of which will actually be used.
>
> [Tom P] Sort of.  In many current cases that use multiple transports,
> the transport selection is done via a signaling application that
> communicates that and many other things -- think SIP/SDP or DNS SRV
> records or a combination.
>
>>
>> port), and multiplexes all of the transports it supports atop that,
>> then the application gets to control how it negotiates and
>> the
>> responder.  The responding application receives this Meta-SYN bundle,
>> picks out the SYN packet for the most preferred transport that it
>> supports, and passes it to the transport locally to start the
>> connection initiation.  The selected transport responds, and
>> round-
>> trip delays and no unnecessary state built up for transports that
>> didn't actually get chosen.
>
> [Tom P] This is good, but it isn't as simple as bundling the various
> "SYN" packets.  Does the order imply a preference?  Even if the  
> there's
> no implied preference, it has to be specified as such.  If there is a
> preference, whose preference matters more (client or server)?  How is
> retransmission handled?  Each transport has slightly different rules.
> There are probably other issues.
>
>>
>> already
>> wisely decided to stop assigning multiple port numbers for "SSL" and
>> "non-SSL" versions, instead requiring that applications negotiate  
>> such
>> matters themselves on top of their (single) port allocation.  I'm  
>> just
>> saying that the same logic applies equally well to transports
>> themselves.
>>
>
> [Tom P] OK for TLS, as that's an above-the-transport-layer thing, but
> this is all transport layer.  It's really up to the transport layer to
> decide which transport is being requested -- after all, it's not
> necessarily so that a given port is the same application for all
> transports, so it really can't be left completely to the application
> layer.
>
>> allocation (or does but doesn't yet use it), there's no problem since
>> it can define whatever mechanism is needed to negotiate/differentiate
>> the different transports it wants to run on that UDP port.  If the
>> application already has an existing UDP port allocation and uses it,
>> then we have to look at the existing "application-over-UDP" protocol
>> spec and find a way (necessarily specific to that application
>> protocol) to build a protocol spec for "application-over-<transport>-
>> over-UDP" such that the latter spec's packets won't be confused with
>> those of the former.  For example, if we for some reason wanted to do
>> DNS over TCP/SCTP/DCCP over UDP, then we would have to look at the
>> regular DNS over UDP spec and come up with some (ideally short)  
>> header
>> format to interpose between the UDP header and the TCP/SCTP/DCCP
>> header such that the resulting UDP packets will never be confused  
>> with
>> regular DNS over UDP packets.  It's a bit ugly and unfortunate that
>> it's specific to the application protocol, but legacy compatibility
>> hacks unavoidably tend to have those problems in any case.
>
> [Tom P] You say "we" here.  I'm taking that as the small "we" who are
> writing udp-transport, not the big "we" of the entire IETF, at least  
> for
> the very popular existing applications such as SIP.
>
>>
>> Cheers,
>> Bryan
>>
>>> Tom P.
>

---

From: Bryan Ford <[email-masked]>
Date: Wed, 26 Nov 2008 01:11:58 +0100

> Are you guys up for that much work?

I agree that we eventually will want to specify/standardize those  
things, but I don't think we have to do it all right away, or in one  
document (like denis-udp-transport) that specifies basic <transport>- 
over-UDP encapsulation formats.  Today, when an application wants to  
run a transport like TCP or SCTP atop UDP, it's most often because the  
application wants to get the transport working across NATs and support  
hole punching reliably.  For that purpose, the application just needs  
some fixed <transport>-over-UDP encapsulation scheme, and probably  
doesn't care about negotiating among different transports.   
Applications that DO want to negotiate between multiple transports can  
use their own application-specific negotiation mechanisms atop their  
allocated UDP ports for now, until and unless we get around to  
standardizing an application-neutral negotiation protocol of some kind.

For the "basic encapsulation format" document (along the lines of  
denis-udp-transport), we perhaps should at least specify a minimal  
disambiguation mechanism that would allow the packets of different  
transports to be distinguished from each other and from negotiation  
packets, _if_ the application chooses to do transport negotiation of  
some kind.  For this purpose, however, we already have a starting  
point to work from: namely STUN (RFC 5389).  If STUN is the "IETF- 
standardized" way of doing UDP NAT hole punching, then any new IETF- 
standardized protocol sitting atop UDP that supports hole punching  
inherently needs to be compatible with STUN, in the sense that the  
protocol's packets need to be distinguishable from STUN packets, as  
described in RFC 5389.  This requirement is unavoidable in any case  
because for hole punching to work, STUN's control packets need to  
share the same UDP session tuple that the hole-punched upper layer  
protocol will be using.  Since one of the primary pragmatic  
motivations (primary THE primary motivation) right now for UDP- 
encapsulated transports is to make them traverse NATs and support hole  
punching, any new <transport>-over-UDP encapsulation scheme needs to  
be compatible with (i.e., at least distinguishable from) STUN  
packets.  We can thus build whatever <transport>-over-UDP  
encapsulation schemes, as well as any future negotiation protocols,  
around the multiplexing groundwork already laid by STUN.  Not to say  
this won't take some work, but I think it has to be done in any case.

> records or a combination.

Indeed.  I don't know enough about SIP/SDP to comment on that, but see  
the discussion regarding Joe Touch's comment on the DNS SRV approach.

> There are probably other issues.

Yes, all important questions that we need to consider, although that  
can be done separately from the specification of basic UDP  
encapsulation formats for specific transports, and doesn't need to be  
completed before UDP-encapsulated transports become useful to  
applications.

In my example Meta-SYN scheme, my intent was that the client bundles  
the SYNs in order of its (the client's) preference, but it is  
ultimately up to the server to choose the transport.  The server can  
abide by the client's preferences, or it can alternatively override  
the client's preferences and pick its _own_ most preferred choice, out  
of the transports the client and server both support.  But again, this  
was just an example scheme; I don't care that much about exactly how  
preferences would be expressed and implemented in a standardized  
negotiation scheme.

> transports, so it really can't be left completely to the application

One might interpret the term "TLS", aka "Transport Layer Security", as  
"security in/for the transport layer". :)

> the very popular existing applications such as SIP.

Yes, probably, although I don't have a big burden about exactly who  
the "we" is that is responsible for the UDP encapsulation spec (e.g.,  
which working group sponsors it), as long as all the right people know  
about it and are involved.

Bryan