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.

145 lines
2.8 KiB

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