conn.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package p2p
  2. import (
  3. "blockchain-go/p2p/enode"
  4. "net"
  5. "sync/atomic"
  6. )
  7. type connFlag int32
  8. func (f connFlag) String() string {
  9. s := ""
  10. if f&trustedConn != 0 {
  11. s += "-trusted"
  12. }
  13. if f&dynDialedConn != 0 {
  14. s += "-dyndial"
  15. }
  16. if f&staticDialedConn != 0 {
  17. s += "-staticdial"
  18. }
  19. if f&inboundConn != 0 {
  20. s += "-inbound"
  21. }
  22. if s != "" {
  23. s = s[1:]
  24. }
  25. return s
  26. }
  27. const (
  28. dynDialedConn connFlag = 1 << iota
  29. staticDialedConn
  30. inboundConn
  31. trustedConn
  32. )
  33. // conn wraps a network connection with information gathered
  34. // during the two handshakes.
  35. type conn struct {
  36. fd net.Conn
  37. transport
  38. node *enode.Node
  39. flags connFlag
  40. cont chan error // The run loop uses cont to signal errors to SetupConn.
  41. caps []Cap // valid after the protocol handshake
  42. name string // valid after the protocol handshake
  43. }
  44. func (c *conn) String() string {
  45. s := c.flags.String()
  46. if (c.node.ID() != enode.ID{}) {
  47. s += " " + c.node.ID().String()
  48. }
  49. s += " " + c.fd.RemoteAddr().String()
  50. return s
  51. }
  52. func (c *conn) is(f connFlag) bool {
  53. flags := connFlag(atomic.LoadInt32((*int32)(&c.flags)))
  54. return flags&f != 0
  55. }
  56. func (c *conn) set(f connFlag, val bool) {
  57. for {
  58. oldFlags := connFlag(atomic.LoadInt32((*int32)(&c.flags)))
  59. flags := oldFlags
  60. if val {
  61. flags |= f
  62. } else {
  63. flags &= ^f
  64. }
  65. if atomic.CompareAndSwapInt32((*int32)(&c.flags), int32(oldFlags), int32(flags)) {
  66. return
  67. }
  68. }
  69. }