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.

125 lines
2.6 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
  1. package peer
  2. import (
  3. "sync/atomic"
  4. "net"
  5. )
  6. const (
  7. DEFAULT_PORT = 8001
  8. )
  9. /* Listener */
  10. type Listener interface {
  11. Connections() <-chan *Connection
  12. LocalAddress() *NetAddress
  13. Stop()
  14. }
  15. /* DefaultListener */
  16. type DefaultListener struct {
  17. listener net.Listener
  18. connections chan *Connection
  19. stopped uint32
  20. }
  21. const (
  22. DEFAULT_BUFFERED_CONNECTIONS = 10
  23. )
  24. func NewDefaultListener(protocol string, listenAddr string) Listener {
  25. listener, err := net.Listen(protocol, listenAddr)
  26. if err != nil { panic(err) }
  27. dl := &DefaultListener{
  28. listener: listener,
  29. connections: make(chan *Connection, DEFAULT_BUFFERED_CONNECTIONS),
  30. }
  31. go dl.listenHandler()
  32. return dl
  33. }
  34. func (l *DefaultListener) listenHandler() {
  35. for {
  36. conn, err := l.listener.Accept()
  37. if atomic.LoadUint32(&l.stopped) == 1 { return }
  38. // listener wasn't stopped,
  39. // yet we encountered an error.
  40. if err != nil { panic(err) }
  41. c := NewConnection(conn)
  42. l.connections <- c
  43. }
  44. // cleanup
  45. close(l.connections)
  46. for _ = range l.connections {
  47. // drain
  48. }
  49. }
  50. func (l *DefaultListener) Connections() <-chan *Connection {
  51. return l.connections
  52. }
  53. func (l *DefaultListener) LocalAddress() *NetAddress {
  54. return GetLocalAddress()
  55. }
  56. func (l *DefaultListener) Stop() {
  57. if atomic.CompareAndSwapUint32(&l.stopped, 0, 1) {
  58. l.listener.Close()
  59. }
  60. }
  61. /* local address helpers */
  62. func GetLocalAddress() *NetAddress {
  63. laddr := GetUPNPLocalAddress()
  64. if laddr != nil { return laddr }
  65. laddr = GetDefaultLocalAddress()
  66. if laddr != nil { return laddr }
  67. panic("Could not determine local address")
  68. }
  69. // UPNP external address discovery & port mapping
  70. // TODO: more flexible internal & external ports
  71. func GetUPNPLocalAddress() *NetAddress {
  72. nat, err := Discover()
  73. if err != nil { return nil }
  74. ext, err := nat.GetExternalAddress()
  75. if err != nil { return nil }
  76. _, err := nat.AddPortMapping("tcp", DEFAULT_PORT, DEFAULT_PORT, "tendermint", 0)
  77. if err != nil { return nil }
  78. return NewNetAddressIPPort(ext, DEFAULT_PORT)
  79. }
  80. // Naive local IPv4 interface address detection
  81. // TODO: use syscalls to get actual ourIP. http://pastebin.com/9exZG4rh
  82. func GetDefaultLocalAddress() *NetAddress {
  83. addrs, err := net.InterfaceAddrs()
  84. if err != nil { panic("Wtf") }
  85. for _, a := range addrs {
  86. ipnet, ok := a.(*net.IPNet)
  87. if !ok { continue }
  88. v4 := ipnet.IP.To4()
  89. if v4 == nil || v4[0] == 127 { continue } // loopback
  90. return NewNetAddress(a)
  91. }
  92. return nil
  93. }