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:
parent
92dbb48eda
commit
36e4ce4b0b
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user