diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 8631ff22..f1ee92a7 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -425,10 +425,33 @@ 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 (protocol + source + dest port) are 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)...) + } + coords = append(coords, sinfo.coords...) // Start with the real coords + coords = append(coords, 0) // Add an explicit 0 for the destination's self peer + addUint64(bs[6:7]) // Byte 6, next header type (e.g. TCP vs UDP) + // TODO parse headers, in case the next header isn't TCP/UDP for some reason + addUint64(bs[40:42]) // Bytes 40-41, source port for TCP/UDP + addUint64(bs[42:44]) // Bytes 42-43, destination port for TCP/UDP payload, nonce := boxSeal(&sinfo.sharedSesKey, bs, &sinfo.myNonce) defer util_putBytes(payload) p := wire_trafficPacket{ - Coords: sinfo.coords, + Coords: coords, Handle: sinfo.theirHandle, Nonce: *nonce, Payload: payload, diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index 6fe50bf3..63380dad 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -529,24 +529,13 @@ func switch_getPacketCoords(packet []byte) []byte { } // Returns a unique string for each stream of traffic -// Equal to type+coords+handle for traffic packets -// Equal to type+coords+toKey+fromKey for protocol traffic packets +// Equal to coords +// The sender may append arbitrary info to the end of coords (as long as it's begins with a 0x00) to designate separate traffic streams +// Currently, it's the IPv6 next header type and the first 2 uint16 of the next header +// This is equivalent to the TCP/UDP protocol numbers and the source / dest ports +// TODO figure out if something else would make more sense (other transport protocols?) func switch_getPacketStreamID(packet []byte) string { - pType, pTypeLen := wire_decode_uint64(packet) - _, coordLen := wire_decode_coords(packet[pTypeLen:]) - end := pTypeLen + coordLen - switch { - case pType == wire_Traffic: - end += handleLen // handle - case pType == wire_ProtocolTraffic: - end += 2 * boxPubKeyLen - default: - end = 0 - } - if end > len(packet) { - end = len(packet) - } - return string(packet[:end]) + return string(switch_getPacketCoords(packet)) } // Handle an incoming packet