From 11b0a82c4a6ad71fce12a7e227dc2356025e62da Mon Sep 17 00:00:00 2001 From: cathugger Date: Sun, 29 Jul 2018 22:09:16 +0000 Subject: [PATCH] Simpler flowlabel parsing; avoid using 0 flowlabel. --- src/yggdrasil/session.go | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 417760b7..647bb0ce 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -425,28 +425,28 @@ func (sinfo *sessionInfo) doSend(bs []byte) { if !sinfo.init { return } // To prevent using empty session keys - // Now we append something to the coords - // Specifically, we append a 0, and then arbitrary data - // The 0 ensures that the destination node switch forwards to the self peer (router) - // The rest is ignored, but it's still part as the coords, so it affects switch queues - // This helps separate traffic streams (coords, flowlabel) to be queued independently + var coords []byte - addUint64 := func(bs []byte) { - // Converts bytes to a uint64 - // Converts that back to variable length bytes - // Appends it to coords - var u uint64 - for _, b := range bs { - u <<= 8 - u |= uint64(b) - } - coords = append(coords, wire_encode_uint64(u)...) + // Read IPv6 flowlabel field (20 bits). + // XXX(cathugger): is len(bs) validated there? + flowlabel := uint(bs[1]&0x0f)<<16 | uint(bs[2])<<8 | uint(bs[3]) + if flowlabel != 0 { + // Now we append something to the coords + // Specifically, we append a 0, and then arbitrary data + // The 0 ensures that the destination node switch forwards to the self peer (router) + // The rest is ignored, but it's still part as the coords, so it affects switch queues + // This helps separate traffic streams (coords, flowlabel) to be queued independently + + coords = append(coords, sinfo.coords...) // Start with the real coords + coords = append(coords, 0) // Then target the local switchport + coords = append(coords, wire_encode_uint64(uint64(flowlabel))...) // Then variable-length encoded flowlabel + } else { + // 0 value means that flowlabels aren't being generated by OS. + // To save bytes, we're not including it, therefore we won't need self-port override either. + // So just use sinfo.coords directly to avoid golang GC allocations. + // XXX: investigate where flowlabels aren't included, and attempt to look into TCP/UDP/SCTP/DCCP headers' sport/dport fields? + coords = sinfo.coords } - coords = append(coords, sinfo.coords...) // Start with the real coords - coords = append(coords, 0) // Then target the local switchport - flowlabel := append([]byte(nil), bs[1:4]...) - flowlabel[0] &= 0x0f - addUint64(flowlabel) payload, nonce := boxSeal(&sinfo.sharedSesKey, bs, &sinfo.myNonce) defer util_putBytes(payload) p := wire_trafficPacket{