peer.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package p2p
  2. import (
  3. "blockchain-go/common/mclock"
  4. "blockchain-go/p2p/enode"
  5. "errors"
  6. "sort"
  7. "time"
  8. )
  9. var (
  10. ErrShuttingDown = errors.New("shutting down")
  11. )
  12. const (
  13. baseProtocolVersion = 5
  14. baseProtocolLength = uint64(16)
  15. baseProtocolMaxMsgSize = 2 * 1024
  16. snappyProtocolVersion = 5
  17. pingInterval = 15 * time.Second
  18. )
  19. const (
  20. // devp2p message codes
  21. handshakeMsg = 0x00
  22. discMsg = 0x01
  23. pingMsg = 0x02
  24. pongMsg = 0x03
  25. )
  26. // protoHandshake is the RLP structure of the protocol handshake.
  27. type protoHandshake struct {
  28. Version uint64
  29. Name string
  30. Caps []Cap
  31. ListenPort uint64
  32. ID []byte // secp256k1 public key
  33. // Ignore additional fields (for forward compatibility).
  34. //Rest []rlp.RawValue `rlp:"tail"`
  35. }
  36. type PeerEventType string
  37. const (
  38. // PeerEventTypeAdd is the type of event emitted when a peer is added
  39. // to a p2p.Server
  40. PeerEventTypeAdd PeerEventType = "add"
  41. // PeerEventTypeDrop is the type of event emitted when a peer is
  42. // dropped from a p2p.Server
  43. PeerEventTypeDrop PeerEventType = "drop"
  44. // PeerEventTypeMsgSend is the type of event emitted when a
  45. // message is successfully sent to a peer
  46. PeerEventTypeMsgSend PeerEventType = "msgsend"
  47. // PeerEventTypeMsgRecv is the type of event emitted when a
  48. // message is received from a peer
  49. PeerEventTypeMsgRecv PeerEventType = "msgrecv"
  50. )
  51. // PeerEvent is an event emitted when peers are either added or dropped from
  52. // a p2p.Server or when a message is sent or received on a peer connection
  53. type PeerEvent struct {
  54. Type PeerEventType `json:"type"`
  55. Peer enode.ID `json:"peer"`
  56. Error string `json:"error,omitempty"`
  57. Protocol string `json:"protocol,omitempty"`
  58. MsgCode *uint64 `json:"msg_code,omitempty"`
  59. MsgSize *uint32 `json:"msg_size,omitempty"`
  60. LocalAddress string `json:"local,omitempty"`
  61. RemoteAddress string `json:"remote,omitempty"`
  62. }
  63. // Peer represents a connected remote node.
  64. type Peer struct {
  65. rw *conn
  66. running map[string]*protoRW
  67. created mclock.AbsTime
  68. protoErr chan error
  69. closed chan struct{}
  70. disc chan DiscReason
  71. //wg sync.WaitGroup
  72. //log log.Logger
  73. // events receives message send / receive events if set
  74. //events *event.Feed
  75. }
  76. func newPeer(conn *conn, protocols []Protocol) *Peer {
  77. protoMap := matchProtocols(protocols, conn.caps, conn)
  78. p := &Peer{
  79. rw: conn,
  80. running: protoMap,
  81. created: mclock.Now(),
  82. protoErr: make(chan error, len(protoMap)+1),
  83. closed: make(chan struct{}),
  84. }
  85. return p
  86. }
  87. type protoRW struct {
  88. Protocol
  89. in chan Msg // receives read messages
  90. closed <-chan struct{} // receives when peer is shutting down
  91. wstart <-chan struct{} // receives when write may start
  92. werr chan<- error // for write results
  93. offset uint64
  94. w MsgWriter
  95. }
  96. func matchProtocols(protocols []Protocol, caps []Cap, rw MsgReadWriter) map[string]*protoRW {
  97. sort.Sort(capsByNameAndVersion(caps))
  98. offset := baseProtocolLength
  99. result := make(map[string]*protoRW)
  100. outer:
  101. for _, capability := range caps {
  102. for _, proto := range protocols {
  103. if proto.Name == capability.Name && proto.Version == capability.Version {
  104. if old := result[capability.Name]; old != nil {
  105. offset -= old.Length
  106. }
  107. result[capability.Name] = &protoRW{Protocol: proto, offset: offset, in: make(chan Msg), w: rw}
  108. offset += proto.Length
  109. continue outer
  110. }
  111. }
  112. }
  113. return result
  114. }