Subject: Re: [multipathtcp] Fwd: [rrg] New Paper On Name-Oriented Sockets Interface

From: Joe Touch <[email-masked]>
Date: Tue, 01 Dec 2009 14:56:39 -0800

Rémi Després wrote:
> Le 27 nov. 2009 à 11:57, Scott Brim a écrit :
> 
>> IIRC in Christian's idea the transport layer itself works on names.
>> It's more than a proposal for a name-based API.
> 
> Agreed.
> I haven't studied all details of Christian's proposal, but I fully support that:
> - A name-capable API is an essential objective.

I'm not sure this is a desirable objective.

When you specify a name, you're not specifying a single address; you're
specifying any one of a set of addresses. It's presumed that these are
equivalent, but not that they are to the same host. A name-based system
could easily end up with a sequence of connections going to different
hosts.

That's avoided today as:

	adr = first(dns("name"))  -- or adr = pickone(dns("name"))
	connect(adr)
	connect(adr)
	connect(adr)

There doesn't seem to be a way to achieve this with:

	connect("name")
	connect("name")
	connect("name")

This destroys the utility of HTTP cookies, e.g.

Joe

---

From: Rémi Després <[email-masked]>
Date: Wed, 02 Dec 2009 11:34:36 +0100

Hi Joe,

Comments below.
Stuart Cheshire added to the list (AFAIK, the leading advocate of 
connect-by-name).

Regards,
RD

Joe Touch wrote :
...
> Rémi Després wrote:
...

> This destroys the utility of HTTP cookies, e.g.

Note that:
- If backward compatibility is maintained, as required in the proposal, 
a name-capable API doesn't imply that it be address-unable.
- Connect-by-name is already mentioned for Shim6 in RFC 5533 - sec. 13, 
(a way to save time when multiple addresses have to be tried for a given 
domain name)

Applications that may depend on successive connections to go to the same 
host, they can use:
	ConnectByName(name) which returns the chosen adr
	Connect(adr)
	Connect(adr)
	Connect(adr)

The useful novelty ahead is IMHO the following:
- If a connection initiator includes its domain name in its connection 
request (e.g. in a TCP option) the API of the reached application, if it 
is name-capable, provides both the address AND the name of the 
connection initiator.
- A consistency check between address and name is done by the transport 
laye before connection acceptance. This check needs only a DNS query. It 
is therefore compatible with DNS dynamic updates and DNSSEC (no need for 
a DNS supported reverse mapping).

---

From: Zhen Cao <[email-masked]>
Date: Wed, 2 Dec 2009 22:28:33 +0800

On Wed, Dec 2, 2009 at 6:34 PM, Rémi Després <[email-masked]> wrote:
> - If backward compatibility is maintained, as required in the proposal, a
> name-capable API doesn't imply that it be address-unable.

I have a question here. How does a host know if its peer support the
name oriented sockets or not?

> - Connect-by-name is already mentioned for Shim6 in RFC 5533 - sec. 13, (a
> way to save time when multiple addresses have to be tried for a given domain
> name)
>
> request (e.g. in a TCP option) the API of the reached application, if it is
> name-capable, provides both the address AND the name of the connection
> initiator.
> - A consistency check between address and name is done by the transport laye
> before connection acceptance. This check needs only a DNS query. It is
> therefore compatible with DNS dynamic updates and DNSSEC (no need for a DNS
> supported reverse mapping).
>
>
> _______________________________________________
> multipathtcp mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/multipathtcp
>

---

From: John Leslie <[email-masked]>
Date: Wed, 2 Dec 2009 10:01:29 -0500

> Stuart Cheshire added to the list (AFAIK, the leading advocate of 

   Hi, Stuart!

>> could easily end up with a sequence of connections going to different

   True.

>> This destroys the utility of HTTP cookies, e.g.

   Only if both ends are blind to the issue...

>   (a way to save time when multiple addresses have to be tried for a
>   given domain name)
> 

   That's one way to think about the problem...

>   request (e.g. in a TCP option) the API of the reached application, if
>   it is name-capable, provides both the address AND the name of the 
>   connection initiator.

   I would argue that any ConnectByName API SHOULD contain the _name_
by which your end wants to be known by the other end. ("Connect" should
imply establishing a "connection" IMHO.)

>   layer before connection acceptance. This check needs only a DNS query.
>   It is therefore compatible with DNS dynamic updates and DNSSEC (no
>   need for a DNS supported reverse mapping).

   I'm not sure that's necessary, but it's certainly appropriate to
discuss what consistency checks _are_ necessary...

   I would argue that our charter calls for work on
" 
" e. An extended API describing how applications can exploit additional
"    features of multipath transport. While MPTCP needs to be usable
"    without any application changes, this API should be an optional
"    extension that provides access to multipath information and enables
"    control over the usage of multipath.

and further that "an extended API" should enable extension to protocol
extensions yet to be defined. Thus:

- the same "extended API" should be able to request legacy TCP, MPTCP,
  or even other transports (such as SCTP);

- the "extended API" should be able to use DNS names or some other name
  format to be defined later (for one example, IPv6 "address" space is
  large enough to contain many "name" spaces);

- the "extended API" should return an indication of which names and/or
  addresses the other end of the connection uses.

--
John Leslie <[email-masked]>

---

From: Joe Touch <[email-masked]>
Date: Wed, 02 Dec 2009 07:12:45 -0800

>     ConnectByName(name) which returns the chosen adr

This cannot work for multipath TCP.

If you do not have "fate sharing" with the original address, subsequent
connections to an address could go to a different host (e.g., that is
reassigned an IP address).

If you do have fate-sharing with the original address, an endpoint will
never be able to connect to an address once reassigned.

I.e., neither way is viable.

Joe

---

From: "Laganier, Julien" <[email-masked]>
Date: Wed, 2 Dec 2009 08:29:00 -0800

Hi Joe,

Joe Touch wrote 
> This destroys the utility of HTTP cookies, e.g.

Looking at this from a different perspective: Since the resolution of a domain name into an address is only valid for the TTL of the returned resource record, it also makes sense that an application that want to connect to a name always call the name to address resolver before connecting to the address. The resolver has knowledge of the TTL, and can return the same address if the resource record hasn't expired, or issue another DNS query and return the result if the resource record had expired.

So in terms of your sequence examples:

adr = first(dns("name"))  --  DNS query return A RR with TTL 255
connect(adr)
adr = first(dns("name"))  --  A RR TTL is now 32, no DNS query
connect(adr)
...                       --  A RR TTL is zero, resolver cache is flushed 
adr = first(dns("name"))  --  DNS query return A RR with TTL 255 
connect(adr)

So if the service provided at "name" is stateful across different connections, it seems like it is the service provider responsibility to ensure that a given client always connect to the same server (possibly via different addresses), or the client state be replicated amongst different servers whose addresses are returned from the DNS. That can be achieved in various ways which are protocol and deployment specific, e.g., L7 load balancer, clustering...  

So either ways (the one you outlined or the one above) seem 'legal' and possible, thus I don't think we should assume a specific DNS semantic (e.g., one name corresponds to one server) or application behavior (e.g., application queries a name for an address and then (re)connect to the address) in the API discussion. Situations varies with protocols and deployments.

--julien

---

From: Joe Touch <[email-masked]>
Date: Wed, 02 Dec 2009 08:38:34 -0800

Hi, Julien,

...
> Looking at this from a different perspective: Since the resolution of
> a domain name into an address is only valid for the TTL of the returned
> resource record, it also makes sense that an application that want to
> connect to a name always call the name to address resolver before
> connecting to the address. The resolver has knowledge of the TTL, and
> can return the same address if the resource record hasn't expired, or
> issue another DNS query and return the result if the resource record had
> expired.

Yes, but do you want behavior to change depending on whether the TTL has
expired? I.e., occasionally your HTTP cookies fail?

Current use caches the address at the application because the name was
relevant only for the connection; subsequent connections are intended
for the same *endpoint*, not just the same name.

Joe

---

From: "Laganier, Julien" <[email-masked]>
Date: Wed, 2 Dec 2009 09:01:51 -0800

Joe Touch wrote:
> > a domain name into an address is only valid for the TTL of the
> > returned resource record, it also makes sense that an application that
> > want to connect to a name always call the name to address resolver
> > before connecting to the address. The resolver has knowledge of the 
> > TTL, and can return the same address if the resource record hasn't 
> > expired, or issue another DNS query and return the result if the 
> > resource record had expired.
> 
> Yes, but do you want behavior to change depending on whether the TTL
> has expired? I.e., occasionally your HTTP cookies fail?
> 

My point was that the address might be cached or not at the application, both are possible. The application might make sure it's connecting to the same address, or make sure it's connecting to a fresh address for the name.

So if a specific application want to make sure it's connecting to the same address it can cache the address both with connect() and, as Remi pointed out, with connect_to_name().

--julien

---

From: Joe Touch <[email-masked]>
Date: Wed, 02 Dec 2009 09:19:19 -0800

Laganier, Julien wrote:
> My point was that the address might be cached or not at the
> application, both are possible. The application might make sure it's
> connecting to the same address, or make sure it's connecting to a fresh
> address for the name.

The former is not possible with multipath TCP if the original IP
addresses disappear.

> So if a specific application want to make sure it's connecting to the
> same address it can cache the address both with connect() and, as Remi
> pointed out, with connect_to_name().

If it does, then we're back to the existing API.

Joe

---

From: "Laganier, Julien" <[email-masked]>
Date: Wed, 2 Dec 2009 10:27:48 -0800

Joe Touch wrote:
> > connecting to the same address, or make sure it's connecting to a
> > fresh address for the name.
> 

If the original IP address disappear, the connect() to that address will fail, period. 

> > same address it can cache the address both with connect() and, as
> > Remi pointed out, with connect_to_name().
> 

No we're not. We still have the advantage that the initial connection can be established to the fastest IPv{4,6} endpoint.

--julien

---

From: Joe Touch <[email-masked]>
Date: Wed, 02 Dec 2009 10:59:40 -0800

> If the original IP address disappear, the connect() to that address will fail, period. 

Right - but that's not what you want to happen in multipath TCP, right?

> No we're not. We still have the advantage that the initial connection
> can be established to the fastest IPv{4,6} endpoint.

Fastest?

I think this means you leave the decision to another layer, but I
haven't heard anyone explain 'fastest' yet.

Joe

---

From: "Laganier, Julien" <[email-masked]>
Date: Wed, 2 Dec 2009 11:07:19 -0800

Joe Touch wrote: 
> >>> application, both are possible. The application might make sure
> >>> it's connecting to the same address, or make sure it's connecting
> >>> to a fresh address for the name.
> >>

In the case we're discussing this is a further connect() after an initial connect_by_name() and thus another MPTCP connection, so it should fail. 

This is different from a single MPTCP connection surviving the disappearance of the original IP address (i.e., not implementing fate sharing b/w an MPTCP connection and the original address.) 
 
> haven't heard anyone explain 'fastest' yet.

For example, send SYN to a a couple of the addresses (v4 or v6) return in the DNS response, and only complete the TCP handshake with the address from which you received the first SYN-ACK.

--julien

---

From: Joe Touch <[email-masked]>
Date: Wed, 02 Dec 2009 11:12:54 -0800

Laganier, Julien wrote:
...
> For example, send SYN to a a couple of the addresses (v4 or v6) return
> in the DNS response, and only complete the TCP handshake with the
> address from which you received the first SYN-ACK.

That gives you the fastest SYN-ACK time. Which has nothing to do with
many other desirable properties (largest BW, lowest data packet latency,
etc.)

And that's already possible at the app layer, FWIW.

Joe

---

From: Rémi Després <[email-masked]>
Date: Thu, 03 Dec 2009 09:56:04 +0100

> This cannot work for multipath TCP.

I don't see why this would work less than what you described, namely:
      adr = first(dns("name")) -- or adr = pickone(dns("name"))
      connect(adr)
      connect(adr)
      connect(adr)

It seems that,like in RFC 5533 sec 1.3 for Mip6, the adr that is 
selected in the initial contact with the remote peer can be used as the 
preserved upper layer identifier (ULID).

RD

---

From: Rémi Després <[email-masked]>
Date: Thu, 03 Dec 2009 10:31:07 +0100

Agreed.

It can be a useful extension that the connection initiator may provide
both the name of the target endpoint but also its own name, and that the
called endpoint would be in this case informed of both the name of the
initiator provided name and the name provided as target endpoint.

> discuss what consistency checks _are_ necessary...

Agreed to discuss it, but hoping to conclude positively:
Making consistency checks mandatory as soon as they are possible, 
greatly simplifies security in general, and anti-spoofing in particular. 
(Letting errors or malevolent inconsistencies to propagate greatly 
increases higher maintenance costs and insecurity.)

Agreed.

> - the "extended API" should be able to use DNS names 

Agreed.

>   or some other name

To be seen, but agreed that using some ad-hoc-format IPv6 addresses as 
names has IMHO an interesting potential.

Agreed.

RD

---

From: Rémi Després <[email-masked]>
Date: Thu, 03 Dec 2009 10:55:10 +0100

> name oriented sockets or not?

A connection initiator that supports name-oriented sockets doesn't need 
to know whether the peer supports them or not: it just adds name 
informations, i.e. initiator name and target name, in options of its 
connection requests .
A connection acceptor that doesn't support name-oriented sockets 
automatically ignores these name informations because they are in 
non-recognized options.

A connection acceptor that supports name-oriented sockets determines 
whether a peer supports them when it finds, or doesn't find, 
name-information options in a connection request it receives.

RD

---

From: Scott Brim <[email-masked]>
Date: Thu, 03 Dec 2009 08:47:51 -0500

> And that's already possible at the app layer, FWIW.

Joe, this is a "time and space" tradeoff.  You quickly gather enough
information to get _some_ decent connectivity, and then refine it as
necessary over the life of the flow.

---

From: Joe Touch <[email-masked]>
Date: Thu, 03 Dec 2009 07:16:13 -0800

> necessary over the life of the flow.

What's being traded?

My concern is that for TCP, this technique requires very careful
implementation to maintain existing semantics - on which many apps rely
- - and doesn't save much effort.

For m-TCP, this technique might actually not be appropriate at all (see
other posts).

Joe

---

From: Joe Touch <[email-masked]>
Date: Thu, 03 Dec 2009 07:27:02 -0800

>      adr = first(dns("name")) -- or adr = pickone(dns("name"))

Agreed - neither one works for multipath tcp.

> preserved upper layer identifier (ULID).

Well, 5533 explains why:

   However, using a single 128-bit ULID doesn't provide seamless
   communication when that locator is unreachable.  See [18] for further
   discussion of the application implications.

I.e., Shim6 wasn't trying to address a scenario that multipath TCP is
focusing on, namely the case where the original IP address disappears.

That's *why* I keep raising the fate-sharing issue. Keep fate sharing
and you keep TCP semantics. Ditch fate sharing and I have absolutely no
idea why this would work.

Joe

---

From: "Laganier, Julien" <[email-masked]>
Date: Thu, 3 Dec 2009 07:39:22 -0800

> - - and doesn't save much effort.

Joe, this is simple: An app using the new API will rely on the semantic of the new API. Semantic of existing APIs and app using them are not affected by the new API and its semantic.  
 
> For m-TCP, this technique might actually not be appropriate at all (see

Well, I haven't see a convincing argument substantiating this claim.

--julien

---

From: Rémi Després <[email-masked]>
Date: Thu, 03 Dec 2009 17:58:13 +0100

Joe Touch wrote :
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> 
> 
> Rémi Després wrote:
>> Joe Touch wrote :
>>
>>> Rémi Després wrote:

Thanks for the reference.

> focusing on, namely the case where the original IP address disappears.

SCTP does work if the original address disappears, and mptcp should do 
the same. The list of currently valid locators is continuously kept 
updated by the transport protocol itself.
Concerns expressed in [18] apply to Shim6, and to other contexts where 
current connections are not known but, in my understanding, not to SCTP 
and mptcp where they are available.

RD

> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
> 
> iEYEARECAAYFAksX2MUACgkQE5f5cImnZrsfkACgjd+EI+J0UPSnH9iqyHriZ8YE
> 4DMAoPyjHkGsoNRkucQN+cpWP1Alg8CH
> =CRCn
> -----END PGP SIGNATURE-----
>

---

From: Joe Touch <[email-masked]>
Date: Thu, 03 Dec 2009 18:41:38 -0800

...
> SCTP does work if the original address disappears, and mptcp should 
> do the same. The list of currently valid locators is continuously
> kept updated by the transport protocol itself. Concerns expressed in
> [18] apply to Shim6, and to other contexts where current connections
> are not known but, in my understanding, not to SCTP and mptcp where
> they are available.

So how do you know the difference in mptcp between trying to open a
connection to the old IP (which is gone, but still used as the ULID for
existing connections) and the new IP (e.g., whomever now has that IP
address now, since it may have been reassigned for all you know)?

You can't have it both ways using just an IP address as ULID, and you
need to have it both ways or else *any* old connection to an IP address
that is no longer where it was when you started is unreachable as a new
location until ALL old connections go away.

That's a bad kind of fate sharing, IMO.

Joe

---

From: Rémi Després <[email-masked]>
Date: Fri, 04 Dec 2009 11:08:04 +0100

> address now, since it may have been reassigned for all you know)?

During an mptcp connection, each endpoint keeps the other endpoint 
informed of its  currently valid address set.
Only an address in such a set may be used as IP address of a new mptcp 
path to be established.
In TCP connection requests other than the first one of an mptcp 
connection, mptcp ULIDs, i.e. IP addresses of the initial TCP connection 
must be conveyed in some form data (in a TCP option or, better IMO but 
this is a different discussion, in an mptcp field at the beginning of 
the TCP payload).

For a new mptcp session, valid IP addresses for a given name must be 
obtained from the DNS.
(For obsolete addresses not to remain in name-to-address-set-mapping 
caches, TTLs of these addresses must be consistent with how quickly 
these addresses may change.)

Anything wrong with this?

RD

---

From: Joe Touch <[email-masked]>
Date: Fri, 04 Dec 2009 16:31:05 -0800

> Anything wrong with this?

Going back to the DNS for subsequent mptcps means that you can't
correlate two different mptcp's as "going to the same place". You want
to just use an IP address to do that.

Joe

---

From: Rémi Després <[email-masked]>
Date: Sat, 05 Dec 2009 10:30:39 +0100

> to just use an IP address to do that.

The goal you express is different from just permitting an 
application-layer TCP connection to be, at the transport layer, 
implemented as a group of parallel TCP connections (to increase 
performance and resilience, in my understanding the specific goal of mptcp).

For this new goal, one possible approach, also applicable to ordinary 
TCP, is that the ConnectByName has an option whereby the application 
proposes an IP address.
If this address is still cached, or present in the set of addresses 
obtained with a new DNS query, this address is used.
Otherwise the connection fails.

In another approach, which better separates layers, the ConnectByName 
has an option to request that the the address to be used be the same as 
in the previous connection to the same name.
The transport layer, which memorizes which address was last used by this 
application for this name, does the job (cache test, new DNS query if 
needed).

RD

---

From: Christian Vogt <[email-masked]>
Date: Sat, 5 Dec 2009 17:46:53 -0800

> to just use an IP address to do that.

Joe -

In an Internet where mobility and multi-homing is becoming increasingly
common, using an IP address as a host reference is of decreasing
utility.  Host-specific names would be the more useful host references. 
Applications that maintain state across sessions should exchange
host-specific names, resolvable via the DNS, to enable future sessions
between the same host pair.

Certainly, to contact a host without DNS-resolvable name, applications
must necessarily try to connect to specific IP addresses.  Yet this does
not mean that sessions have to be bound to a specific IP address pair
for their entire lifetime.  A more powerful alternative would be to
derive names from IP addresses, and endow those with the semantics: "The
host which used the underlying IP address at the time of session
establishment."  Then, sessions established with such names can continue
even if the IP address pair used during session establishment becomes
defunct.  Note that applications are guaranteed to be aware of the
semantics of IP-address-derived names, as they have explicitly selected
a name-based sockets interface that supports those.

The paper being discussed uses IP-address-derived names as well.

- Christian

---

From: Christian Vogt <[email-masked]>
Date: Sat, 5 Dec 2009 17:56:51 -0800

On Dec 3, 2009, Rémi Després wrote:

> to know whether the peer supports them or not [...]

This is correct as long as you don't support IP address updates, i.e.,
mobility or multi-homing.  IP address updates require bilateral support,
because both peers must switch to a new IP address pair in a coordinated
manner.  This is why hosts should indeed be able to detect their peer's
support of name-based sockets.  The paper utilizes a bidirectional name
exchange at the beginning of a session for this purpose.

- Christian

---

From: Joe Touch <[email-masked]>
Date: Sat, 05 Dec 2009 17:57:56 -0800

Christian Vogt wrote:
> utility. 

I could not agree more, but I think that this goes too far outside the
scope of TCP to still be called TCP if that's the case.

As you note, there are challenges with shifting over to a name-based
model, and those challenges not only change the TCP API, but also
require changes in the DNS API as well.

Joe

---

From: Christian Vogt <[email-masked]>
Date: Sat, 5 Dec 2009 20:02:19 -0800

> scope of TCP to still be called TCP if that's the case.

Whether we call it "TCP" or something else becomes irrelevant once we
introduce a new API, because the new API guarantees that applications
are aware of the changes we introduce.  More challenging is, in my
opinion, the deployment of multi-path TCP in an application-transparent
manner, as this indeed requires adhering to the original TCP semantics.

> require changes in the DNS API as well.

I don't see why changes to the DNS API would be necessary.  And
regarding changes to the socket API:  Yes, this is challenging.  But I
am optimistic that it can be done.  The popularity of existing name-
based socket API abstractions, as in Java or MacOS X, demonstrates this.

- Christian

---

From: Rémi Després <[email-masked]>
Date: Mon, 07 Dec 2009 12:12:45 +0100

Christian Vogt a écrit :
> mobility or multi-homing.

During the connection establishment handshake, yes it is useful that 
both ends exchange information about their capabilities, in particular 
about mobility and multihoming support.

> IP address updates require bilateral support,

After the initial exchange of addresses, it is still unclear to me 
whether it is sufficient that both ends become aware of their support of 
mobility, and/or multihoming, or whether they have also to be aware of 
their support of name-based sockets.

If possible, keeping orthogonality of these features is IMHO preferable.

RD

---

From: Javier Ubillos <[email-masked]>
Date: Mon, 07 Dec 2009 12:34:51 +0100

> If possible, keeping orthogonality of these features is IMHO

Exchange of addresses as in exchange of names?
If the names are exchanged, it's already established that both ends
support the name-based sockets.

Also, the mechanism of name-exchange is an good and easy platform for
capability negotiations. Simply (somehow) append capability
information/preferences to the name option.

// Javier

---

From: Rémi Després <[email-masked]>
Date: Mon, 07 Dec 2009 17:15:07 +0100

> Exchange of addresses as in exchange of names?

The point is about addresses.
They can be exchanged even if the connection acceptor doesn't support 
name-capable sockets.

> support the name-based sockets.

Right.

> information/preferences to the name option.

No objection, but multihoming and mobility already exist, without 
relationship with name-capable sockets.
SCTP and NEMO, for example, should need no change to work in combination 
with name-capable sockets.

Unless we prefer to mix problems, name-capable sockets should IMHO only 
be sockets where names may be used in place of addresses.

RD