mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	remove duplicate tcp connections
This commit is contained in:
		
							parent
							
								
									25f00c1c7a
								
							
						
					
					
						commit
						8ba11b86bb
					
				
					 1 changed files with 38 additions and 10 deletions
				
			
		| 
						 | 
					@ -23,11 +23,14 @@ type tcpInterface struct {
 | 
				
			||||||
	serv  *net.TCPListener
 | 
						serv  *net.TCPListener
 | 
				
			||||||
	mutex sync.Mutex // Protecting the below
 | 
						mutex sync.Mutex // Protecting the below
 | 
				
			||||||
	calls map[string]struct{}
 | 
						calls map[string]struct{}
 | 
				
			||||||
 | 
						conns map[tcpInfo](chan struct{})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type tcpKeys struct {
 | 
					type tcpInfo struct {
 | 
				
			||||||
	box boxPubKey
 | 
						box        boxPubKey
 | 
				
			||||||
	sig sigPubKey
 | 
						sig        sigPubKey
 | 
				
			||||||
 | 
						localAddr  string // net.IPAddr.String(), not TCPAddr, don't care about port
 | 
				
			||||||
 | 
						remoteAddr string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (iface *tcpInterface) init(core *Core, addr string) {
 | 
					func (iface *tcpInterface) init(core *Core, addr string) {
 | 
				
			||||||
| 
						 | 
					@ -41,6 +44,7 @@ func (iface *tcpInterface) init(core *Core, addr string) {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	iface.calls = make(map[string]struct{})
 | 
						iface.calls = make(map[string]struct{})
 | 
				
			||||||
 | 
						iface.conns = make(map[tcpInfo](chan struct{}))
 | 
				
			||||||
	go iface.listener()
 | 
						go iface.listener()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,8 +106,8 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
				
			||||||
	if n < len(keys) { /*panic("Partial key packet?") ;*/
 | 
						if n < len(keys) { /*panic("Partial key packet?") ;*/
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ks := tcpKeys{}
 | 
						info := tcpInfo{}
 | 
				
			||||||
	if !tcp_chop_keys(&ks.box, &ks.sig, &keys) { /*panic("Invalid key packet?") ;*/
 | 
						if !tcp_chop_keys(&info.box, &info.sig, &keys) { /*panic("Invalid key packet?") ;*/
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Quit the parent call if this is a connection to ourself
 | 
						// Quit the parent call if this is a connection to ourself
 | 
				
			||||||
| 
						 | 
					@ -115,16 +119,40 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if equiv(ks.box[:], iface.core.boxPub[:]) {
 | 
						if equiv(info.box[:], iface.core.boxPub[:]) {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	} // testing
 | 
						} // testing
 | 
				
			||||||
	if equiv(ks.sig[:], iface.core.sigPub[:]) {
 | 
						if equiv(info.sig[:], iface.core.sigPub[:]) {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Check if we already have a connection to this node, close and block if yes
 | 
				
			||||||
 | 
						local := sock.LocalAddr().(*net.TCPAddr)
 | 
				
			||||||
 | 
						laddr := net.IPAddr{
 | 
				
			||||||
 | 
							IP:   local.IP,
 | 
				
			||||||
 | 
							Zone: local.Zone,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info.localAddr = laddr.String()
 | 
				
			||||||
 | 
						remote := sock.RemoteAddr().(*net.TCPAddr)
 | 
				
			||||||
 | 
						raddr := net.IPAddr{
 | 
				
			||||||
 | 
							IP:   remote.IP,
 | 
				
			||||||
 | 
							Zone: remote.Zone,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info.remoteAddr = raddr.String()
 | 
				
			||||||
 | 
						iface.mutex.Lock()
 | 
				
			||||||
 | 
						if blockChan, isIn := iface.conns[info]; isIn {
 | 
				
			||||||
 | 
							iface.mutex.Unlock()
 | 
				
			||||||
 | 
							sock.Close()
 | 
				
			||||||
 | 
							<-blockChan
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						blockChan := make(chan struct{})
 | 
				
			||||||
 | 
						iface.conns[info] = blockChan
 | 
				
			||||||
 | 
						iface.mutex.Unlock()
 | 
				
			||||||
 | 
						defer close(blockChan)
 | 
				
			||||||
	// Note that multiple connections to the same node are allowed
 | 
						// Note that multiple connections to the same node are allowed
 | 
				
			||||||
	//  E.g. over different interfaces
 | 
						//  E.g. over different interfaces
 | 
				
			||||||
	linkIn := make(chan []byte, 1)
 | 
						linkIn := make(chan []byte, 1)
 | 
				
			||||||
	p := iface.core.peers.newPeer(&ks.box, &ks.sig) //, in, out)
 | 
						p := iface.core.peers.newPeer(&info.box, &info.sig) //, in, out)
 | 
				
			||||||
	in := func(bs []byte) {
 | 
						in := func(bs []byte) {
 | 
				
			||||||
		p.handlePacket(bs, linkIn)
 | 
							p.handlePacket(bs, linkIn)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -197,8 +225,8 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
 | 
				
			||||||
		p.core.peers.mutex.Unlock()
 | 
							p.core.peers.mutex.Unlock()
 | 
				
			||||||
		close(linkIn)
 | 
							close(linkIn)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	them := sock.RemoteAddr()
 | 
						them := sock.RemoteAddr().(*net.TCPAddr)
 | 
				
			||||||
	themNodeID := getNodeID(&ks.box)
 | 
						themNodeID := getNodeID(&info.box)
 | 
				
			||||||
	themAddr := address_addrForNodeID(themNodeID)
 | 
						themAddr := address_addrForNodeID(themNodeID)
 | 
				
			||||||
	themAddrString := net.IP(themAddr[:]).String()
 | 
						themAddrString := net.IP(themAddr[:]).String()
 | 
				
			||||||
	themString := fmt.Sprintf("%s@%s", themAddrString, them)
 | 
						themString := fmt.Sprintf("%s@%s", themAddrString, them)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue