mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03: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
					
				
					 2 changed files with 63 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue