You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
7.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package p2p
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "sync/atomic"
  7. "time"
  8. . "github.com/tendermint/tendermint/common"
  9. )
  10. type Reactor interface {
  11. Start(sw *Switch)
  12. Stop()
  13. GetChannels() []*ChannelDescriptor
  14. AddPeer(peer *Peer)
  15. RemovePeer(peer *Peer, reason interface{})
  16. Receive(chId byte, peer *Peer, msgBytes []byte)
  17. }
  18. //--------------------------------------
  19. type BaseReactor struct{}
  20. func (_ BaseReactor) Start(sw *Switch) {}
  21. func (_ BaseReactor) Stop() {}
  22. func (_ BaseReactor) GetChannels() []*ChannelDescriptor { return nil }
  23. func (_ BaseReactor) AddPeer(peer *Peer) {}
  24. func (_ BaseReactor) RemovePeer(peer *Peer, reason interface{}) {}
  25. func (_ BaseReactor) Receive(chId byte, peer *Peer, msgBytes []byte) {}
  26. //-----------------------------------------------------------------------------
  27. /*
  28. The `Switch` handles peer connections and exposes an API to receive incoming messages
  29. on `Reactors`. Each `Reactor` is responsible for handling incoming messages of one
  30. or more `Channels`. So while sending outgoing messages is typically performed on the peer,
  31. incoming messages are received on the reactor.
  32. */
  33. type Switch struct {
  34. network string
  35. listeners []Listener
  36. reactors map[string]Reactor
  37. chDescs []*ChannelDescriptor
  38. reactorsByCh map[byte]Reactor
  39. peers *PeerSet
  40. dialing *CMap
  41. running uint32
  42. }
  43. var (
  44. ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
  45. )
  46. const (
  47. peerDialTimeoutSeconds = 3
  48. )
  49. func NewSwitch() *Switch {
  50. sw := &Switch{
  51. network: "",
  52. reactors: make(map[string]Reactor),
  53. chDescs: make([]*ChannelDescriptor, 0),
  54. reactorsByCh: make(map[byte]Reactor),
  55. peers: NewPeerSet(),
  56. dialing: NewCMap(),
  57. running: 0,
  58. }
  59. return sw
  60. }
  61. // Not goroutine safe.
  62. func (sw *Switch) SetNetwork(network string) {
  63. sw.network = network
  64. }
  65. // Not goroutine safe.
  66. func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor {
  67. // Validate the reactor.
  68. // No two reactors can share the same channel.
  69. reactorChannels := reactor.GetChannels()
  70. for _, chDesc := range reactorChannels {
  71. chId := chDesc.Id
  72. if sw.reactorsByCh[chId] != nil {
  73. panic(fmt.Sprintf("Channel %X has multiple reactors %v & %v", chId, sw.reactorsByCh[chId], reactor))
  74. }
  75. sw.chDescs = append(sw.chDescs, chDesc)
  76. sw.reactorsByCh[chId] = reactor
  77. }
  78. sw.reactors[name] = reactor
  79. return reactor
  80. }
  81. // Not goroutine safe.
  82. func (sw *Switch) Reactors() map[string]Reactor {
  83. return sw.reactors
  84. }
  85. // Not goroutine safe.
  86. func (sw *Switch) Reactor(name string) Reactor {
  87. return sw.reactors[name]
  88. }
  89. // Not goroutine safe.
  90. func (sw *Switch) AddListener(l Listener) {
  91. sw.listeners = append(sw.listeners, l)
  92. }
  93. func (sw *Switch) Listeners() []Listener {
  94. return sw.listeners
  95. }
  96. // Not goroutine safe.
  97. func (sw *Switch) IsListening() bool {
  98. return len(sw.listeners) > 0
  99. }
  100. func (sw *Switch) Start() {
  101. if atomic.CompareAndSwapUint32(&sw.running, 0, 1) {
  102. // Start reactors
  103. for _, reactor := range sw.reactors {
  104. reactor.Start(sw)
  105. }
  106. // Start peers
  107. for _, peer := range sw.peers.List() {
  108. sw.startInitPeer(peer)
  109. }
  110. // Start listeners
  111. for _, listener := range sw.listeners {
  112. go sw.listenerRoutine(listener)
  113. }
  114. }
  115. }
  116. func (sw *Switch) Stop() {
  117. if atomic.CompareAndSwapUint32(&sw.running, 1, 0) {
  118. // Stop listeners
  119. for _, listener := range sw.listeners {
  120. listener.Stop()
  121. }
  122. sw.listeners = nil
  123. // Stop peers
  124. for _, peer := range sw.peers.List() {
  125. peer.stop()
  126. }
  127. sw.peers = NewPeerSet()
  128. // Stop reactors
  129. for _, reactor := range sw.reactors {
  130. reactor.Stop()
  131. }
  132. }
  133. }
  134. func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
  135. peer := newPeer(conn, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError)
  136. // Add the peer to .peers
  137. if sw.peers.Add(peer) {
  138. log.Info("Added peer", "peer", peer)
  139. } else {
  140. log.Info("Ignoring duplicate peer", "peer", peer)
  141. return nil, ErrSwitchDuplicatePeer
  142. }
  143. if atomic.LoadUint32(&sw.running) == 1 {
  144. sw.startInitPeer(peer)
  145. }
  146. return peer, nil
  147. }
  148. func (sw *Switch) startInitPeer(peer *Peer) {
  149. // Start the peer
  150. peer.start()
  151. // Notify reactors
  152. sw.doAddPeer(peer)
  153. // Send handshake
  154. msg := &pexHandshakeMessage{Network: sw.network}
  155. peer.Send(PexChannel, msg)
  156. }
  157. func (sw *Switch) DialPeerWithAddress(addr *NetAddress) (*Peer, error) {
  158. log.Debug("Dialing address", "address", addr)
  159. sw.dialing.Set(addr.String(), addr)
  160. conn, err := addr.DialTimeout(peerDialTimeoutSeconds * time.Second)
  161. sw.dialing.Delete(addr.String())
  162. if err != nil {
  163. log.Debug("Failed dialing address", "address", addr, "error", err)
  164. return nil, err
  165. }
  166. peer, err := sw.AddPeerWithConnection(conn, true)
  167. if err != nil {
  168. log.Debug("Failed adding peer", "address", addr, "conn", conn, "error", err)
  169. return nil, err
  170. }
  171. log.Info("Dialed and added peer", "address", addr, "peer", peer)
  172. return peer, nil
  173. }
  174. func (sw *Switch) IsDialing(addr *NetAddress) bool {
  175. return sw.dialing.Has(addr.String())
  176. }
  177. // Broadcast runs a go routine for each attempted send, which will block
  178. // trying to send for defaultSendTimeoutSeconds. Returns a channel
  179. // which receives success values for each attempted send (false if times out)
  180. func (sw *Switch) Broadcast(chId byte, msg interface{}) chan bool {
  181. successChan := make(chan bool, len(sw.peers.List()))
  182. log.Debug("Broadcast", "channel", chId, "msg", msg)
  183. for _, peer := range sw.peers.List() {
  184. go func() {
  185. success := peer.Send(chId, msg)
  186. successChan <- success
  187. }()
  188. }
  189. return successChan
  190. }
  191. // Returns the count of outbound/inbound and outbound-dialing peers.
  192. func (sw *Switch) NumPeers() (outbound, inbound, dialing int) {
  193. peers := sw.peers.List()
  194. for _, peer := range peers {
  195. if peer.outbound {
  196. outbound++
  197. } else {
  198. inbound++
  199. }
  200. }
  201. dialing = sw.dialing.Size()
  202. return
  203. }
  204. func (sw *Switch) Peers() IPeerSet {
  205. return sw.peers
  206. }
  207. // Disconnect from a peer due to external error.
  208. // TODO: make record depending on reason.
  209. func (sw *Switch) StopPeerForError(peer *Peer, reason interface{}) {
  210. log.Info("Stopping peer for error", "peer", peer, "error", reason)
  211. sw.peers.Remove(peer)
  212. peer.stop()
  213. // Notify reactors
  214. sw.doRemovePeer(peer, reason)
  215. }
  216. // Disconnect from a peer gracefully.
  217. // TODO: handle graceful disconnects.
  218. func (sw *Switch) StopPeerGracefully(peer *Peer) {
  219. log.Info("Stopping peer gracefully")
  220. sw.peers.Remove(peer)
  221. peer.stop()
  222. // Notify reactors
  223. sw.doRemovePeer(peer, nil)
  224. }
  225. func (sw *Switch) doAddPeer(peer *Peer) {
  226. for _, reactor := range sw.reactors {
  227. reactor.AddPeer(peer)
  228. }
  229. }
  230. func (sw *Switch) doRemovePeer(peer *Peer, reason interface{}) {
  231. for _, reactor := range sw.reactors {
  232. reactor.RemovePeer(peer, reason)
  233. }
  234. }
  235. func (sw *Switch) listenerRoutine(l Listener) {
  236. for {
  237. inConn, ok := <-l.Connections()
  238. if !ok {
  239. break
  240. }
  241. // New inbound connection!
  242. peer, err := sw.AddPeerWithConnection(inConn, false)
  243. if err != nil {
  244. log.Info("Ignoring error from inbound connection: %v\n%v",
  245. peer, err)
  246. continue
  247. }
  248. // NOTE: We don't yet have the external address of the
  249. // remote (if they have a listener at all).
  250. // PEXReactor's pexRoutine will handle that.
  251. }
  252. // cleanup
  253. }
  254. //-----------------------------------------------------------------------------
  255. type SwitchEventNewPeer struct {
  256. Peer *Peer
  257. }
  258. type SwitchEventDonePeer struct {
  259. Peer *Peer
  260. Error interface{}
  261. }