[NOD-134] Don't connect to an address from the same 16 CIDR (#423)

* [NOD-134] Don't connect to an address from the same 16 CIDR

* [NOD-134] Rename outboundPeerConnected variables

* [NOD-134] Change newConnMtx to newConnReqMtx
This commit is contained in:
Ori Newman 2019-10-06 15:53:58 +03:00 committed by Dan Aharoni
parent e6a4ed04f3
commit 9dfc3091b4
2 changed files with 45 additions and 27 deletions

View File

@ -178,6 +178,8 @@ type ConnManager struct {
start int32 start int32
stop int32 stop int32
newConnReqMtx sync.Mutex
cfg Config cfg Config
wg sync.WaitGroup wg sync.WaitGroup
failedAttempts uint64 failedAttempts uint64
@ -270,7 +272,7 @@ out:
delete(pending, connReq.id) delete(pending, connReq.id)
if cm.cfg.OnConnection != nil { if cm.cfg.OnConnection != nil {
go cm.cfg.OnConnection(connReq, msg.conn) cm.cfg.OnConnection(connReq, msg.conn)
} }
case handleDisconnected: case handleDisconnected:
@ -359,6 +361,8 @@ out:
// NewConnReq creates a new connection request and connects to the // NewConnReq creates a new connection request and connects to the
// corresponding address. // corresponding address.
func (cm *ConnManager) NewConnReq() { func (cm *ConnManager) NewConnReq() {
cm.newConnReqMtx.Lock()
defer cm.newConnReqMtx.Unlock()
if atomic.LoadInt32(&cm.stop) != 0 { if atomic.LoadInt32(&cm.stop) != 0 {
return return
} }

View File

@ -137,6 +137,11 @@ type relayMsg struct {
data interface{} data interface{}
} }
type outboundPeerConnectedMsg struct {
connReq *connmgr.ConnReq
conn net.Conn
}
// updatePeerHeightsMsg is a message sent from the blockmanager to the server // updatePeerHeightsMsg is a message sent from the blockmanager to the server
// after a new block has been accepted. The purpose of the message is to update // after a new block has been accepted. The purpose of the message is to update
// the heights of peers that were known to announce the block before we // the heights of peers that were known to announce the block before we
@ -266,6 +271,7 @@ type Server struct {
newPeers chan *Peer newPeers chan *Peer
donePeers chan *Peer donePeers chan *Peer
banPeers chan *Peer banPeers chan *Peer
newOutboundConnection chan *outboundPeerConnectedMsg
Query chan interface{} Query chan interface{}
relayInv chan relayMsg relayInv chan relayMsg
broadcast chan broadcastMsg broadcast chan broadcastMsg
@ -695,7 +701,6 @@ func (s *Server) handleAddPeerMsg(state *peerState, sp *Peer) bool {
if sp.Inbound() { if sp.Inbound() {
state.inboundPeers[sp.ID()] = sp state.inboundPeers[sp.ID()] = sp
} else { } else {
state.outboundGroups[addrmgr.GroupKey(sp.NA())]++
if sp.persistent { if sp.persistent {
state.persistentPeers[sp.ID()] = sp state.persistentPeers[sp.ID()] = sp
} else { } else {
@ -1110,21 +1115,22 @@ func (s *Server) inboundPeerConnected(conn net.Conn) {
// peer instance, associates it with the relevant state such as the connection // peer instance, associates it with the relevant state such as the connection
// request instance and the connection itself, and finally notifies the address // request instance and the connection itself, and finally notifies the address
// manager of the attempt. // manager of the attempt.
func (s *Server) outboundPeerConnected(c *connmgr.ConnReq, conn net.Conn) { func (s *Server) outboundPeerConnected(state *peerState, msg *outboundPeerConnectedMsg) {
sp := newServerPeer(s, c.Permanent) sp := newServerPeer(s, msg.connReq.Permanent)
p, err := peer.NewOutboundPeer(newPeerConfig(sp), c.Addr.String()) outboundPeer, err := peer.NewOutboundPeer(newPeerConfig(sp), msg.connReq.Addr.String())
if err != nil { if err != nil {
srvrLog.Debugf("Cannot create outbound peer %s: %s", c.Addr, err) srvrLog.Debugf("Cannot create outbound peer %s: %s", msg.connReq.Addr, err)
s.connManager.Disconnect(c.ID()) s.connManager.Disconnect(msg.connReq.ID())
} }
sp.Peer = p sp.Peer = outboundPeer
sp.connReq = c sp.connReq = msg.connReq
sp.isWhitelisted = isWhitelisted(conn.RemoteAddr()) sp.isWhitelisted = isWhitelisted(msg.conn.RemoteAddr())
sp.AssociateConnection(conn) sp.AssociateConnection(msg.conn)
spawn(func() { spawn(func() {
s.peerDoneHandler(sp) s.peerDoneHandler(sp)
}) })
s.addrManager.Attempt(sp.NA()) s.addrManager.Attempt(sp.NA())
state.outboundGroups[addrmgr.GroupKey(sp.NA())]++
} }
// peerDoneHandler handles peer disconnects by notifiying the server that it's // peerDoneHandler handles peer disconnects by notifiying the server that it's
@ -1226,6 +1232,9 @@ out:
return true return true
}) })
break out break out
case opcMsg := <-s.newOutboundConnection:
s.outboundPeerConnected(state, opcMsg)
} }
} }
@ -1601,6 +1610,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
broadcast: make(chan broadcastMsg, config.MainConfig().MaxPeers), broadcast: make(chan broadcastMsg, config.MainConfig().MaxPeers),
quit: make(chan struct{}), quit: make(chan struct{}),
modifyRebroadcastInv: make(chan interface{}), modifyRebroadcastInv: make(chan interface{}),
newOutboundConnection: make(chan *outboundPeerConnectedMsg),
nat: nat, nat: nat,
db: db, db: db,
TimeSource: blockdag.NewMedianTime(), TimeSource: blockdag.NewMedianTime(),
@ -1757,7 +1767,6 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
addrString := addrmgr.NetAddressKey(addr.NetAddress()) addrString := addrmgr.NetAddressKey(addr.NetAddress())
return addrStringToNetAddr(addrString) return addrStringToNetAddr(addrString)
} }
return nil, errors.New("no valid connect address") return nil, errors.New("no valid connect address")
} }
} }
@ -1773,7 +1782,12 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
RetryDuration: connectionRetryInterval, RetryDuration: connectionRetryInterval,
TargetOutbound: uint32(targetOutbound), TargetOutbound: uint32(targetOutbound),
Dial: serverutils.BTCDDial, Dial: serverutils.BTCDDial,
OnConnection: s.outboundPeerConnected, OnConnection: func(c *connmgr.ConnReq, conn net.Conn) {
s.newOutboundConnection <- &outboundPeerConnectedMsg{
connReq: c,
conn: conn,
}
},
GetNewAddress: newAddressFunc, GetNewAddress: newAddressFunc,
}) })
if err != nil { if err != nil {