mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 09:30:28 +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:
parent
92dbb48eda
commit
36e4ce4b0b
@ -243,8 +243,25 @@ func (p *peer) _handleTraffic(packet []byte) {
|
|||||||
// Drop traffic if the peer isn't in the switch
|
// Drop traffic if the peer isn't in the switch
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, coords := wire_getTrafficOffsetAndCoords(packet)
|
obs, coords := wire_getTrafficOffsetAndCoords(packet)
|
||||||
next := p.table.lookup(coords)
|
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 {
|
if nPeer, isIn := p.ports[next]; isIn {
|
||||||
nPeer.sendPacketFrom(p, packet)
|
nPeer.sendPacketFrom(p, packet)
|
||||||
}
|
}
|
||||||
|
@ -631,13 +631,11 @@ func (t *switchTable) start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *lookupTable) lookup(coords []byte) switchPort {
|
func (t *lookupTable) lookup(ports []switchPort) switchPort {
|
||||||
var offset int
|
|
||||||
here := &t._start
|
here := &t._start
|
||||||
for offset < len(coords) {
|
for idx := range ports {
|
||||||
port, l := wire_decode_uint64(coords[offset:])
|
port := ports[idx]
|
||||||
offset += l
|
if next, ok := here.next[port]; ok {
|
||||||
if next, ok := here.next[switchPort(port)]; ok {
|
|
||||||
here = next
|
here = next
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@ -645,3 +643,43 @@ func (t *lookupTable) lookup(coords []byte) switchPort {
|
|||||||
}
|
}
|
||||||
return here.port
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user