5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-23 07:35:39 +00:00

WIP rough implementation of the source routed part of hybrid routing, does not work if coord length is too long (>127 hops)

This commit is contained in:
Arceliar 2020-11-07 07:10:13 -06:00
parent 92dbb48eda
commit 36e4ce4b0b
2 changed files with 63 additions and 8 deletions

View File

@ -243,8 +243,25 @@ func (p *peer) _handleTraffic(packet []byte) {
// Drop traffic if the peer isn't in the switch
return
}
_, coords := wire_getTrafficOffsetAndCoords(packet)
next := p.table.lookup(coords)
obs, coords := wire_getTrafficOffsetAndCoords(packet)
offset, _ := wire_decode_uint64(obs)
ports := p.table.getPorts(coords)
if offset == 0 {
offset = p.table.getOffset(ports)
}
var next switchPort
if offset == 0 {
// Greedy routing, find the best next hop
next = p.table.lookup(ports)
} else {
// Source routing, read next hop from coords and update offset/obs
if int(offset) < len(ports) {
next = ports[offset]
offset += 1
// FIXME this breaks if offset is > 127, it's just for testing
wire_put_uint64(offset, obs[:0])
}
}
if nPeer, isIn := p.ports[next]; isIn {
nPeer.sendPacketFrom(p, packet)
}

View File

@ -631,13 +631,11 @@ func (t *switchTable) start() error {
return nil
}
func (t *lookupTable) lookup(coords []byte) switchPort {
var offset int
func (t *lookupTable) lookup(ports []switchPort) switchPort {
here := &t._start
for offset < len(coords) {
port, l := wire_decode_uint64(coords[offset:])
offset += l
if next, ok := here.next[switchPort(port)]; ok {
for idx := range ports {
port := ports[idx]
if next, ok := here.next[port]; ok {
here = next
} else {
break
@ -645,3 +643,43 @@ func (t *lookupTable) lookup(coords []byte) switchPort {
}
return here.port
}
func (t *lookupTable) getPorts(coords []byte) []switchPort {
var ports []switchPort
var offset int
for offset < len(coords) {
port, l := wire_decode_uint64(coords[offset:])
offset += l
ports = append(ports, switchPort(port))
}
return ports
}
func (t *lookupTable) isDescendant(ports []switchPort) bool {
// Note that this returns true for anyone in the subtree that starts at us
// That includes ourself, so we are our own descendant by this logic...
if len(t.self.coords) >= len(ports) {
// Our coords are longer, so they can't be our descendant
return false
}
for idx := range t.self.coords {
if ports[idx] != t.self.coords[idx] {
return false
}
}
return true
}
func (t *lookupTable) getOffset(ports []switchPort) uint64 {
// If they're our descendant, this returns the length of our coords, used as an offset for source routing
// If they're not our descendant, this returns 0
var offset uint64
for idx := range t.self.coords {
if idx < len(ports) && ports[idx] == t.self.coords[idx] {
offset += 1
} else {
return 0
}
}
return offset
}