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.

210 lines
4.7 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. package p2p
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/p2p/upnp"
  8. )
  9. type Listener interface {
  10. Connections() <-chan net.Conn
  11. InternalAddress() *NetAddress
  12. ExternalAddress() *NetAddress
  13. String() string
  14. Stop() bool
  15. }
  16. // Implements Listener
  17. type DefaultListener struct {
  18. BaseService
  19. listener net.Listener
  20. intAddr *NetAddress
  21. extAddr *NetAddress
  22. connections chan net.Conn
  23. }
  24. const (
  25. numBufferedConnections = 10
  26. defaultExternalPort = 8770
  27. )
  28. func splitHostPort(addr string) (host string, port int) {
  29. host, portStr, err := net.SplitHostPort(addr)
  30. if err != nil {
  31. PanicSanity(err)
  32. }
  33. port, err = strconv.Atoi(portStr)
  34. if err != nil {
  35. PanicSanity(err)
  36. }
  37. return host, port
  38. }
  39. func NewDefaultListener(protocol string, lAddr string, requireUPNPHairpin bool) Listener {
  40. // Local listen IP & port
  41. lAddrIP, lAddrPort := splitHostPort(lAddr)
  42. // Create listener
  43. listener, err := net.Listen(protocol, lAddr)
  44. if err != nil {
  45. PanicCrisis(err)
  46. }
  47. // Actual listener local IP & port
  48. listenerIP, listenerPort := splitHostPort(listener.Addr().String())
  49. log.Info("Local listener", "ip", listenerIP, "port", listenerPort)
  50. // Determine internal address...
  51. var intAddr *NetAddress = NewNetAddressString(lAddr)
  52. // Determine external address...
  53. var extAddr *NetAddress
  54. // If the lAddrIP is INADDR_ANY, try UPnP
  55. if lAddrIP == "" || lAddrIP == "0.0.0.0" {
  56. if requireUPNPHairpin {
  57. upnpCapabilities, err := upnp.Probe()
  58. if err != nil {
  59. log.Warn("Failed to probe UPNP", "error", err)
  60. goto SKIP_UPNP
  61. }
  62. if !upnpCapabilities.Hairpin {
  63. goto SKIP_UPNP
  64. }
  65. }
  66. extAddr = getUPNPExternalAddress(lAddrPort, listenerPort)
  67. }
  68. SKIP_UPNP:
  69. // Otherwise just use the local address...
  70. if extAddr == nil {
  71. extAddr = getNaiveExternalAddress(listenerPort)
  72. }
  73. if extAddr == nil {
  74. PanicCrisis("Could not determine external address!")
  75. }
  76. dl := &DefaultListener{
  77. listener: listener,
  78. intAddr: intAddr,
  79. extAddr: extAddr,
  80. connections: make(chan net.Conn, numBufferedConnections),
  81. }
  82. dl.BaseService = *NewBaseService(log, "DefaultListener", dl)
  83. dl.Start() // Started upon construction
  84. return dl
  85. }
  86. func (l *DefaultListener) OnStart() {
  87. l.BaseService.OnStart()
  88. go l.listenRoutine()
  89. }
  90. func (l *DefaultListener) OnStop() {
  91. l.BaseService.OnStop()
  92. l.listener.Close()
  93. }
  94. // Accept connections and pass on the channel
  95. func (l *DefaultListener) listenRoutine() {
  96. for {
  97. conn, err := l.listener.Accept()
  98. if !l.IsRunning() {
  99. break // Go to cleanup
  100. }
  101. // listener wasn't stopped,
  102. // yet we encountered an error.
  103. if err != nil {
  104. PanicCrisis(err)
  105. }
  106. l.connections <- conn
  107. }
  108. // Cleanup
  109. close(l.connections)
  110. for _ = range l.connections {
  111. // Drain
  112. }
  113. }
  114. // A channel of inbound connections.
  115. // It gets closed when the listener closes.
  116. func (l *DefaultListener) Connections() <-chan net.Conn {
  117. return l.connections
  118. }
  119. func (l *DefaultListener) InternalAddress() *NetAddress {
  120. return l.intAddr
  121. }
  122. func (l *DefaultListener) ExternalAddress() *NetAddress {
  123. return l.extAddr
  124. }
  125. // NOTE: The returned listener is already Accept()'ing.
  126. // So it's not suitable to pass into http.Serve().
  127. func (l *DefaultListener) NetListener() net.Listener {
  128. return l.listener
  129. }
  130. func (l *DefaultListener) String() string {
  131. return fmt.Sprintf("Listener(@%v)", l.extAddr)
  132. }
  133. /* external address helpers */
  134. // UPNP external address discovery & port mapping
  135. func getUPNPExternalAddress(externalPort, internalPort int) *NetAddress {
  136. log.Info("Getting UPNP external address")
  137. nat, err := upnp.Discover()
  138. if err != nil {
  139. log.Info("Could not perform UPNP discover", "error", err)
  140. return nil
  141. }
  142. ext, err := nat.GetExternalAddress()
  143. if err != nil {
  144. log.Info("Could not get UPNP external address", "error", err)
  145. return nil
  146. }
  147. // UPnP can't seem to get the external port, so let's just be explicit.
  148. if externalPort == 0 {
  149. externalPort = defaultExternalPort
  150. }
  151. externalPort, err = nat.AddPortMapping("tcp", externalPort, internalPort, "tendermint", 0)
  152. if err != nil {
  153. log.Info("Could not add UPNP port mapping", "error", err)
  154. return nil
  155. }
  156. log.Info("Got UPNP external address", "address", ext)
  157. return NewNetAddressIPPort(ext, uint16(externalPort))
  158. }
  159. // TODO: use syscalls: http://pastebin.com/9exZG4rh
  160. func getNaiveExternalAddress(port int) *NetAddress {
  161. addrs, err := net.InterfaceAddrs()
  162. if err != nil {
  163. PanicCrisis(Fmt("Could not fetch interface addresses: %v", err))
  164. }
  165. for _, a := range addrs {
  166. ipnet, ok := a.(*net.IPNet)
  167. if !ok {
  168. continue
  169. }
  170. v4 := ipnet.IP.To4()
  171. if v4 == nil || v4[0] == 127 {
  172. continue
  173. } // loopback
  174. return NewNetAddressIPPort(ipnet.IP, uint16(port))
  175. }
  176. return nil
  177. }