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.

111 lines
2.1 KiB

11 years ago
11 years ago
10 years ago
11 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
11 years ago
11 years ago
11 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
11 years ago
  1. package p2p
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "sync/atomic"
  7. . "github.com/tendermint/tendermint/binary"
  8. . "github.com/tendermint/tendermint/common"
  9. )
  10. /* Peer */
  11. type Peer struct {
  12. outbound bool
  13. mconn *MConnection
  14. started uint32
  15. stopped uint32
  16. Key string
  17. Data *CMap // User data.
  18. }
  19. func newPeer(conn net.Conn, outbound bool, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{})) *Peer {
  20. var p *Peer
  21. onReceive := func(chId byte, msgBytes []byte) {
  22. reactor := reactorsByCh[chId]
  23. if reactor == nil {
  24. Panicf("Unknown channel %X", chId)
  25. }
  26. reactor.Receive(chId, p, msgBytes)
  27. }
  28. onError := func(r interface{}) {
  29. p.stop()
  30. onPeerError(p, r)
  31. }
  32. mconn := NewMConnection(conn, chDescs, onReceive, onError)
  33. p = &Peer{
  34. outbound: outbound,
  35. mconn: mconn,
  36. stopped: 0,
  37. Key: mconn.RemoteAddress.String(),
  38. Data: NewCMap(),
  39. }
  40. return p
  41. }
  42. func (p *Peer) start() {
  43. if atomic.CompareAndSwapUint32(&p.started, 0, 1) {
  44. log.Debug("Starting %v", p)
  45. p.mconn.Start()
  46. }
  47. }
  48. func (p *Peer) stop() {
  49. if atomic.CompareAndSwapUint32(&p.stopped, 0, 1) {
  50. log.Debug("Stopping %v", p)
  51. p.mconn.Stop()
  52. }
  53. }
  54. func (p *Peer) IsStopped() bool {
  55. return atomic.LoadUint32(&p.stopped) == 1
  56. }
  57. func (p *Peer) RemoteAddress() *NetAddress {
  58. return p.mconn.RemoteAddress
  59. }
  60. func (p *Peer) IsOutbound() bool {
  61. return p.outbound
  62. }
  63. func (p *Peer) Send(chId byte, msg Binary) bool {
  64. if atomic.LoadUint32(&p.stopped) == 1 {
  65. return false
  66. }
  67. return p.mconn.Send(chId, msg)
  68. }
  69. func (p *Peer) TrySend(chId byte, msg Binary) bool {
  70. if atomic.LoadUint32(&p.stopped) == 1 {
  71. return false
  72. }
  73. return p.mconn.TrySend(chId, msg)
  74. }
  75. func (p *Peer) CanSend(chId byte) bool {
  76. if atomic.LoadUint32(&p.stopped) == 1 {
  77. return false
  78. }
  79. return p.mconn.CanSend(chId)
  80. }
  81. func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
  82. WriteString(w, p.Key, &n, &err)
  83. return
  84. }
  85. func (p *Peer) String() string {
  86. if p.outbound {
  87. return fmt.Sprintf("P(->%v)", p.mconn)
  88. } else {
  89. return fmt.Sprintf("P(%v->)", p.mconn)
  90. }
  91. }
  92. func (p *Peer) Equals(other *Peer) bool {
  93. return p.Key == other.Key
  94. }