2017-10-04 17:19:49 -04:00
|
|
|
// Taken from taipei-torrent.
|
|
|
|
// Just enough UPnP to be able to forward ports
|
|
|
|
// For more information, see: http://www.upnp-hacks.org/upnp.html
|
2015-10-25 18:21:51 -07:00
|
|
|
package upnp
|
|
|
|
|
2017-10-04 17:19:49 -04:00
|
|
|
// TODO: use syscalls to get actual ourIP, see issue #712
|
2015-10-25 18:21:51 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/xml"
|
|
|
|
"errors"
|
return an error if we fail to parse external IP
```
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
```
Fixes #1717
```
I[06-08|11:51:56.952] Starting multiAppConn module=proxy impl=multiAppConn
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=query impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=mempool impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=consensus impl=localClient
I[06-08|11:51:56.952] ABCI Handshake module=consensus appHeight=0 appHash=
I[06-08|11:51:56.952] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0
I[06-08|11:51:57.053] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=0 appHash=
I[06-08|11:51:57.053] This node is a validator module=consensus addr=6816B5D9BAC32A3CDF07884D9D3D2650694C371D pubKey=PubKeyEd25519{27A40CD032DD2467342D0CF27C5EC92052D966FEC714B6CF2F3BF3146AFD0D51}
I[06-08|11:51:57.234] Starting Node module=main impl=Node
I[06-08|11:51:57.234] Starting EventBus module=events impl=EventBus
I[06-08|11:51:57.234] Local listener module=p2p ip=:: port=46656
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
I[06-08|11:51:58.867] Starting DefaultListener module=p2p impl=Listener(@<nil>:46656)
I[06-08|11:51:58.867] P2P Node ID module=main ID=3629b516392e494ae717ac4c6a1ea7eb0fe421c3 file=/home/tpb/.tendermint/config/node_key.json
I[06-08|11:51:58.868] Add our address to book module=p2p book=/home/tpb/.tendermint/config/addrbook.json addr=null
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x89fb86]
goroutine 1 [running]:
github.com/tendermint/tendermint/p2p.(*NetAddress).String(0x0, 0xc96e24, 0x17)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/netaddress.go:171 +0x26
github.com/tendermint/tendermint/p2p/pex.(*addrBook).AddOurAddress(0xc420190620, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/pex/addrbook.go:160 +0x116
github.com/tendermint/tendermint/node.(*Node).OnStart(0xc420286d00, 0xc4201b8010, 0xd)
/home/tpb/code/go/src/github.com/tendermint/tendermint/node/node.go:402 +0x547
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start(0xc420286d00, 0xe51c40, 0xc42000bd40)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x3bd
github.com/tendermint/tendermint/cmd/tendermint/commands.NewRunNodeCmd.func1(0xc42022e000, 0xc4200acdc0, 0x0, 0x1, 0x0, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/commands/run_node.go:58 +0xfe
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).execute(0xc42022e000, 0xc4200acda0, 0x1, 0x1, 0xc42022e000, 0xc4200acda0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:762 +0x468
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0x1289280, 0xbbdda0, 0xc420015e01, 0xc4201bc640)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:852 +0x30a
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).Execute(0x1289280, 0xc4201bc640, 0xc420015e98)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:800 +0x2b
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli.Executor.Execute(0x1289280, 0xde5798, 0x2, 0xc4200332c0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli/setup.go:89 +0x4e
main.main()
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/main.go:45 +0x24d
```
2018-06-09 15:03:38 +04:00
|
|
|
"fmt"
|
2015-10-25 18:21:51 -07:00
|
|
|
"io/ioutil"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type upnpNAT struct {
|
|
|
|
serviceURL string
|
|
|
|
ourIP string
|
|
|
|
urnDomain string
|
|
|
|
}
|
|
|
|
|
|
|
|
// protocol is either "udp" or "tcp"
|
|
|
|
type NAT interface {
|
|
|
|
GetExternalAddress() (addr net.IP, err error)
|
|
|
|
AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error)
|
|
|
|
DeletePortMapping(protocol string, externalPort, internalPort int) (err error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Discover() (nat NAT, err error) {
|
|
|
|
ssdp, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
conn, err := net.ListenPacket("udp4", ":0")
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
socket := conn.(*net.UDPConn)
|
2017-10-03 18:49:20 -04:00
|
|
|
defer socket.Close() // nolint: errcheck
|
2015-10-25 18:21:51 -07:00
|
|
|
|
2017-09-06 13:11:47 -04:00
|
|
|
if err := socket.SetDeadline(time.Now().Add(3 * time.Second)); err != nil {
|
|
|
|
return nil, err
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
st := "InternetGatewayDevice:1"
|
|
|
|
|
|
|
|
buf := bytes.NewBufferString(
|
|
|
|
"M-SEARCH * HTTP/1.1\r\n" +
|
|
|
|
"HOST: 239.255.255.250:1900\r\n" +
|
|
|
|
"ST: ssdp:all\r\n" +
|
|
|
|
"MAN: \"ssdp:discover\"\r\n" +
|
|
|
|
"MX: 2\r\n\r\n")
|
|
|
|
message := buf.Bytes()
|
|
|
|
answerBytes := make([]byte, 1024)
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
_, err = socket.WriteToUDP(message, ssdp)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var n int
|
2017-05-29 23:11:40 -04:00
|
|
|
_, _, err = socket.ReadFromUDP(answerBytes)
|
2017-10-03 19:11:55 -04:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2015-10-25 18:21:51 -07:00
|
|
|
for {
|
|
|
|
n, _, err = socket.ReadFromUDP(answerBytes)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
answer := string(answerBytes[0:n])
|
2017-05-29 23:11:40 -04:00
|
|
|
if !strings.Contains(answer, st) {
|
2015-10-25 18:21:51 -07:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
// HTTP header field names are case-insensitive.
|
|
|
|
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
|
|
|
locString := "\r\nlocation:"
|
|
|
|
answer = strings.ToLower(answer)
|
|
|
|
locIndex := strings.Index(answer, locString)
|
|
|
|
if locIndex < 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
loc := answer[locIndex+len(locString):]
|
|
|
|
endIndex := strings.Index(loc, "\r\n")
|
|
|
|
if endIndex < 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
locURL := strings.TrimSpace(loc[0:endIndex])
|
|
|
|
var serviceURL, urnDomain string
|
|
|
|
serviceURL, urnDomain, err = getServiceURL(locURL)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var ourIP net.IP
|
|
|
|
ourIP, err = localIPv4()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
nat = &upnpNAT{serviceURL: serviceURL, ourIP: ourIP.String(), urnDomain: urnDomain}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-04-02 10:21:17 +02:00
|
|
|
err = errors.New("UPnP port discovery failed")
|
2019-09-10 03:31:44 -04:00
|
|
|
return nat, err
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type Envelope struct {
|
|
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
|
|
|
|
Soap *SoapBody
|
|
|
|
}
|
|
|
|
type SoapBody struct {
|
|
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
|
|
|
|
ExternalIP *ExternalIPAddressResponse
|
|
|
|
}
|
|
|
|
|
|
|
|
type ExternalIPAddressResponse struct {
|
|
|
|
XMLName xml.Name `xml:"GetExternalIPAddressResponse"`
|
|
|
|
IPAddress string `xml:"NewExternalIPAddress"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type ExternalIPAddress struct {
|
|
|
|
XMLName xml.Name `xml:"NewExternalIPAddress"`
|
|
|
|
IP string
|
|
|
|
}
|
|
|
|
|
|
|
|
type UPNPService struct {
|
|
|
|
ServiceType string `xml:"serviceType"`
|
|
|
|
ControlURL string `xml:"controlURL"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type DeviceList struct {
|
|
|
|
Device []Device `xml:"device"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type ServiceList struct {
|
|
|
|
Service []UPNPService `xml:"service"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Device struct {
|
|
|
|
XMLName xml.Name `xml:"device"`
|
|
|
|
DeviceType string `xml:"deviceType"`
|
|
|
|
DeviceList DeviceList `xml:"deviceList"`
|
|
|
|
ServiceList ServiceList `xml:"serviceList"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Root struct {
|
|
|
|
Device Device
|
|
|
|
}
|
|
|
|
|
|
|
|
func getChildDevice(d *Device, deviceType string) *Device {
|
|
|
|
dl := d.DeviceList.Device
|
|
|
|
for i := 0; i < len(dl); i++ {
|
2017-05-29 23:11:40 -04:00
|
|
|
if strings.Contains(dl[i].DeviceType, deviceType) {
|
2015-10-25 18:21:51 -07:00
|
|
|
return &dl[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getChildService(d *Device, serviceType string) *UPNPService {
|
|
|
|
sl := d.ServiceList.Service
|
|
|
|
for i := 0; i < len(sl); i++ {
|
2017-05-29 23:11:40 -04:00
|
|
|
if strings.Contains(sl[i].ServiceType, serviceType) {
|
2015-10-25 18:21:51 -07:00
|
|
|
return &sl[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func localIPv4() (net.IP, error) {
|
|
|
|
tt, err := net.Interfaces()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, t := range tt {
|
|
|
|
aa, err := t.Addrs()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, a := range aa {
|
|
|
|
ipnet, ok := a.(*net.IPNet)
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
v4 := ipnet.IP.To4()
|
|
|
|
if v4 == nil || v4[0] == 127 { // loopback address
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return v4, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, errors.New("cannot find local IP address")
|
|
|
|
}
|
|
|
|
|
|
|
|
func getServiceURL(rootURL string) (url, urnDomain string, err error) {
|
2019-06-21 07:58:32 +02:00
|
|
|
r, err := http.Get(rootURL) // nolint: gosec
|
2015-10-25 18:21:51 -07:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2017-10-03 18:49:20 -04:00
|
|
|
defer r.Body.Close() // nolint: errcheck
|
2017-09-21 09:55:06 -04:00
|
|
|
|
2015-10-25 18:21:51 -07:00
|
|
|
if r.StatusCode >= 400 {
|
|
|
|
err = errors.New(string(r.StatusCode))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var root Root
|
|
|
|
err = xml.NewDecoder(r.Body).Decode(&root)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
a := &root.Device
|
2017-05-29 23:11:40 -04:00
|
|
|
if !strings.Contains(a.DeviceType, "InternetGatewayDevice:1") {
|
2015-10-25 18:21:51 -07:00
|
|
|
err = errors.New("No InternetGatewayDevice")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
b := getChildDevice(a, "WANDevice:1")
|
|
|
|
if b == nil {
|
|
|
|
err = errors.New("No WANDevice")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c := getChildDevice(b, "WANConnectionDevice:1")
|
|
|
|
if c == nil {
|
|
|
|
err = errors.New("No WANConnectionDevice")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
d := getChildService(c, "WANIPConnection:1")
|
|
|
|
if d == nil {
|
|
|
|
// Some routers don't follow the UPnP spec, and put WanIPConnection under WanDevice,
|
|
|
|
// instead of under WanConnectionDevice
|
|
|
|
d = getChildService(b, "WANIPConnection:1")
|
|
|
|
|
|
|
|
if d == nil {
|
|
|
|
err = errors.New("No WANIPConnection")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Extract the domain name, which isn't always 'schemas-upnp-org'
|
|
|
|
urnDomain = strings.Split(d.ServiceType, ":")[1]
|
|
|
|
url = combineURL(rootURL, d.ControlURL)
|
2019-09-10 03:31:44 -04:00
|
|
|
return url, urnDomain, err
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func combineURL(rootURL, subURL string) string {
|
|
|
|
protocolEnd := "://"
|
|
|
|
protoEndIndex := strings.Index(rootURL, protocolEnd)
|
|
|
|
a := rootURL[protoEndIndex+len(protocolEnd):]
|
|
|
|
rootIndex := strings.Index(a, "/")
|
|
|
|
return rootURL[0:protoEndIndex+len(protocolEnd)+rootIndex] + subURL
|
|
|
|
}
|
|
|
|
|
|
|
|
func soapRequest(url, function, message, domain string) (r *http.Response, err error) {
|
|
|
|
fullMessage := "<?xml version=\"1.0\" ?>" +
|
|
|
|
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" +
|
|
|
|
"<s:Body>" + message + "</s:Body></s:Envelope>"
|
|
|
|
|
|
|
|
req, err := http.NewRequest("POST", url, strings.NewReader(fullMessage))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "text/xml ; charset=\"utf-8\"")
|
|
|
|
req.Header.Set("User-Agent", "Darwin/10.0.0, UPnP/1.0, MiniUPnPc/1.3")
|
|
|
|
//req.Header.Set("Transfer-Encoding", "chunked")
|
|
|
|
req.Header.Set("SOAPAction", "\"urn:"+domain+":service:WANIPConnection:1#"+function+"\"")
|
|
|
|
req.Header.Set("Connection", "Close")
|
|
|
|
req.Header.Set("Cache-Control", "no-cache")
|
|
|
|
req.Header.Set("Pragma", "no-cache")
|
|
|
|
|
|
|
|
// log.Stderr("soapRequest ", req)
|
|
|
|
|
|
|
|
r, err = http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
/*if r.Body != nil {
|
|
|
|
defer r.Body.Close()
|
|
|
|
}*/
|
|
|
|
|
|
|
|
if r.StatusCode >= 400 {
|
|
|
|
// log.Stderr(function, r.StatusCode)
|
|
|
|
err = errors.New("Error " + strconv.Itoa(r.StatusCode) + " for " + function)
|
|
|
|
r = nil
|
|
|
|
return
|
|
|
|
}
|
2019-09-10 03:31:44 -04:00
|
|
|
return r, err
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type statusInfo struct {
|
|
|
|
externalIpAddress string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *upnpNAT) getExternalIPAddress() (info statusInfo, err error) {
|
|
|
|
|
|
|
|
message := "<u:GetExternalIPAddress xmlns:u=\"urn:" + n.urnDomain + ":service:WANIPConnection:1\">\r\n" +
|
|
|
|
"</u:GetExternalIPAddress>"
|
|
|
|
|
|
|
|
var response *http.Response
|
|
|
|
response, err = soapRequest(n.serviceURL, "GetExternalIPAddress", message, n.urnDomain)
|
|
|
|
if response != nil {
|
2017-10-03 18:49:20 -04:00
|
|
|
defer response.Body.Close() // nolint: errcheck
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var envelope Envelope
|
|
|
|
data, err := ioutil.ReadAll(response.Body)
|
2017-09-06 13:11:47 -04:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2015-10-25 18:21:51 -07:00
|
|
|
reader := bytes.NewReader(data)
|
2017-09-06 13:11:47 -04:00
|
|
|
err = xml.NewDecoder(reader).Decode(&envelope)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2015-10-25 18:21:51 -07:00
|
|
|
|
|
|
|
info = statusInfo{envelope.Soap.ExternalIP.IPAddress}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-10 03:31:44 -04:00
|
|
|
return info, err
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
|
return an error if we fail to parse external IP
```
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
```
Fixes #1717
```
I[06-08|11:51:56.952] Starting multiAppConn module=proxy impl=multiAppConn
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=query impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=mempool impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=consensus impl=localClient
I[06-08|11:51:56.952] ABCI Handshake module=consensus appHeight=0 appHash=
I[06-08|11:51:56.952] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0
I[06-08|11:51:57.053] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=0 appHash=
I[06-08|11:51:57.053] This node is a validator module=consensus addr=6816B5D9BAC32A3CDF07884D9D3D2650694C371D pubKey=PubKeyEd25519{27A40CD032DD2467342D0CF27C5EC92052D966FEC714B6CF2F3BF3146AFD0D51}
I[06-08|11:51:57.234] Starting Node module=main impl=Node
I[06-08|11:51:57.234] Starting EventBus module=events impl=EventBus
I[06-08|11:51:57.234] Local listener module=p2p ip=:: port=46656
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
I[06-08|11:51:58.867] Starting DefaultListener module=p2p impl=Listener(@<nil>:46656)
I[06-08|11:51:58.867] P2P Node ID module=main ID=3629b516392e494ae717ac4c6a1ea7eb0fe421c3 file=/home/tpb/.tendermint/config/node_key.json
I[06-08|11:51:58.868] Add our address to book module=p2p book=/home/tpb/.tendermint/config/addrbook.json addr=null
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x89fb86]
goroutine 1 [running]:
github.com/tendermint/tendermint/p2p.(*NetAddress).String(0x0, 0xc96e24, 0x17)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/netaddress.go:171 +0x26
github.com/tendermint/tendermint/p2p/pex.(*addrBook).AddOurAddress(0xc420190620, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/pex/addrbook.go:160 +0x116
github.com/tendermint/tendermint/node.(*Node).OnStart(0xc420286d00, 0xc4201b8010, 0xd)
/home/tpb/code/go/src/github.com/tendermint/tendermint/node/node.go:402 +0x547
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start(0xc420286d00, 0xe51c40, 0xc42000bd40)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x3bd
github.com/tendermint/tendermint/cmd/tendermint/commands.NewRunNodeCmd.func1(0xc42022e000, 0xc4200acdc0, 0x0, 0x1, 0x0, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/commands/run_node.go:58 +0xfe
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).execute(0xc42022e000, 0xc4200acda0, 0x1, 0x1, 0xc42022e000, 0xc4200acda0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:762 +0x468
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0x1289280, 0xbbdda0, 0xc420015e01, 0xc4201bc640)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:852 +0x30a
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).Execute(0x1289280, 0xc4201bc640, 0xc420015e98)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:800 +0x2b
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli.Executor.Execute(0x1289280, 0xde5798, 0x2, 0xc4200332c0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli/setup.go:89 +0x4e
main.main()
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/main.go:45 +0x24d
```
2018-06-09 15:03:38 +04:00
|
|
|
// GetExternalAddress returns an external IP. If GetExternalIPAddress action
|
|
|
|
// fails or IP returned is invalid, GetExternalAddress returns an error.
|
2015-10-25 18:21:51 -07:00
|
|
|
func (n *upnpNAT) GetExternalAddress() (addr net.IP, err error) {
|
|
|
|
info, err := n.getExternalIPAddress()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
addr = net.ParseIP(info.externalIpAddress)
|
return an error if we fail to parse external IP
```
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
```
Fixes #1717
```
I[06-08|11:51:56.952] Starting multiAppConn module=proxy impl=multiAppConn
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=query impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=mempool impl=localClient
I[06-08|11:51:56.952] Starting localClient module=abci-client connection=consensus impl=localClient
I[06-08|11:51:56.952] ABCI Handshake module=consensus appHeight=0 appHash=
I[06-08|11:51:56.952] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0
I[06-08|11:51:57.053] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=0 appHash=
I[06-08|11:51:57.053] This node is a validator module=consensus addr=6816B5D9BAC32A3CDF07884D9D3D2650694C371D pubKey=PubKeyEd25519{27A40CD032DD2467342D0CF27C5EC92052D966FEC714B6CF2F3BF3146AFD0D51}
I[06-08|11:51:57.234] Starting Node module=main impl=Node
I[06-08|11:51:57.234] Starting EventBus module=events impl=EventBus
I[06-08|11:51:57.234] Local listener module=p2p ip=:: port=46656
I[06-08|11:51:57.234] Getting UPNP external address module=p2p
I[06-08|11:51:58.867] Got UPNP external address module=p2p address=
I[06-08|11:51:58.867] Starting DefaultListener module=p2p impl=Listener(@<nil>:46656)
I[06-08|11:51:58.867] P2P Node ID module=main ID=3629b516392e494ae717ac4c6a1ea7eb0fe421c3 file=/home/tpb/.tendermint/config/node_key.json
I[06-08|11:51:58.868] Add our address to book module=p2p book=/home/tpb/.tendermint/config/addrbook.json addr=null
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x89fb86]
goroutine 1 [running]:
github.com/tendermint/tendermint/p2p.(*NetAddress).String(0x0, 0xc96e24, 0x17)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/netaddress.go:171 +0x26
github.com/tendermint/tendermint/p2p/pex.(*addrBook).AddOurAddress(0xc420190620, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/p2p/pex/addrbook.go:160 +0x116
github.com/tendermint/tendermint/node.(*Node).OnStart(0xc420286d00, 0xc4201b8010, 0xd)
/home/tpb/code/go/src/github.com/tendermint/tendermint/node/node.go:402 +0x547
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start(0xc420286d00, 0xe51c40, 0xc42000bd40)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x3bd
github.com/tendermint/tendermint/cmd/tendermint/commands.NewRunNodeCmd.func1(0xc42022e000, 0xc4200acdc0, 0x0, 0x1, 0x0, 0x0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/commands/run_node.go:58 +0xfe
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).execute(0xc42022e000, 0xc4200acda0, 0x1, 0x1, 0xc42022e000, 0xc4200acda0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:762 +0x468
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0x1289280, 0xbbdda0, 0xc420015e01, 0xc4201bc640)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:852 +0x30a
github.com/tendermint/tendermint/vendor/github.com/spf13/cobra.(*Command).Execute(0x1289280, 0xc4201bc640, 0xc420015e98)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/spf13/cobra/command.go:800 +0x2b
github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli.Executor.Execute(0x1289280, 0xde5798, 0x2, 0xc4200332c0)
/home/tpb/code/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/cli/setup.go:89 +0x4e
main.main()
/home/tpb/code/go/src/github.com/tendermint/tendermint/cmd/tendermint/main.go:45 +0x24d
```
2018-06-09 15:03:38 +04:00
|
|
|
if addr == nil {
|
|
|
|
err = fmt.Errorf("Failed to parse IP: %v", info.externalIpAddress)
|
|
|
|
}
|
2015-10-25 18:21:51 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *upnpNAT) AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error) {
|
|
|
|
// A single concatenation would break ARM compilation.
|
|
|
|
message := "<u:AddPortMapping xmlns:u=\"urn:" + n.urnDomain + ":service:WANIPConnection:1\">\r\n" +
|
|
|
|
"<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort)
|
|
|
|
message += "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>"
|
|
|
|
message += "<NewInternalPort>" + strconv.Itoa(internalPort) + "</NewInternalPort>" +
|
|
|
|
"<NewInternalClient>" + n.ourIP + "</NewInternalClient>" +
|
|
|
|
"<NewEnabled>1</NewEnabled><NewPortMappingDescription>"
|
|
|
|
message += description +
|
|
|
|
"</NewPortMappingDescription><NewLeaseDuration>" + strconv.Itoa(timeout) +
|
|
|
|
"</NewLeaseDuration></u:AddPortMapping>"
|
|
|
|
|
|
|
|
var response *http.Response
|
|
|
|
response, err = soapRequest(n.serviceURL, "AddPortMapping", message, n.urnDomain)
|
|
|
|
if response != nil {
|
2017-10-03 18:49:20 -04:00
|
|
|
defer response.Body.Close() // nolint: errcheck
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check response to see if the port was forwarded
|
|
|
|
// log.Println(message, response)
|
|
|
|
// JAE:
|
|
|
|
// body, err := ioutil.ReadAll(response.Body)
|
|
|
|
// fmt.Println(string(body), err)
|
|
|
|
mappedExternalPort = externalPort
|
|
|
|
_ = response
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
|
|
|
|
|
|
|
|
message := "<u:DeletePortMapping xmlns:u=\"urn:" + n.urnDomain + ":service:WANIPConnection:1\">\r\n" +
|
|
|
|
"<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort) +
|
|
|
|
"</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>" +
|
|
|
|
"</u:DeletePortMapping>"
|
|
|
|
|
|
|
|
var response *http.Response
|
|
|
|
response, err = soapRequest(n.serviceURL, "DeletePortMapping", message, n.urnDomain)
|
|
|
|
if response != nil {
|
2017-10-03 18:49:20 -04:00
|
|
|
defer response.Body.Close() // nolint: errcheck
|
2015-10-25 18:21:51 -07:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check response to see if the port was deleted
|
|
|
|
// log.Println(message, response)
|
|
|
|
_ = response
|
|
|
|
return
|
|
|
|
}
|