Subject: Re: [nbs] A suggestion for an "on-demand API".

From: [email-masked]
Date: Tue, 14 Dec 2010 09:47:34 -0500

[email-masked] wrote:

> At IETF79, at some point after the name-based sockets BoF.
> Together with Erik Nordmark and Christian Vogt, we sat down, discussed a
> bit about name-oriented APIs and gravitated towards this idea:
> 
> The cost for behavior and an API should be incremental and optional, in
> the sense that; you should only pay the price for a feature if you
> really want to have it.
> 
> E.g.
> 
> * A web-server only requires a session-handle, the web-server will reply
> to any-one initiating a session. No "extras" are asked for.
> 
> * Some other application might require authenticity of name->IP binding,
> and is also prepared to pay the cost for that authenticity (typically a
> round-trip).
> 
> An example:
> 
> Host A (A.left.org) and host b (B.right.org).
> 
> * Host A.left.net resolves "B.right.net" to IP(B).
> 
> * The packet received by B contains only IP(A) & IP(B).
> 
> * The application at B receives only a session-handle.
> 
> * Now, B can simply accept the session-handle and respond with data.
> This would be the typical behavior for a web-server.

In this model, would there be any name piggybacking in the packet at all?
I'm guessing the answer is "yes" based on the comment about authentication
below..

> * Or, if B wants to know more, e.g. the IP and/or the name of the sender
> it needs to query the API asking for it.
> 
> 
> Asking for the IP should be trivial.
> Authenticating the name (with the IP) would most likely come with a
> cost. Either a round-trip to A, or a round-trip to DNS verifying the
> name->IP.

[Assuming that names would still be piggybacked as described in 
http://tools.ietf.org/pdf/draft-ubillos-name-based-sockets]

If the authentication fails, then the action that the authenticator
should take is not clear to me.. in your example, let's say that DNS maps
A.left.org to IP(A) when the connection is set up, and the authentication
attempted by B at that time succeeds. Now at some later point, A
changes its hostname to A1.left.org (but still keeps IP(A)). In a
world where name-resolution is done before connection establishment,
the connection would stay unaffected since it only cares about IP
address (i.e., IP(A)) itself. But in the new proposal, if B tries to
re-authenticate, it will find that authentication of
(name == A.left.org, IP(A)) will fail.  How does B know decide this
was always an invalid name manufactured by the sender, or whether this
"just became invalid"?

> Of course, the initiator could also set requirements for the
> communication.

Please clarify - what sort of requirements?

> This way, all elements become optional, and are only used if the
> application is ready to pay the cost for them.
> In the trivial case, an application is simply only using an API which is
> friendly and not paying the cost for any of the "extra" features.

--Sowmini

---

From: Javier Ubillos <[email-masked]>
Date: Wed, 15 Dec 2010 09:17:09 +0100

> [email-masked] wrote:
<snip>
> I'm guessing the answer is "yes" based on the comment about authentication

The way I picture it, not necessarily. I think that the name-exchange
should be an optional part (perhaps default?). In the exchange above 

Either the initiator (A) starts off with a piggy-backed name-exchange,
or the name exchange is initiated on the responders (B) request. 

Or the name-exchange is simply not used.

The point is to not introduce any extra overhead/costs unless either
side requests something that requires it. 

I suggest the name-exchange should be enabled by default, the
overhead/cost for the name-exchange is negligible unless for certain
very specialized situations.

The short answer is: There would only be name piggybacking if either
side requests it. Both A and B could do this in the above example.

> was always an invalid name manufactured by the sender, or whether this

Good question, I hadn't given that scenario much thought.

What could go wrong is if 
   * B requires authenticated connections.
   * A has name name(a).
   1. A sends a packet to B with a name-exchange.
   2. A changes name to name(a')
   3. B now tries to authenticate A.

My spontaneous answer is that the connection _should_ fail.
If the responder cannot authenticate the packet, it shouldn't accept it.
It could be that A has changed names, but it could also be that the
resolution system does not have a mapping name(A) => A for B (e.g. if
the resolution system is some DHT based solution and A & B are on
different partitions).
Or it could be a phishing attempt.
Assuming that B does require authentication, if the authentication fails
it shouldn't be accepted. Independently if whether the reason is because
a record has "just become invalid" or it is in fact invalid :)

What do you think? Does this make sense?

> Please clarify - what sort of requirements?

I was thinking requirements, both hard and soft as
* Authenticity (of sender)
* Integrity (of data)
* Multi-homing / mobility /multi-path exploitation
* Security (encryption of data)

I can also imagine a scenario where this mechanism becomes even more
flexible and intelligent, but I think it might be a bit premature to
introduce those bits just yet :)

// Javier

---

From: [email-masked]
Date: Wed, 15 Dec 2010 10:45:56 -0500

>    * B requires authenticated connections.

If B is the passive side of the connection, how would it mandate that
it requires authenticated connections e.g., if it got a SYN without
a name, what should it do? (I think this also brings us back to Erik's
original point about exposure to DOS)

> a record has "just become invalid" or it is in fact invalid :)

But what if the authentication fails after several data packets have
been exchanged? How frequently should you reverify the [name(A), A]
mapping?

> * Authenticity (of sender)

of receiver, you mean? Anyway, lots of missing details as you point out
below.

---

From: Javier Ubillos <[email-masked]>
Date: Thu, 16 Dec 2010 12:48:22 +0100

> original point about exposure to DOS)

In the TCP scenario, the SYNACK would include a name-extension header
(or some similar mechanism) with some flag requiring the initiator to
send whatever is necessary for authentication. In the simplest-case this
could be a name-extension header with a resolvable name (FQDN).
As we are still using IP "on-the-wire", and I think the syn-cookies may
not use the names in the hashes, I don't think any new weaknesses are
introduced. 
Host-to-host, each TCP flow must still have it's own four-tuple to avoid
the syn-cookie ordeal. This does mean that the stack needs an internal
coordination (making sure that flows bound to names do not collide in
their four-tuples). I don't think this is  

> been exchanged? How frequently should you reverify the [name(A), A]

That is up to the application.

I don't think names should be re-verified. However, if there would be a
reason for doing this, it could either be triggered/configured by the
application or be a default for whichever name-resolution mecanism one
chooses. In the DNS/FQDN case, I don't see why one would need to
re-verify the mapping during the session. If it is due to impersonation
attacks, I'd suggest the exchange of a nonce. Perhaps this should be
default behavior.

The name-resolution mechanism may provide a level of authenticity in the
first step (whenever the check is made). I would argue that, from that
point and onwards, it is up to the two hosts to maintain the
relationship. I can imagine that some one would want to have a continual
polling of the name->locator mapping, but I cant see what the scenario
would be. Do you have any good case to test the idea with?

> of receiver, you mean? Anyway, lots of missing details as you point out

I was actually thinking in both ways.
If either side requests an authenticity check of the name->locator
mapping of the remote party. The application may just request the check
and then decide what to do (with some sensible default behavior).

And yes, I do leave out a lot of details. Because I don't have all the
details. I'm not trying to push a ready-made proposal, but rather trying
to get a discussion going on what the API/behavior _should_ be.
We do have a prototype (which does not yet reflect the API very well),
but I don't want to insist on having that experiment as a defined
standard.

I welcome more comments on ... everything and anything. There are still
plenty of details to work out, and I think this is the best way of
finding them and working them out.
"The devil is in the details.", and this is the exorcism :)

// Javier

---

From: [email-masked]
Date: Fri, 17 Dec 2010 18:13:22 -0500

On (12/16/10 12:48), Javier Ubillos wrote:
> >=20
> introduced.=20

I'm not sure I see what you have in mind since the details have to be
fleshed out, but I dont see how, for example, B can require authenticatation
of, e.g., udp. 

> re-verify the mapping during the session. If it is due to impersonation

If we store name(A)  with IP(A) for a connection what assertion can we
make about the state of the system at any instant in time: if
name(A) and IP(A) diverge, how does one make sense of the 
observed internal state?

> and is also prepared to pay the cost for that authenticity (typically a

I'd interpret that as 

- a vanilla version of AF_NAME would just move the DNS and addr
  resolution (currently done in user space, to obtain the addrs needed
  for setting up AF_INET[6] sockets) under the hood (i.e., behind the
  socket(..AF_NAME) implementation)

- if the application desires, the API should allow the socket
  end-points to exchange names and do any authentication needed, but
  afaict this can only be done after any intial connection
  setup/validation etc steps have been completed. Also, it seems to me
  that if we associate a name with any connection, that name must also 
  be tied to a "last verified timestamp" of some sort, in order for it
  to be meaningful- that would allow then applications to decide the 
  when/where/how-often of authentication.  Does that make sense?

--Sowmini

---

From: Javier Ubillos <[email-masked]>
Date: Tue, 21 Dec 2010 17:02:34 +0100

>   when/where/how-often of authentication.  Does that make sense?

I think this is a very sensible idea.

The basic question is, is it enough with the name->locator binding being
OK in the beginning of the connection or must it be valid throughout the
connection.

Having a "last verified time-stamp" makes it very explicit that the
name->locator binding was valid at that given point in time.

This leaves it open for a continual polling to the nameing system if
that is what is required by that nameing system and the application.

It also leaves it open to the application to decide whether or not it is
OK to have a valid name->locator binding at the beginning of the
connection or not.

// Javier

---

From: Javier Ubillos <[email-masked]>
Date: Tue, 21 Dec 2010 17:41:51 +0100

> fleshed out, but I dont see how, for example, B can require authenticatation

Good question!

I'm not sure, can one assume that UDP might not be _able_ to have a
two-way communication?
If so, then there would be a clear incompatibility between using UDP and
flow-requirements on the receiving host.

However, if that is the case, that we cannot send _any_ replies to the
UDP stream, then:
a. It becomes impossible to check for bi-lateral support (unless some
other channel is used).
b. It becomes impossible to exchange names and/or preferences.

Assuming that we _can_ have a bi-directional communication. The
UDP-version could very well include some kind of feedback mechanism
where names & preferences are sent back to the initiator.

Is it a crazy idea to subdivide the data-gram domain into truly
uni-directional flows and flows where we can have a bi-directional flow?

// Javier

---

From: Brian E Carpenter <[email-masked]>
Date: Wed, 22 Dec 2010 08:38:16 +1300

...
> OK to have a valid name->locator binding at the beginning of the

As is noted in draft-carpenter-referral-ps, these bindings
(and even nameless locators) have finite lifetimes, known at their
point of origin (from DHCP, SLAAC, DNS TTL, etc.) The problem shouldn't
be stated as timestamps or a need for polling. Quoting that draft:
"A referral that does not convey the lifetime associated with
an address is problematic." The lifetime should be carried with
the binding, and counted down locally.

      Brian

---

From: [email-masked]
Date: Tue, 21 Dec 2010 15:58:18 -0500

> I'm not sure, can one assume that UDP might not be _able_ to have a

UDP was just one example of a connectionless protocol that I suggested,
but I think the more critical thing (which is what I thought was
discussed in the meeting with Erik, perhaps he can clarify..) is that
you shouldn't (can't?) try to enforce name exchange/authentication at
the initial packet exchange, but rather let the application drive
this..

> b. It becomes impossible to exchange names and/or preferences.

not impossible.. in the udp example, the application that consumes
the udp packet can trigger (b) at its discretion (the actual mechanics
of how it will be done are TBD, but hopefully it would not be ULP-specific).

---

From: Javier Ubillos <[email-masked]>
Date: Wed, 22 Dec 2010 11:12:49 +0100

> the binding, and counted down locally.

That sounds great.
Given that the application (on either side) actually does want
authenticity in the name->locator binding:
Letting the naming-system/referral-mechanism manage this, and that a
client MUST verify and renew the lifetime of the name->locator binding
sounds healthy to me.

// Javier

---

From: Javier Ubillos <[email-masked]>
Date: Wed, 22 Dec 2010 13:47:18 +0100

> the initial packet exchange, but rather let the application drive

I completely agree. This is only an issue _if_ either side does ask the
socket for more than just the basics.
Yes, it should be optional.
However, the original question was _if_ it was possible for "B" (the
recipient) to require authentication.

Perhaps a set of scenarios would be good as a basis for discussion.
I'll try to whip a few together, and perhaps we can build from there.
(I'll also try to take time to update the draft that as I promised I
would earlier :)

> of how it will be done are TBD, but hopefully it would not be ULP-specific).

I'm not sure the following assertion stands any more, but:
Initially, in name-based sockets, we decided that all connections should
use connection-oriented semantics (read TCP semantics).

I'm not sure if this still stands. But if it does, then providing an API
where the application may attempt to request more from the socket.
If a two-way connection is possible, those requests might succeed. If
not, then it'll just fail and the application will have to make some
decision about it.

In short.
Should the API-semantics be connection-oriented?
Let's provide an API, including functions that require bi-lateral
support. If the calls fail, let the application make a decision.

// Javier