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.

118 lines
2.5 KiB

  1. package p2p
  2. import (
  3. "bytes"
  4. "errors"
  5. "io"
  6. . "github.com/tendermint/tendermint/binary"
  7. )
  8. var pexErrInvalidMessage = errors.New("Invalid PEX message")
  9. const pexCh = "PEX"
  10. /*
  11. The PexHandler routine should be started separately from the Switch.
  12. It handles basic PEX communciation.
  13. The application is responsible for sending out a PexRequestMessage.
  14. */
  15. func PexHandler(s *Switch, addrBook *AddrBook) {
  16. for {
  17. inPkt := s.Receive(pexCh) // {Peer, Time, Packet}
  18. if inPkt == nil {
  19. // Client has stopped
  20. break
  21. }
  22. // decode message
  23. msg := decodeMessage(inPkt.Bytes)
  24. switch msg.(type) {
  25. case *PexRequestMessage:
  26. // inPkt.Peer requested some peers.
  27. // TODO: prevent abuse.
  28. addrs := addrBook.GetSelection()
  29. response := &pexResponseMessage{Addrs: addrs}
  30. pkt := NewPacket(pexCh, BinaryBytes(response))
  31. queued := inPkt.Peer.TryQueue(pkt)
  32. if !queued {
  33. // ignore
  34. }
  35. case *pexResponseMessage:
  36. // We received some peer addresses from inPkt.Peer.
  37. // TODO: prevent abuse.
  38. // (We don't want to get spammed with bad peers)
  39. srcAddr := inPkt.Peer.RemoteAddress()
  40. for _, addr := range msg.(*pexResponseMessage).Addrs {
  41. addrBook.AddAddress(addr, srcAddr)
  42. }
  43. default:
  44. // Bad peer.
  45. s.StopPeerForError(inPkt.Peer, pexErrInvalidMessage)
  46. }
  47. }
  48. // cleanup
  49. }
  50. /* Messages */
  51. const (
  52. pexTypeUnknown = Byte(0x00)
  53. pexTypeRequest = Byte(0x01)
  54. pexTypeResponse = Byte(0x02)
  55. )
  56. // TODO: check for unnecessary extra bytes at the end.
  57. func decodeMessage(bz ByteSlice) (msg Message) {
  58. switch Byte(bz[0]) {
  59. case pexTypeRequest:
  60. return &PexRequestMessage{}
  61. case pexTypeResponse:
  62. return readPexResponseMessage(bytes.NewReader(bz[1:]))
  63. default:
  64. return nil
  65. }
  66. }
  67. /*
  68. A response with peer addresses
  69. */
  70. type PexRequestMessage struct {
  71. }
  72. func (m *PexRequestMessage) WriteTo(w io.Writer) (n int64, err error) {
  73. n, err = WriteOnto(pexTypeRequest, w, n, err)
  74. return
  75. }
  76. /*
  77. A response with peer addresses
  78. */
  79. type pexResponseMessage struct {
  80. Addrs []*NetAddress
  81. }
  82. func readPexResponseMessage(r io.Reader) *pexResponseMessage {
  83. numAddrs := int(ReadUInt32(r))
  84. addrs := []*NetAddress{}
  85. for i := 0; i < numAddrs; i++ {
  86. addr := ReadNetAddress(r)
  87. addrs = append(addrs, addr)
  88. }
  89. return &pexResponseMessage{
  90. Addrs: addrs,
  91. }
  92. }
  93. func (m *pexResponseMessage) WriteTo(w io.Writer) (n int64, err error) {
  94. n, err = WriteOnto(pexTypeResponse, w, n, err)
  95. n, err = WriteOnto(UInt32(len(m.Addrs)), w, n, err)
  96. for _, addr := range m.Addrs {
  97. n, err = WriteOnto(addr, w, n, err)
  98. }
  99. return
  100. }