mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Switch connAddr (udp map key) from string to a struct that allocates less. Reduce some other allocations. Use larger channel buffers to reduce backpressure from runtime jitter.
This commit is contained in:
		
							parent
							
								
									ef1e0c902f
								
							
						
					
					
						commit
						75965b6da4
					
				
					 6 changed files with 60 additions and 28 deletions
				
			
		| 
						 | 
				
			
			@ -274,9 +274,14 @@ func (c *Core) DEBUG_getGlobalUDPAddr() net.Addr {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (c *Core) DEBUG_maybeSendUDPKeys(saddr string) {
 | 
			
		||||
	addr := connAddr(saddr)
 | 
			
		||||
	udpAddr, err := net.ResolveUDPAddr("udp", saddr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	var addr connAddr
 | 
			
		||||
	addr.fromUDPAddr(udpAddr)
 | 
			
		||||
	c.udp.mutex.RLock()
 | 
			
		||||
	_, isIn := c.udp.conns[connAddr(addr)]
 | 
			
		||||
	_, isIn := c.udp.conns[addr]
 | 
			
		||||
	c.udp.mutex.RUnlock()
 | 
			
		||||
	if !isIn {
 | 
			
		||||
		c.udp.sendKeys(addr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,10 +171,10 @@ func (p *peer) handleTraffic(packet []byte, pTypeLen int) {
 | 
			
		|||
	if to == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	newTTLSlice := wire_encode_uint64(newTTL)
 | 
			
		||||
	newTTLLen := wire_uint64_len(newTTL)
 | 
			
		||||
	// This mutates the packet in-place if the length of the TTL changes!
 | 
			
		||||
	shift := ttlLen - len(newTTLSlice)
 | 
			
		||||
	copy(packet[ttlBegin+shift:], newTTLSlice)
 | 
			
		||||
	shift := ttlLen - newTTLLen
 | 
			
		||||
	wire_put_uint64(newTTL, packet[ttlBegin+shift:])
 | 
			
		||||
	copy(packet[shift:], packet[:pTypeLen])
 | 
			
		||||
	packet = packet[shift:]
 | 
			
		||||
	to.sendPacket(packet)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ type router struct {
 | 
			
		|||
func (r *router) init(core *Core) {
 | 
			
		||||
	r.core = core
 | 
			
		||||
	r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
 | 
			
		||||
	in := make(chan []byte, 1)                                // TODO something better than this...
 | 
			
		||||
	in := make(chan []byte, 1024)                             // TODO something better than this...
 | 
			
		||||
	p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub) //, out, in)
 | 
			
		||||
	// TODO set in/out functions on the new peer...
 | 
			
		||||
	p.out = func(packet []byte) { in <- packet } // FIXME in theory it blocks...
 | 
			
		||||
| 
						 | 
				
			
			@ -50,8 +50,8 @@ func (r *router) init(core *Core) {
 | 
			
		|||
	// TODO attach these to the tun
 | 
			
		||||
	//  Maybe that's the core's job...
 | 
			
		||||
	//  It creates tun, creates the router, creates channels, sets them?
 | 
			
		||||
	recv := make(chan []byte, 1)
 | 
			
		||||
	send := make(chan []byte, 1)
 | 
			
		||||
	recv := make(chan []byte, 1024)
 | 
			
		||||
	send := make(chan []byte, 1024)
 | 
			
		||||
	r.recv = recv
 | 
			
		||||
	r.send = send
 | 
			
		||||
	r.core.tun.recv = recv
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -164,8 +164,8 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo {
 | 
			
		|||
	sinfo.myHandle = *newHandle()
 | 
			
		||||
	sinfo.theirAddr = *address_addrForNodeID(getNodeID(&sinfo.theirPermPub))
 | 
			
		||||
	sinfo.theirSubnet = *address_subnetForNodeID(getNodeID(&sinfo.theirPermPub))
 | 
			
		||||
	sinfo.send = make(chan []byte, 1)
 | 
			
		||||
	sinfo.recv = make(chan *wire_trafficPacket, 1)
 | 
			
		||||
	sinfo.send = make(chan []byte, 1024)
 | 
			
		||||
	sinfo.recv = make(chan *wire_trafficPacket, 1024)
 | 
			
		||||
	go sinfo.doWorker()
 | 
			
		||||
	sinfo.time = time.Now()
 | 
			
		||||
	// Do some cleanup
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,8 +21,31 @@ type udpInterface struct {
 | 
			
		|||
	conns map[connAddr]*connInfo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type connAddr string // TODO something more efficient, but still a valid map key
 | 
			
		||||
//type connAddr string // TODO something more efficient, but still a valid map key
 | 
			
		||||
 | 
			
		||||
type connAddr struct {
 | 
			
		||||
	ip   [16]byte
 | 
			
		||||
	port int
 | 
			
		||||
	zone string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *connAddr) fromUDPAddr(u *net.UDPAddr) {
 | 
			
		||||
	copy(c.ip[:], u.IP.To16())
 | 
			
		||||
	c.port = u.Port
 | 
			
		||||
	c.zone = u.Zone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *connAddr) toUDPAddr() *net.UDPAddr {
 | 
			
		||||
	var u net.UDPAddr
 | 
			
		||||
	u.IP = make([]byte, 16)
 | 
			
		||||
	copy(u.IP, c.ip[:])
 | 
			
		||||
	u.Port = c.port
 | 
			
		||||
	u.Zone = c.zone
 | 
			
		||||
	return &u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type connInfo struct {
 | 
			
		||||
	name     string
 | 
			
		||||
	addr     connAddr
 | 
			
		||||
	peer     *peer
 | 
			
		||||
	linkIn   chan []byte
 | 
			
		||||
| 
						 | 
				
			
			@ -54,10 +77,7 @@ func (iface *udpInterface) init(core *Core, addr string) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (iface *udpInterface) sendKeys(addr connAddr) {
 | 
			
		||||
	udpAddr, err := net.ResolveUDPAddr("udp", string(addr))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	udpAddr := addr.toUDPAddr()
 | 
			
		||||
	msg := []byte{}
 | 
			
		||||
	msg = udp_encode(msg, 0, 0, 0, nil)
 | 
			
		||||
	msg = append(msg, iface.core.boxPub[:]...)
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +111,7 @@ func (iface *udpInterface) startConn(info *connInfo) {
 | 
			
		|||
		close(info.linkIn)
 | 
			
		||||
		close(info.keysIn)
 | 
			
		||||
		close(info.out)
 | 
			
		||||
		iface.core.log.Println("Removing peer:", info.addr)
 | 
			
		||||
		iface.core.log.Println("Removing peer:", info.name)
 | 
			
		||||
	}()
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
| 
						 | 
				
			
			@ -135,11 +155,13 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
	conn, isIn := iface.conns[addr]
 | 
			
		||||
	iface.mutex.RUnlock() // TODO? keep the lock longer?...
 | 
			
		||||
	if !isIn {
 | 
			
		||||
		udpAddr, err := net.ResolveUDPAddr("udp", string(addr))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		udpAddr := addr.toUDPAddr()
 | 
			
		||||
		themNodeID := getNodeID(&ks.box)
 | 
			
		||||
		themAddr := address_addrForNodeID(themNodeID)
 | 
			
		||||
		themAddrString := net.IP(themAddr[:]).String()
 | 
			
		||||
		themString := fmt.Sprintf("%s@%s", themAddrString, udpAddr.String())
 | 
			
		||||
		conn = &connInfo{
 | 
			
		||||
			name:   themString,
 | 
			
		||||
			addr:   connAddr(addr),
 | 
			
		||||
			peer:   iface.core.peers.newPeer(&ks.box, &ks.sig),
 | 
			
		||||
			linkIn: make(chan []byte, 1),
 | 
			
		||||
| 
						 | 
				
			
			@ -208,10 +230,10 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
		go func() {
 | 
			
		||||
			//var chunks [][]byte
 | 
			
		||||
			var out []byte
 | 
			
		||||
			var chunks [][]byte
 | 
			
		||||
			for msg := range conn.out {
 | 
			
		||||
				var chunks [][]byte
 | 
			
		||||
				chunks = chunks[:0]
 | 
			
		||||
				bs := msg
 | 
			
		||||
				for len(bs) > udp_chunkSize {
 | 
			
		||||
					chunks, bs = append(chunks, bs[:udp_chunkSize]), bs[udp_chunkSize:]
 | 
			
		||||
| 
						 | 
				
			
			@ -238,11 +260,7 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
		iface.mutex.Lock()
 | 
			
		||||
		iface.conns[addr] = conn
 | 
			
		||||
		iface.mutex.Unlock()
 | 
			
		||||
		themNodeID := getNodeID(&ks.box)
 | 
			
		||||
		themAddr := address_addrForNodeID(themNodeID)
 | 
			
		||||
		themAddrString := net.IP(themAddr[:]).String()
 | 
			
		||||
		themString := fmt.Sprintf("%s@%s", themAddrString, addr)
 | 
			
		||||
		iface.core.log.Println("Adding peer:", themString)
 | 
			
		||||
		iface.core.log.Println("Adding peer:", conn.name)
 | 
			
		||||
		go iface.startConn(conn)
 | 
			
		||||
		go conn.peer.linkLoop(conn.linkIn)
 | 
			
		||||
		iface.sendKeys(conn.addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +297,8 @@ func (iface *udpInterface) reader() {
 | 
			
		|||
		}
 | 
			
		||||
		//msg := append(util_getBytes(), bs[:n]...)
 | 
			
		||||
		msg := bs[:n]
 | 
			
		||||
		addr := connAddr(udpAddr.String())
 | 
			
		||||
		var addr connAddr
 | 
			
		||||
		addr.fromUDPAddr(udpAddr)
 | 
			
		||||
		if udp_isKeys(msg) {
 | 
			
		||||
			var them address
 | 
			
		||||
			copy(them[:], udpAddr.IP.To16())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,14 @@ func wire_put_uint64(elem uint64, out []byte) []byte {
 | 
			
		|||
	return append(out, bs...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func wire_uint64_len(elem uint64) int {
 | 
			
		||||
	l := 1
 | 
			
		||||
	for e := elem >> 7; e > 0; e >>= 7 {
 | 
			
		||||
		l++
 | 
			
		||||
	}
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode uint64 from a []byte slice
 | 
			
		||||
// Returns the decoded uint64 and the number of bytes used
 | 
			
		||||
func wire_decode_uint64(bs []byte) (uint64, int) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue