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.

139 lines
2.8 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
10 years ago
10 years ago
  1. package p2p
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "sync"
  7. "sync/atomic"
  8. "github.com/tendermint/tendermint/binary"
  9. . "github.com/tendermint/tendermint/common"
  10. "github.com/tendermint/tendermint/types"
  11. )
  12. type Peer struct {
  13. outbound bool
  14. mconn *MConnection
  15. running uint32
  16. *types.NodeInfo
  17. Key string
  18. Data *CMap // User data.
  19. }
  20. func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, error) {
  21. var peerNodeInfo = new(types.NodeInfo)
  22. var wg sync.WaitGroup
  23. var err1 error
  24. var err2 error
  25. wg.Add(2)
  26. go func() {
  27. var n int64
  28. binary.WriteBinary(ourNodeInfo, conn, &n, &err1)
  29. wg.Done()
  30. }()
  31. go func() {
  32. var n int64
  33. binary.ReadBinary(peerNodeInfo, conn, &n, &err2)
  34. log.Info("Peer handshake", "peerNodeInfo", peerNodeInfo)
  35. wg.Done()
  36. }()
  37. wg.Wait()
  38. if err1 != nil {
  39. return nil, err1
  40. }
  41. if err2 != nil {
  42. return nil, err2
  43. }
  44. return peerNodeInfo, nil
  45. }
  46. func newPeer(conn net.Conn, peerNodeInfo *types.NodeInfo, outbound bool, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{})) *Peer {
  47. var p *Peer
  48. onReceive := func(chId byte, msgBytes []byte) {
  49. reactor := reactorsByCh[chId]
  50. if reactor == nil {
  51. panic(Fmt("Unknown channel %X", chId))
  52. }
  53. reactor.Receive(chId, p, msgBytes)
  54. }
  55. onError := func(r interface{}) {
  56. p.stop()
  57. onPeerError(p, r)
  58. }
  59. mconn := NewMConnection(conn, chDescs, onReceive, onError)
  60. p = &Peer{
  61. outbound: outbound,
  62. mconn: mconn,
  63. running: 0,
  64. NodeInfo: peerNodeInfo,
  65. Key: mconn.RemoteAddress.IP.String(),
  66. Data: NewCMap(),
  67. }
  68. return p
  69. }
  70. func (p *Peer) start() {
  71. if atomic.CompareAndSwapUint32(&p.running, 0, 1) {
  72. log.Debug("Starting Peer", "peer", p)
  73. p.mconn.Start()
  74. }
  75. }
  76. func (p *Peer) stop() {
  77. if atomic.CompareAndSwapUint32(&p.running, 1, 0) {
  78. log.Debug("Stopping Peer", "peer", p)
  79. p.mconn.Stop()
  80. }
  81. }
  82. func (p *Peer) IsRunning() bool {
  83. return atomic.LoadUint32(&p.running) == 1
  84. }
  85. func (p *Peer) Connection() *MConnection {
  86. return p.mconn
  87. }
  88. func (p *Peer) IsOutbound() bool {
  89. return p.outbound
  90. }
  91. func (p *Peer) Send(chId byte, msg interface{}) bool {
  92. if atomic.LoadUint32(&p.running) == 0 {
  93. return false
  94. }
  95. return p.mconn.Send(chId, msg)
  96. }
  97. func (p *Peer) TrySend(chId byte, msg interface{}) bool {
  98. if atomic.LoadUint32(&p.running) == 0 {
  99. return false
  100. }
  101. return p.mconn.TrySend(chId, msg)
  102. }
  103. func (p *Peer) CanSend(chId byte) bool {
  104. if atomic.LoadUint32(&p.running) == 0 {
  105. return false
  106. }
  107. return p.mconn.CanSend(chId)
  108. }
  109. func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
  110. binary.WriteString(p.Key, w, &n, &err)
  111. return
  112. }
  113. func (p *Peer) String() string {
  114. if p.outbound {
  115. return fmt.Sprintf("Peer{->%v}", p.mconn)
  116. } else {
  117. return fmt.Sprintf("Peer{%v->}", p.mconn)
  118. }
  119. }
  120. func (p *Peer) Equals(other *Peer) bool {
  121. return p.Key == other.Key
  122. }