9 log "github.com/sirupsen/logrus"
10 cmn "github.com/tendermint/tmlibs/common"
12 "github.com/vapor/errors"
13 "github.com/vapor/p2p/upnp"
17 numBufferedConnections = 10
18 defaultExternalPort = 8770
22 //Listener subset of the methods of DefaultListener
23 type Listener interface {
24 Connections() <-chan net.Conn
25 InternalAddress() *NetAddress
26 ExternalAddress() *NetAddress
31 //getUPNPExternalAddress UPNP external address discovery & port mapping
32 func getUPNPExternalAddress(externalPort, internalPort int) (*NetAddress, error) {
33 nat, err := upnp.Discover()
35 return nil, errors.Wrap(err, "could not perform UPNP discover")
38 ext, err := nat.GetExternalAddress()
40 return nil, errors.Wrap(err, "could not perform UPNP external address")
43 if externalPort == 0 {
44 externalPort = defaultExternalPort
46 externalPort, err = nat.AddPortMapping("tcp", externalPort, internalPort, "bytomd tcp", 0)
48 return nil, errors.Wrap(err, "could not add tcp UPNP port mapping")
50 externalPort, err = nat.AddPortMapping("udp", externalPort, internalPort, "bytomd udp", 0)
52 return nil, errors.Wrap(err, "could not add udp UPNP port mapping")
54 return NewNetAddressIPPort(ext, uint16(externalPort)), nil
57 func getNaiveExternalAddress(port int, settleForLocal bool) *NetAddress {
58 addrs, err := net.InterfaceAddrs()
60 cmn.PanicCrisis(cmn.Fmt("Could not fetch interface addresses: %v", err))
63 for _, a := range addrs {
64 ipnet, ok := a.(*net.IPNet)
68 if v4 := ipnet.IP.To4(); v4 == nil || (!settleForLocal && v4[0] == 127) {
71 return NewNetAddressIPPort(ipnet.IP, uint16(port))
74 log.Info("Node may not be connected to internet. Settling for local address")
75 return getNaiveExternalAddress(port, true)
78 func splitHostPort(addr string) (host string, port int) {
79 host, portStr, err := net.SplitHostPort(addr)
83 port, err = strconv.Atoi(portStr)
90 //DefaultListener Implements bytomd server Listener
91 type DefaultListener struct {
97 connections chan net.Conn
100 //NewDefaultListener create a default listener
101 func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) (Listener, bool) {
102 // Local listen IP & port
103 lAddrIP, lAddrPort := splitHostPort(lAddr)
105 listener, err := net.Listen(protocol, lAddr)
106 for i := 0; i < tryListenTimes && err != nil; i++ {
107 time.Sleep(time.Second * 1)
108 listener, err = net.Listen(protocol, lAddr)
114 intAddr, err := NewNetAddressString(lAddr)
119 // Actual listener local IP & port
120 listenerIP, listenerPort := splitHostPort(listener.Addr().String())
121 log.Info("Local listener", " ip:", listenerIP, " port:", listenerPort)
123 // Determine external address...
124 var extAddr *NetAddress
126 if !skipUPNP && (lAddrIP == "" || lAddrIP == "0.0.0.0") {
127 extAddr, err = getUPNPExternalAddress(lAddrPort, listenerPort)
129 log.WithField("err", err).Info("get UPNP external address")
133 if address := GetIP(); address.Success == true {
134 extAddr = NewNetAddressIPPort(net.ParseIP(address.IP), uint16(lAddrPort))
138 extAddr = getNaiveExternalAddress(listenerPort, false)
141 cmn.PanicCrisis("could not determine external address!")
144 dl := &DefaultListener{
148 connections: make(chan net.Conn, numBufferedConnections),
150 dl.BaseService = *cmn.NewBaseService(nil, "DefaultListener", dl)
151 dl.Start() // Started upon construction
156 conn, err := net.DialTimeout("tcp", extAddr.String(), 3*time.Second)
164 //OnStart start listener
165 func (l *DefaultListener) OnStart() error {
166 l.BaseService.OnStart()
171 //OnStop stop listener
172 func (l *DefaultListener) OnStop() {
173 l.BaseService.OnStop()
177 //listenRoutine Accept connections and pass on the channel
178 func (l *DefaultListener) listenRoutine() {
180 conn, err := l.listener.Accept()
182 break // Go to cleanup
184 // listener wasn't stopped,
185 // yet we encountered an error.
189 l.connections <- conn
195 //Connections a channel of inbound connections. It gets closed when the listener closes.
196 func (l *DefaultListener) Connections() <-chan net.Conn {
200 //InternalAddress listener internal address
201 func (l *DefaultListener) InternalAddress() *NetAddress {
205 //ExternalAddress listener external address for remote peer dial
206 func (l *DefaultListener) ExternalAddress() *NetAddress {
210 // NetListener the returned listener is already Accept()'ing. So it's not suitable to pass into http.Serve().
211 func (l *DefaultListener) NetListener() net.Listener {
215 //String string of default listener
216 func (l *DefaultListener) String() string {
217 return fmt.Sprintf("Listener(@%v)", l.extAddr)