mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-23 18:15:24 +00:00
remove duplicate tcp connections
This commit is contained in:
parent
25f00c1c7a
commit
8ba11b86bb
@ -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…
Reference in New Issue
Block a user