|
@ -28,12 +28,12 @@ incoming messages are received on the reactor. |
|
|
*/ |
|
|
*/ |
|
|
type Switch struct { |
|
|
type Switch struct { |
|
|
network string |
|
|
network string |
|
|
|
|
|
listeners []Listener |
|
|
reactors map[string]Reactor |
|
|
reactors map[string]Reactor |
|
|
chDescs []*ChannelDescriptor |
|
|
chDescs []*ChannelDescriptor |
|
|
reactorsByCh map[byte]Reactor |
|
|
reactorsByCh map[byte]Reactor |
|
|
peers *PeerSet |
|
|
peers *PeerSet |
|
|
dialing *CMap |
|
|
dialing *CMap |
|
|
listeners *CMap // listenerName -> chan interface{}
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var ( |
|
|
var ( |
|
@ -53,7 +53,6 @@ func NewSwitch() *Switch { |
|
|
reactorsByCh: make(map[byte]Reactor), |
|
|
reactorsByCh: make(map[byte]Reactor), |
|
|
peers: NewPeerSet(), |
|
|
peers: NewPeerSet(), |
|
|
dialing: NewCMap(), |
|
|
dialing: NewCMap(), |
|
|
listeners: NewCMap(), |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return sw |
|
|
return sw |
|
@ -109,10 +108,20 @@ func (sw *Switch) StopPeers() { |
|
|
sw.peers = NewPeerSet() |
|
|
sw.peers = NewPeerSet() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Convenience function
|
|
|
|
|
|
func (sw *Switch) StopListeners() { |
|
|
|
|
|
// Stop each listener.
|
|
|
|
|
|
for _, listener := range sw.listeners { |
|
|
|
|
|
listener.Stop() |
|
|
|
|
|
} |
|
|
|
|
|
sw.listeners = nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Convenience function
|
|
|
// Convenience function
|
|
|
func (sw *Switch) Stop() { |
|
|
func (sw *Switch) Stop() { |
|
|
sw.StopPeers() |
|
|
sw.StopPeers() |
|
|
sw.StopReactors() |
|
|
sw.StopReactors() |
|
|
|
|
|
sw.StopListeners() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Not goroutine safe to modify.
|
|
|
// Not goroutine safe to modify.
|
|
@ -120,6 +129,15 @@ func (sw *Switch) Reactors() map[string]Reactor { |
|
|
return sw.reactors |
|
|
return sw.reactors |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (sw *Switch) AddListener(l Listener) { |
|
|
|
|
|
sw.listeners = append(sw.listeners, l) |
|
|
|
|
|
go sw.listenerRoutine(l) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (sw *Switch) IsListening() bool { |
|
|
|
|
|
return len(sw.listeners) > 0 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) { |
|
|
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) { |
|
|
peer := newPeer(conn, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError) |
|
|
peer := newPeer(conn, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError) |
|
|
|
|
|
|
|
@ -134,7 +152,7 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er |
|
|
// Start the peer
|
|
|
// Start the peer
|
|
|
peer.start() |
|
|
peer.start() |
|
|
|
|
|
|
|
|
// Notify listeners.
|
|
|
|
|
|
|
|
|
// Notify reactors
|
|
|
sw.doAddPeer(peer) |
|
|
sw.doAddPeer(peer) |
|
|
|
|
|
|
|
|
// Send handshake
|
|
|
// Send handshake
|
|
@ -207,7 +225,7 @@ func (sw *Switch) StopPeerForError(peer *Peer, reason interface{}) { |
|
|
sw.peers.Remove(peer) |
|
|
sw.peers.Remove(peer) |
|
|
peer.stop() |
|
|
peer.stop() |
|
|
|
|
|
|
|
|
// Notify listeners
|
|
|
|
|
|
|
|
|
// Notify reactors
|
|
|
sw.doRemovePeer(peer, reason) |
|
|
sw.doRemovePeer(peer, reason) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -218,14 +236,10 @@ func (sw *Switch) StopPeerGracefully(peer *Peer) { |
|
|
sw.peers.Remove(peer) |
|
|
sw.peers.Remove(peer) |
|
|
peer.stop() |
|
|
peer.stop() |
|
|
|
|
|
|
|
|
// Notify listeners
|
|
|
|
|
|
|
|
|
// Notify reactors
|
|
|
sw.doRemovePeer(peer, nil) |
|
|
sw.doRemovePeer(peer, nil) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (sw *Switch) IsListening() bool { |
|
|
|
|
|
return sw.listeners.Size() > 0 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (sw *Switch) doAddPeer(peer *Peer) { |
|
|
func (sw *Switch) doAddPeer(peer *Peer) { |
|
|
for _, reactor := range sw.reactors { |
|
|
for _, reactor := range sw.reactors { |
|
|
reactor.AddPeer(peer) |
|
|
reactor.AddPeer(peer) |
|
@ -238,6 +252,27 @@ func (sw *Switch) doRemovePeer(peer *Peer, reason interface{}) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (sw *Switch) listenerRoutine(l Listener) { |
|
|
|
|
|
for { |
|
|
|
|
|
inConn, ok := <-l.Connections() |
|
|
|
|
|
if !ok { |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
// New inbound connection!
|
|
|
|
|
|
peer, err := sw.AddPeerWithConnection(inConn, false) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
log.Info("Ignoring error from inbound connection: %v\n%v", |
|
|
|
|
|
peer, err) |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
// NOTE: We don't yet have the external address of the
|
|
|
|
|
|
// remote (if they have a listener at all).
|
|
|
|
|
|
// PEXReactor's pexRoutine will handle that.
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
type SwitchEventNewPeer struct { |
|
|
type SwitchEventNewPeer struct { |
|
|