Subject: [Spud] SPUD magic number

From: Tom Herbert <[email-masked]>
Date: Thu, 9 Apr 2015 19:35:47 -0700

Hi,

The SPUD magic number seems like a good idea and in fact I anticipate
that we'll want to adopt this technique in other UDP encapsulation
protocols.

I believe the magic number could be applied in two different ways:

1) A middlebox must match both the UDP destination port and the magic
number before accepting the packet is SPUD protocol. In this case ,
the magic number is used to distinguish SPUD from other arbitrary uses
of a SPUD assigned port.
2) A middlebox matches the magic number in any UDP packet regardless
of destination port and declares it to be SPUD. This is nice because
we would not need to configure SPUD ports on middleboxes, but
increases the chances of misinterpreting something which is not SPUD
at all (a larger magic number size might be warranted).

What is the intended use for this in the SPUD prototype protocol?

Thanks,
Tom

---

From: "Pal Martinsen (palmarti)" <[email-masked]>
Date: Fri, 10 Apr 2015 07:12:47 +0000

> On 10 Apr 2015, at 04:35, Tom Herbert <[email-masked]> wrote:
> 
> Hi,
> 
+1

STUN (RFC5389) also uses this trick in section 6 (https://tools.ietf.org/html/rfc5389#section-6)

> What is the intended use for this in the SPUD prototype protocol?
This was actually the first bet we implemented (https://github.com/iptube/SPUDlib). Mostly due to your 2) bullet point. 

It allowed us to quickly get a linux router with netfiletr/iptables up and running with the following rule:

-A PREROUTING -p udp —match u32 --u32 "0>>22&0x3C@8=0xd80000d8" -j NFQUEUE --queue-num 0

See https://github.com/iptube/TubeNode for a quick and dirty implementation.

From a client perspective lessons learned from implementing ICE and STUN where RTP, STUN and vide variety of other packets might be multiplexed on the same port was that having a simple isSPUD function is really useful..

In the spud prototype it is defined like this:

bool spud_is_spud(const uint8_t *payload, size_t length)
{
    if (length < sizeof(spud_header)) {
        return false;
    }
    return (memcmp(payload, (void *)SpudMagicCookie, SPUD_MAGIC_COOKIE_SIZE) == 0);
}

.-.
Pål-Erik

> Thanks,
> Tom
> 
> _______________________________________________
> Spud mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/spud

---

From: Tom Herbert <[email-masked]>
Date: Fri, 10 Apr 2015 10:26:34 -0700

> This was actually the first bet we implemented (https://github.com/iptube/SPUDlib). Mostly due to your 2) bullet point.
32 bits seems a little light to me for this usage #2, especially if
when some application packet inadvertently matches the magic number
packet is dropped when it would have otherwise been accepted if magic
numbers weren't being checked. 64 bits might be safer.

For UDP encapsulations (GUE, Geneve, VXLAN, etc), we probably would
the magic number to be optional since we'll already have a port number
to identify the protocol (at the client) and might not need middlebox
support within a data center. To make the magic number optional, we
need a way to distinguish the magic number from a valid encapsulation
header. I was thinking to set the first byte of magic number to 0xff
and declaring that indicates an invalid header for the encapsulation
protocol. 0xff works nicely since most of the new UDP encapsulations
have a version number in the first byte and haven't got past version
zero, so this gives forward compatibility.

Tom

---

From: Toerless Eckert <[email-masked]>
Date: Fri, 10 Apr 2015 10:33:02 -0700

In STUN/ICE there is also a checksum that can be checked. That
gives 32 bit for extraction from HW for CMDs, and then
another 32 bits of checksum to be done in SW, so that you
ultimately only had 1/2^64 for false positives. Unless somebody
explains me why not, i would recommend such a checksum for
SPUD cmd != 0 packets as well.

The 1/2^64 certainty + parsing of packets should then be good enough
to protect any middlebox action that could happen on cmd = 0 packets,
because for any middlebox action that needs a really high certainty
that it is really SPUD traffic, the cmd != 0 packets could be
used to learn the tube ID, and later on the packet cmd = 0
recognition could be based on the 96 bits of cookie + tun-ID.

Cheers
    Toerless

On Fri, Apr 10, 2015 at 07:12:47AM +0000, Pal Martinsen (palmarti) wrote:
> -A PREROUTING -p udp ???match u32 --u32 "0>>22&0x3C@8=0xd80000d8" -j NFQUEUE --queue-num 0
>

---

From: Toerless Eckert <[email-masked]>
Date: Fri, 10 Apr 2015 10:48:52 -0700

> numbers weren't being checked. 64 bits might be safer.

See my last email of how we ultimately would get 1/2^96 false
positive in middleboxes that are keeping today per-flow state
and with SPUD would do per-tube state.

> support within a data center.

Even if just meant to be used for end-to-end signaling, i would not
remove the cookie. Its still very helpfull for end-to-end communication,
especially for any communication where it is not upfront clear whether
SPUD is used or not. And if there is prior signaling that makes
the endpoints know SPUD is used, then the cookie is easy to skip.
And hopefully the 32 bits are not going to be so valuable space
(SPUD tax..) that we need to make them optional.

I think the most important design goal should be to ensure that it
is easy for middleboxes to distinguish different type of "awareness"
int SPUD traffic, so that a middlebox would only need to inspect what
it is intersted in.

For example: A middlebox that ONLY wants to do a lightweight tracking
of flows would simply set up snoop punt entry in the forwarding plane
for cookie+cmd=01, cookie+cmd=02, cookie+cmd=03. And it would
never see data packets, but just connection setup/teardown.

With this in mind, i think it would be a lot better if SPUD had 8 bit
of CMD, and that would give us the ability to distinguish additional
levels of awareness through additional new CMDs, and only the middleboxes
interested in those commands would have to snoop those command packets
its interested in. And we could of course also simply say that the
high order bit = 0 or 1 is an indication whether middleboxes are
allowed to look at (and potentially modify) the packet. 

Cheers
    Toerless

-- 
---
Toerless Eckert, [email-masked]