Subject: [pcp] How can I make a ~stateless forwarding PCP proxy again?

From: Markus Stenberg <[email-masked]>
Date: Mon, 5 May 2014 19:59:32 +0200

Let’s assume I have client, proxy, and server. Proxy isn’t even firewall, nor is it NAT. 

[1] Client sends to proxy (first-hop router).  Proxy replaces internal IP with it’s own, adds THIRD_PARTY, and forwards to real server it decides based on magic.

[2] Server sends back response to proxy.

[3] Proxy has no per-client state, and drops packet as it can’t find client’s address from anywhere.

Motivation:

For homenet use cases, for inner routers within home, you _won’t_ want actually firewall or NAT to be involved, but you _do_ need a proxy to make decisions about which CER to talk to with different source addresses as it’s not really addressed by current solutions and routers know more about network topology changes than the client will in any case.

For example, IPv4 uplink may change somewhere ‘in the network’, and current PCP client implementations I play with wouldn’t even know about how to learn of it, not to even mention react to it. This is reality in my NAT-‘enabled’ home, as at a time I have only one upstream NAT active, but it may change, based on active-standby model (and yes, it could be on different routers).

As another example, IPv6 traffic within a home network is routed based on source prefix, but I have yet to see PCP client implementation that does server selection based on this (is it even specified?).  Yet making firewall holes would be still nice.

As I _do_ control both (mostly fictional) proxy implementation as well as the (mostly functional) server implementation, my current plan is to add option which just contains client’s address at proxy, and strip it on way back from proxy to client. Is there a better solution?

Cheers,

-Markus

P.S. I’ll accept that it’s host’s responsibility always if and only if every device (mostly with fruity logo on them) on my home that talks PCP actually deals with this stuff somehow magically. I’m not holding my breath, though.

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Mon, 5 May 2014 19:41:22 +0000

Hi Markus,

we had this discussion in the past but and I, for one, backed the idea of PCP being able to support stateless proxies.  So, you are not alone there but maybe you want to write a draft about it so the WG can discuss it.

thanks,

Reinaldo

________________________________________
From: pcp [[email-masked]] on behalf of Markus Stenberg [[email-masked]]
Sent: Monday, May 05, 2014 10:59 AM
To: [email-masked]
Subject: [pcp] How can I make a ~stateless forwarding PCP proxy again?

Motivation:

Cheers,

-Markus

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

---

From: Markus Stenberg <[email-masked]>
Date: Mon, 5 May 2014 22:14:57 +0200

> we had this discussion in the past but and I, for one, backed the idea of PCP being able to support stateless proxies.  So, you are not alone there but maybe you want to write a draft about it so t…

Nods. Personally I like to minimize the amount of state in a system, so I’m a fan of stateless designs. My current design for a proxy has just 3 logical pieces of ‘state’ per supported remote server:

- (client) source prefix + prefix length to match
- address of the server
- server epoch + when was it received

And currently I’m trying to make sure it’s actually doable to do all I want with just that and few hundred lines of C. After looking at how big PCP client libraries are, last thing I want is really PCP client glued to PCP server.

Getting back to my previous question, now that I think of it, actually, the IP address of the client is in the THIRD_PARTY option. Only thing that isn’t explicitly stored somewhere is the address client contacts the proxy on (it probably has 1-N addresses per M interfaces). If proxy uses same source address for talking with server as client used to contact it (with different port, obviously), it should work fine, without per-client or per-request state. 

e.g.

C -> P [IntIP=C]
P -> S [IntIP=P, TP=C]
S -> P [TP=C]
P -> C [no TP]

Beyond that, some ANNOUNCE handling is needed, but as long as you stick to multicast, that can be also stateless. (Connected clients know if they have state with the particular proxy that spams ANNOUNCEs.)

Perhaps I’ll write up about it somewhere (pcp or homenet), although it’s more of an implementation detail draft, than actual protocol change requiring one.

Cheers,

-Markus

P.S. This scheme works fine with IPv4. With IPv6, it may have issues, when C contacts P using link-local address and I don’t think there is anything preventing that. P is probably unable to contact S using that. Oh well. I guess doing other IPv6 scopes would work, and falling back to IPv4 if client doesn’t do DHCP*/RA/something else option to learn the IPv6 GUA/ULA of the proxy on first hop.

---

From: "Reinaldo Penno (repenno)" <[email-masked]>
Date: Mon, 5 May 2014 21:38:04 +0000

"Getting back to my previous question, now that I think of it, actually, the IP address of the client is in the THIRD_PARTY option. Only thing that isn’t explicitly stored somewhere is the address client contacts the proxy on (it probably has 1-N addresses per M interfaces)."

Yes, but I believe in the current back-to-back proxy proposal (newest draft) the third party option would/should be completely removed by the proxy before forwarding a message.
 
________________________________________
From: Markus Stenberg [[email-masked]]
Sent: Monday, May 05, 2014 1:14 PM
To: Reinaldo Penno (repenno)
Cc: Markus Stenberg; [email-masked]
Subject: Re: [pcp] How can I make a ~stateless forwarding PCP proxy again?

e.g.

C -> P [IntIP=C]
P -> S [IntIP=P, TP=C]
S -> P [TP=C]
P -> C [no TP]

Cheers,

-Markus

---

From: Markus Stenberg <[email-masked]>
Date: Tue, 6 May 2014 00:03:26 +0200

> Yes, but I believe in the current back-to-back proxy proposal (newest draft) the third party option would/should be completely removed by the proxy before forwarding a message.

Well, it actually behaves the same way what I said - it _does_ (in firewall case) insert THIRD_PARTY options on way to server and back. Only difference is that in my case, I don’t even want to think of being a NAT that proxies requests onward (I’m sure you need lots of state at that point and the content of the current draft seems focused mostly on that).

I wonder if someone’s implemented the back-to-back draft yet? It looks like a lot of work. The minimal state design I sketched is about 500 LoC of C[1] (with quite short line lengths too, debug messages, etc that I wrote today). Perhaps it would be a bit more if I actually bother to send ANNOUNCEs some day, but not much.

And that’s all you really need, given

a) you don’t want to cascade that proxy (you can’t have multiple THIRD_PARTY options)

b) you can live with ‘someone else’ having the control of server selection and PCP-forwarder being just dumb element following orders.

Perhaps I’ll write a draft on my thoughts on homenet + PCP angle for the next IETF (sigh, too full calendar, but one day of hacking this was amusing enough).

Cheers,

-Markus

[1] https://github.com/fingon/minimalist-pcproxy

---

From: Dan Wing <[email-masked]>
Date: Mon, 5 May 2014 23:01:31 -0700

On May 5, 2014, at 1:14 PM, Markus Stenberg <[email-masked]> wrote:

> P.S. This scheme works fine with IPv4. With IPv6, it may have issues, when C contacts P using link-local address and I don’t think there is anything preventing that.

Correct, nothing prevents it.  But C is unable to show it owns another address (so can't use THIRD_PARTY), and link-local doesn't do anything on the other side of the router (firewall), so seems fruitless for C's PCP client to use link local.  I would even think P or any PCP server should just return an error if the PCP request came from an IPv6 link local address and the proxy (or PCP server) is not doing NPTv6 or NAT66.  Link local can't go anywhere, so seems an error no matter if proxy or PCP server returns an error -- link-local won't do any good as a firewall rule because it isn't routable from the Internet.

-d

> P is probably unable to contact S using that. Oh well. I guess doing other IPv6 scopes would work, and falling back to IPv4 if client doesn’t do DHCP*/RA/something else option to learn the IPv6 GUA/ULA of the proxy on first hop.
> 
>

---

From: <[email-masked]>
Date: Tue, 6 May 2014 11:48:08 +0200

Hi Markus,

It seems that your design is close to what is documented in http://tools.ietf.org/html/draft-ietf-pcp-proxy-04#section-8, no?

FWIW, the heaviness of the b2b model was raised in slide 6 of http://tools.ietf.org/agenda/89/slides/slides-89-pcp-4.pdf but I don't know what was the outcome of that discussion.

Cheers,
Med

>-----Message d'origine-----
>De : pcp [mailto:[email-masked]] De la part de Markus Stenberg
>Envoyé : lundi 5 mai 2014 22:15
>À : Reinaldo Penno (repenno)
>Cc : [email-masked]
>Objet : Re: [pcp] How can I make a ~stateless forwarding PCP proxy again?
>
>> we had this discussion in the past but and I, for one, backed the idea of
>PCP being able to support stateless proxies.  So, you are not alone there
>but maybe you want to write a draft about it so the WG can discuss it.
>
>
>Nods. Personally I like to minimize the amount of state in a system, so I'm
>a fan of stateless designs. My current design for a proxy has just 3
>logical pieces of 'state' per supported remote server:
>
>And currently I'm trying to make sure it's actually doable to do all I want
>with just that and few hundred lines of C. After looking at how big PCP
>client libraries are, last thing I want is really PCP client glued to PCP
>server.
>
>Getting back to my previous question, now that I think of it, actually, the
>IP address of the client is in the THIRD_PARTY option. Only thing that
>isn't explicitly stored somewhere is the address client contacts the proxy
>on (it probably has 1-N addresses per M interfaces). If proxy uses same
>source address for talking with server as client used to contact it (with
>different port, obviously), it should work fine, without per-client or per-
>request state.
>
>e.g.
>
>C -> P [IntIP=C]
>P -> S [IntIP=P, TP=C]
>S -> P [TP=C]
>P -> C [no TP]
>
>Beyond that, some ANNOUNCE handling is needed, but as long as you stick to
>multicast, that can be also stateless. (Connected clients know if they have
>state with the particular proxy that spams ANNOUNCEs.)
>
>Perhaps I'll write up about it somewhere (pcp or homenet), although it's
>more of an implementation detail draft, than actual protocol change
>requiring one.
>
>Cheers,
>
>-Markus
>
>P.S. This scheme works fine with IPv4. With IPv6, it may have issues, when
>C contacts P using link-local address and I don't think there is anything
>preventing that. P is probably unable to contact S using that. Oh well. I
>guess doing other IPv6 scopes would work, and falling back to IPv4 if
>client doesn't do DHCP*/RA/something else option to learn the IPv6 GUA/ULA
>of the proxy on first hop.
>
>

---

From: Markus Stenberg <[email-masked]>
Date: Wed, 7 May 2014 19:26:16 +0200

> FWIW, the heaviness of the b2b model was raised in slide 6 of http://tools.ietf.org/agenda/89/slides/slides-89-pcp-4.pdf but I don't know what was the outcome of that discussion.

It’s perhaps similar, yes. There are differences, though, in which it’s also somewhat similar to the current proxy draft (own epoch tracking, multiple servers,  etc). I wrote it up in a rather brief draft here - comments and criticism welcome:

http://tools.ietf.org/html/draft-stenberg-homenet-minimalist-pcp-proxy-00

I’m not really sure I’m going to push that in homenet (or here), but I am tinkering with an implementation and seeing if it fulfills the need I have in homenet cases where I need PCP proxying (as opposed to the full-blown draft-ietf-pcp-proxy-05).

Cheers,

-Markus

---

From: Markus Stenberg <[email-masked]>
Date: Wed, 14 May 2014 13:50:11 +0300

On 6.5.2014, at 9.01, Dan Wing <[email-masked]> wrote:
> Correct, nothing prevents it.  But C is unable to show it owns another address (so can't use THIRD_PARTY), and link-local doesn't do anything on the other side of the router (firewall), so seems fruitless for C's PCP client to use link local.  I would even think P or any PCP server should just return an error if the PCP request came from an IPv6 link local address and the proxy (or PCP server) is not doing NPTv6 or NAT66.  Link local can’t go anywhere, so seems an error no matter if proxy or PCP server returns an error -- link-local won't do any good as a firewall rule because it isn't routable from the Internet.

The main problem is if this happens:

C uses GUA IPv6 address
 .. and has only link-local next-hop route to P to find IPv6 PCP server
=> contacts P with src = GUA, dst = link-local

=> P cannot meaningfully forward it to S using src = C’s linklocal.

I’m not sure how IPv6 PCP in general should work (I haven’t seen that many implementations of it in the wild), is it supposed to work only given DHCP* option?

Cheers,

-Markus

---

From: Markus Stenberg <[email-masked]>
Date: Wed, 14 May 2014 13:55:15 +0300

> => P cannot meaningfully forward it to S using src = C’s linklocal.

Argh. Should’ve reread what I wrote. It should have been:

using src = P’s linklocal that is (so that the reverse chain towards C will be able to get the address from the reply’s dst).

Having looked at various ways on how e.g. homenet solution can work, there’s few different ways to do it. This limited minimalist stateless proxy may not be the long-term correct way, but I’m not convinced we’ll see good working general-purpose proxies any time soon either.

(And of course I’m hoping to be proven wrong, and in open source, preferably..)

Cheers,

-Markus