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.

256 lines
6.0 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package p2p
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "math/rand"
  7. "reflect"
  8. "time"
  9. . "github.com/tendermint/go-common"
  10. "github.com/tendermint/go-wire"
  11. )
  12. var pexErrInvalidMessage = errors.New("Invalid PEX message")
  13. const (
  14. PexChannel = byte(0x00)
  15. ensurePeersPeriodSeconds = 30
  16. minNumOutboundPeers = 10
  17. maxPexMessageSize = 1048576 // 1MB
  18. )
  19. /*
  20. PEXReactor handles PEX (peer exchange) and ensures that an
  21. adequate number of peers are connected to the switch.
  22. */
  23. type PEXReactor struct {
  24. BaseReactor
  25. sw *Switch
  26. book *AddrBook
  27. }
  28. func NewPEXReactor(book *AddrBook) *PEXReactor {
  29. pexR := &PEXReactor{
  30. book: book,
  31. }
  32. pexR.BaseReactor = *NewBaseReactor(log, "PEXReactor", pexR)
  33. return pexR
  34. }
  35. func (pexR *PEXReactor) OnStart() error {
  36. pexR.BaseReactor.OnStart()
  37. go pexR.ensurePeersRoutine()
  38. return nil
  39. }
  40. func (pexR *PEXReactor) OnStop() {
  41. pexR.BaseReactor.OnStop()
  42. }
  43. // Implements Reactor
  44. func (pexR *PEXReactor) GetChannels() []*ChannelDescriptor {
  45. return []*ChannelDescriptor{
  46. &ChannelDescriptor{
  47. ID: PexChannel,
  48. Priority: 1,
  49. SendQueueCapacity: 10,
  50. },
  51. }
  52. }
  53. // Implements Reactor
  54. func (pexR *PEXReactor) AddPeer(peer *Peer) {
  55. // Add the peer to the address book
  56. netAddr := NewNetAddressString(peer.ListenAddr)
  57. if peer.IsOutbound() {
  58. if pexR.book.NeedMoreAddrs() {
  59. pexR.RequestPEX(peer)
  60. }
  61. } else {
  62. // For inbound connections, the peer is its own source
  63. // (For outbound peers, the address is already in the books)
  64. pexR.book.AddAddress(netAddr, netAddr)
  65. }
  66. }
  67. // Implements Reactor
  68. func (pexR *PEXReactor) RemovePeer(peer *Peer, reason interface{}) {
  69. // TODO
  70. }
  71. // Implements Reactor
  72. // Handles incoming PEX messages.
  73. func (pexR *PEXReactor) Receive(chID byte, src *Peer, msgBytes []byte) {
  74. // decode message
  75. _, msg, err := DecodeMessage(msgBytes)
  76. if err != nil {
  77. log.Warn("Error decoding message", "error", err)
  78. return
  79. }
  80. log.Notice("Received message", "msg", msg)
  81. switch msg := msg.(type) {
  82. case *pexRequestMessage:
  83. // src requested some peers.
  84. // TODO: prevent abuse.
  85. pexR.SendAddrs(src, pexR.book.GetSelection())
  86. case *pexAddrsMessage:
  87. // We received some peer addresses from src.
  88. // TODO: prevent abuse.
  89. // (We don't want to get spammed with bad peers)
  90. srcAddr := src.Connection().RemoteAddress
  91. for _, addr := range msg.Addrs {
  92. pexR.book.AddAddress(addr, srcAddr)
  93. }
  94. default:
  95. log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg)))
  96. }
  97. }
  98. // Asks peer for more addresses.
  99. func (pexR *PEXReactor) RequestPEX(peer *Peer) {
  100. peer.Send(PexChannel, struct{ PexMessage }{&pexRequestMessage{}})
  101. }
  102. func (pexR *PEXReactor) SendAddrs(peer *Peer, addrs []*NetAddress) {
  103. peer.Send(PexChannel, struct{ PexMessage }{&pexAddrsMessage{Addrs: addrs}})
  104. }
  105. // Ensures that sufficient peers are connected. (continuous)
  106. func (pexR *PEXReactor) ensurePeersRoutine() {
  107. // Randomize when routine starts
  108. time.Sleep(time.Duration(rand.Int63n(500*ensurePeersPeriodSeconds)) * time.Millisecond)
  109. // fire once immediately.
  110. pexR.ensurePeers()
  111. // fire periodically
  112. timer := NewRepeatTimer("pex", ensurePeersPeriodSeconds*time.Second)
  113. FOR_LOOP:
  114. for {
  115. select {
  116. case <-timer.Ch:
  117. pexR.ensurePeers()
  118. case <-pexR.Quit:
  119. break FOR_LOOP
  120. }
  121. }
  122. // Cleanup
  123. timer.Stop()
  124. }
  125. // Ensures that sufficient peers are connected. (once)
  126. func (pexR *PEXReactor) ensurePeers() {
  127. numOutPeers, _, numDialing := pexR.Switch.NumPeers()
  128. numToDial := minNumOutboundPeers - (numOutPeers + numDialing)
  129. log.Info("Ensure peers", "numOutPeers", numOutPeers, "numDialing", numDialing, "numToDial", numToDial)
  130. if numToDial <= 0 {
  131. return
  132. }
  133. toDial := NewCMap()
  134. // Try to pick numToDial addresses to dial.
  135. // TODO: improve logic.
  136. for i := 0; i < numToDial; i++ {
  137. newBias := MinInt(numOutPeers, 8)*10 + 10
  138. var picked *NetAddress
  139. // Try to fetch a new peer 3 times.
  140. // This caps the maximum number of tries to 3 * numToDial.
  141. for j := 0; j < 3; j++ {
  142. try := pexR.book.PickAddress(newBias)
  143. if try == nil {
  144. break
  145. }
  146. alreadySelected := toDial.Has(try.IP.String())
  147. alreadyDialing := pexR.Switch.IsDialing(try)
  148. alreadyConnected := pexR.Switch.Peers().Has(try.IP.String())
  149. if alreadySelected || alreadyDialing || alreadyConnected {
  150. /*
  151. log.Info("Cannot dial address", "addr", try,
  152. "alreadySelected", alreadySelected,
  153. "alreadyDialing", alreadyDialing,
  154. "alreadyConnected", alreadyConnected)
  155. */
  156. continue
  157. } else {
  158. log.Info("Will dial address", "addr", try)
  159. picked = try
  160. break
  161. }
  162. }
  163. if picked == nil {
  164. continue
  165. }
  166. toDial.Set(picked.IP.String(), picked)
  167. }
  168. // Dial picked addresses
  169. for _, item := range toDial.Values() {
  170. go func(picked *NetAddress) {
  171. _, err := pexR.Switch.DialPeerWithAddress(picked)
  172. if err != nil {
  173. pexR.book.MarkAttempt(picked)
  174. }
  175. }(item.(*NetAddress))
  176. }
  177. // If we need more addresses, pick a random peer and ask for more.
  178. if pexR.book.NeedMoreAddrs() {
  179. if peers := pexR.Switch.Peers().List(); len(peers) > 0 {
  180. i := rand.Int() % len(peers)
  181. peer := peers[i]
  182. log.Info("No addresses to dial. Sending pexRequest to random peer", "peer", peer)
  183. pexR.RequestPEX(peer)
  184. }
  185. }
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Messages
  189. const (
  190. msgTypeRequest = byte(0x01)
  191. msgTypeAddrs = byte(0x02)
  192. )
  193. type PexMessage interface{}
  194. var _ = wire.RegisterInterface(
  195. struct{ PexMessage }{},
  196. wire.ConcreteType{&pexRequestMessage{}, msgTypeRequest},
  197. wire.ConcreteType{&pexAddrsMessage{}, msgTypeAddrs},
  198. )
  199. func DecodeMessage(bz []byte) (msgType byte, msg PexMessage, err error) {
  200. msgType = bz[0]
  201. n := new(int)
  202. r := bytes.NewReader(bz)
  203. msg = wire.ReadBinary(struct{ PexMessage }{}, r, maxPexMessageSize, n, &err).(struct{ PexMessage }).PexMessage
  204. return
  205. }
  206. /*
  207. A pexRequestMessage requests additional peer addresses.
  208. */
  209. type pexRequestMessage struct {
  210. }
  211. func (m *pexRequestMessage) String() string {
  212. return "[pexRequest]"
  213. }
  214. /*
  215. A message with announced peer addresses.
  216. */
  217. type pexAddrsMessage struct {
  218. Addrs []*NetAddress
  219. }
  220. func (m *pexAddrsMessage) String() string {
  221. return fmt.Sprintf("[pexAddrs %v]", m.Addrs)
  222. }