From 0e31316261e47922c0575bfdcb7fc7f8df730560 Mon Sep 17 00:00:00 2001 From: Steven Allen <steven@stebalien.com> Date: Thu, 16 Aug 2018 15:56:03 -0700 Subject: [PATCH] only map *usable* addresses Otherwise, we'll try to port-map localhost. --- nat.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/nat.go b/nat.go index d68aca0..0c47a4c 100644 --- a/nat.go +++ b/nat.go @@ -3,6 +3,7 @@ package nat import ( "errors" "fmt" + "net" "strconv" "strings" "sync" @@ -125,15 +126,40 @@ func (nat *NAT) NewMapping(maddr ma.Multiaddr) (Mapping, error) { return nil, fmt.Errorf("DialArgs failed on addr: %s", maddr.String()) } + var ip net.IP switch network { case "tcp", "tcp4", "tcp6": + addr, err := net.ResolveTCPAddr(network, addr) + if err != nil { + return nil, err + } + ip = addr.IP network = "tcp" case "udp", "udp4", "udp6": + addr, err := net.ResolveUDPAddr(network, addr) + if err != nil { + return nil, err + } + ip = addr.IP network = "udp" default: return nil, fmt.Errorf("transport not supported by NAT: %s", network) } + // XXX: Known limitation: doesn't handle multiple internal addresses. + // If this applies to you, you can figure it out yourself. Ideally, the + // NAT library would allow us to handle this case but the "go way" + // appears to be to just "shrug" at edge-cases. + if !ip.IsUnspecified() { + internalAddr, err := nat.nat.GetInternalAddress() + if err != nil { + return nil, fmt.Errorf("failed to discover address on nat: %s", err) + } + if !ip.Equal(internalAddr) { + return nil, fmt.Errorf("nat address is %s, refusing to map %s", internalAddr, ip) + } + } + intports := strings.Split(addr, ":")[1] intport, err := strconv.Atoi(intports) if err != nil { -- GitLab