mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Use larger UDP chunks for link-local IP and let the OS fragment it. Switch to UDP for link-local peers. Minor code cleanup for TCP.
This commit is contained in:
		
							parent
							
								
									8c7d514032
								
							
						
					
					
						commit
						4045597516
					
				
					 4 changed files with 53 additions and 47 deletions
				
			
		| 
						 | 
				
			
			@ -158,6 +158,23 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
			
		|||
	}
 | 
			
		||||
	out := make(chan []byte, 32) // TODO? what size makes sense
 | 
			
		||||
	defer close(out)
 | 
			
		||||
	send := func(msg []byte) {
 | 
			
		||||
		buf := net.Buffers{tcp_msg[:],
 | 
			
		||||
			wire_encode_uint64(uint64(len(msg))),
 | 
			
		||||
			msg}
 | 
			
		||||
		size := 0
 | 
			
		||||
		for _, bs := range buf {
 | 
			
		||||
			size += len(bs)
 | 
			
		||||
		}
 | 
			
		||||
		start := time.Now()
 | 
			
		||||
		buf.WriteTo(sock)
 | 
			
		||||
		timed := time.Since(start)
 | 
			
		||||
		pType, _ := wire_decode_uint64(msg)
 | 
			
		||||
		if pType == wire_LinkProtocolTraffic {
 | 
			
		||||
			p.updateBandwidth(size, timed)
 | 
			
		||||
		}
 | 
			
		||||
		util_putBytes(msg)
 | 
			
		||||
	}
 | 
			
		||||
	go func() {
 | 
			
		||||
		var stack [][]byte
 | 
			
		||||
		put := func(msg []byte) {
 | 
			
		||||
| 
						 | 
				
			
			@ -167,25 +184,6 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
			
		|||
				stack = stack[1:]
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		send := func() {
 | 
			
		||||
			msg := stack[len(stack)-1]
 | 
			
		||||
			stack = stack[:len(stack)-1]
 | 
			
		||||
			buf := net.Buffers{tcp_msg[:],
 | 
			
		||||
				wire_encode_uint64(uint64(len(msg))),
 | 
			
		||||
				msg}
 | 
			
		||||
			size := 0
 | 
			
		||||
			for _, bs := range buf {
 | 
			
		||||
				size += len(bs)
 | 
			
		||||
			}
 | 
			
		||||
			start := time.Now()
 | 
			
		||||
			buf.WriteTo(sock)
 | 
			
		||||
			timed := time.Since(start)
 | 
			
		||||
			pType, _ := wire_decode_uint64(msg)
 | 
			
		||||
			if pType == wire_LinkProtocolTraffic {
 | 
			
		||||
				p.updateBandwidth(size, timed)
 | 
			
		||||
			}
 | 
			
		||||
			util_putBytes(msg)
 | 
			
		||||
		}
 | 
			
		||||
		for msg := range out {
 | 
			
		||||
			put(msg)
 | 
			
		||||
			for len(stack) > 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +195,9 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
			
		|||
					}
 | 
			
		||||
					put(msg)
 | 
			
		||||
				default:
 | 
			
		||||
					send()
 | 
			
		||||
					msg := stack[len(stack)-1]
 | 
			
		||||
					stack = stack[:len(stack)-1]
 | 
			
		||||
					send(msg)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,16 +46,17 @@ func (c *connAddr) toUDPAddr() *net.UDPAddr {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type connInfo struct {
 | 
			
		||||
	name     string
 | 
			
		||||
	addr     connAddr
 | 
			
		||||
	peer     *peer
 | 
			
		||||
	linkIn   chan []byte
 | 
			
		||||
	keysIn   chan *udpKeys
 | 
			
		||||
	timeout  int // count of how many heartbeats have been missed
 | 
			
		||||
	in       func([]byte)
 | 
			
		||||
	out      chan []byte
 | 
			
		||||
	countIn  uint8
 | 
			
		||||
	countOut uint8
 | 
			
		||||
	name      string
 | 
			
		||||
	addr      connAddr
 | 
			
		||||
	peer      *peer
 | 
			
		||||
	linkIn    chan []byte
 | 
			
		||||
	keysIn    chan *udpKeys
 | 
			
		||||
	timeout   int // count of how many heartbeats have been missed
 | 
			
		||||
	in        func([]byte)
 | 
			
		||||
	out       chan []byte
 | 
			
		||||
	countIn   uint8
 | 
			
		||||
	countOut  uint8
 | 
			
		||||
	chunkSize uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type udpKeys struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +74,8 @@ func (iface *udpInterface) init(core *Core, addr string) {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	//iface.sock.SetReadBuffer(1048576)
 | 
			
		||||
	//iface.sock.SetWriteBuffer(1048576)
 | 
			
		||||
	iface.conns = make(map[connAddr]*connInfo)
 | 
			
		||||
	go iface.reader()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -162,12 +165,16 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
		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),
 | 
			
		||||
			keysIn: make(chan *udpKeys, 1),
 | 
			
		||||
			out:    make(chan []byte, 32),
 | 
			
		||||
			name:      themString,
 | 
			
		||||
			addr:      connAddr(addr),
 | 
			
		||||
			peer:      iface.core.peers.newPeer(&ks.box, &ks.sig),
 | 
			
		||||
			linkIn:    make(chan []byte, 1),
 | 
			
		||||
			keysIn:    make(chan *udpKeys, 1),
 | 
			
		||||
			out:       make(chan []byte, 32),
 | 
			
		||||
			chunkSize: 576 - 60 - 8 - 3, // max save - max ip - udp header - chunk overhead
 | 
			
		||||
		}
 | 
			
		||||
		if udpAddr.IP.IsLinkLocalUnicast() {
 | 
			
		||||
			conn.chunkSize = 65535 - 8 - 3
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		   conn.in = func (msg []byte) { conn.peer.handlePacket(msg, conn.linkIn) }
 | 
			
		||||
| 
						 | 
				
			
			@ -236,8 +243,8 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
			for msg := range conn.out {
 | 
			
		||||
				chunks = chunks[:0]
 | 
			
		||||
				bs := msg
 | 
			
		||||
				for len(bs) > udp_chunkSize {
 | 
			
		||||
					chunks, bs = append(chunks, bs[:udp_chunkSize]), bs[udp_chunkSize:]
 | 
			
		||||
				for len(bs) > int(conn.chunkSize) {
 | 
			
		||||
					chunks, bs = append(chunks, bs[:conn.chunkSize]), bs[conn.chunkSize:]
 | 
			
		||||
				}
 | 
			
		||||
				chunks = append(chunks, bs)
 | 
			
		||||
				//iface.core.log.Println("DEBUG: out chunks:", len(chunks), len(msg))
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +291,7 @@ func (iface *udpInterface) handlePacket(msg []byte, addr connAddr) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (iface *udpInterface) reader() {
 | 
			
		||||
	bs := make([]byte, 2048) // This needs to be large enough for everything...
 | 
			
		||||
	bs := make([]byte, 65536) // This needs to be large enough for everything...
 | 
			
		||||
	for {
 | 
			
		||||
		//iface.core.log.Println("Starting read")
 | 
			
		||||
		n, udpAddr, err := iface.sock.ReadFromUDP(bs)
 | 
			
		||||
| 
						 | 
				
			
			@ -293,9 +300,7 @@ func (iface *udpInterface) reader() {
 | 
			
		|||
			panic(err)
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if n > 1500 {
 | 
			
		||||
			panic(n)
 | 
			
		||||
		}
 | 
			
		||||
		//iface.core.log.Println("DEBUG: recv len:", n)
 | 
			
		||||
		//msg := append(util_getBytes(), bs[:n]...)
 | 
			
		||||
		msg := bs[:n]
 | 
			
		||||
		var addr connAddr
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +324,8 @@ func (iface *udpInterface) reader() {
 | 
			
		|||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const udp_chunkSize = 508 // Apparently the maximum guaranteed safe IPv4 size
 | 
			
		||||
//const udp_chunkSize = 508 // Apparently the maximum guaranteed safe IPv4 size
 | 
			
		||||
//const udp_chunkSize = 65535 - 3 - 8
 | 
			
		||||
 | 
			
		||||
func udp_decode(bs []byte) (chunks, chunk, count uint8, payload []byte) {
 | 
			
		||||
	if len(bs) >= 3 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ const (
 | 
			
		|||
	wire_DHTLookupResponse          // inside protocol traffic header
 | 
			
		||||
	wire_SearchRequest              // inside protocol traffic header
 | 
			
		||||
	wire_SearchResponse             // inside protocol traffic header
 | 
			
		||||
	//wire_Keys                 // udp key packet (boxPub, sigPub)
 | 
			
		||||
	wire_Keys                       // udp key packet (boxPub, sigPub)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Encode uint64 using a variable length scheme
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue