From 2f53df8a97878bb64851ab1a9cb7b806a125d2dd Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 9 Sep 2014 11:27:46 +0100 Subject: [PATCH] Check if we already have a connection on an address before attempting to connect to it --- connection_maker.go | 10 +++++++--- peer.go | 31 ++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/connection_maker.go b/connection_maker.go index ebdd8b1b..e7822d26 100644 --- a/connection_maker.go +++ b/connection_maker.go @@ -115,9 +115,13 @@ func (cm *ConnectionMaker) queryLoop(queryChan <-chan *ConnectionMakerInteractio case now := <-tick: for address, target := range cm.targets { if target.state == CMUnconnected && now.After(target.tryAfter) { - target.attemptCount += 1 - target.state = CMAttempting - go cm.attemptConnection(address, target.acceptAnyPeer) + if _, found := cm.router.Ourself.ConnectionOn(address); found { + target.state = CMEstablished + } else { + target.attemptCount += 1 + target.state = CMAttempting + go cm.attemptConnection(address, target.acceptAnyPeer) + } } } tick = nil diff --git a/peer.go b/peer.go index fb43ccef..9bdd3968 100644 --- a/peer.go +++ b/peer.go @@ -57,6 +57,29 @@ func (peer *Peer) ConnectionTo(name PeerName) (Connection, bool) { return conn, found // yes, you really can't inline that. FFS. } +// given an address like '1.2.3.4:567', return the address if it has a port, +// otherwise return the address with weave's standard port number +func normalisePeerAddr(peerAddr string) string { + _, _, err := net.SplitHostPort(peerAddr) + if err == nil { + return peerAddr + } else { + return fmt.Sprintf("%s:%d", peerAddr, Port) + } +} + +func (peer *Peer) ConnectionOn(peerAddr string) (Connection, bool) { + peerAddr = normalisePeerAddr(peerAddr) + peer.RLock() + defer peer.RUnlock() + for _, conn := range peer.connections { + if conn.RemoteTCPAddr() == peerAddr { + return conn, true + } + } + return nil, false +} + func (peer *Peer) ForEachConnection(fun func(PeerName, Connection)) { peer.RLock() defer peer.RUnlock() @@ -197,13 +220,7 @@ func (peer *Peer) CreateConnection(peerAddr string, acceptNewPeer bool) error { return err } // We're dialing the remote so that means connections will come from random ports - _, _, err := net.SplitHostPort(peerAddr) - var addrStr string - if err == nil { - addrStr = peerAddr - } else { - addrStr = fmt.Sprintf("%s:%d", peerAddr, Port) - } + addrStr := normalisePeerAddr(peerAddr) tcpAddr, tcpErr := net.ResolveTCPAddr("tcp4", addrStr) udpAddr, udpErr := net.ResolveUDPAddr("udp4", addrStr) if tcpErr != nil || udpErr != nil {