Unverified Commit a3bf1687 authored by Jakub Sztandera's avatar Jakub Sztandera
Browse files

Retry NAT punching without duration on mapping failure

Some hardware doesn't support UPnP with durations.
parent 632eeab6
...@@ -159,6 +159,7 @@ type mapping struct { ...@@ -159,6 +159,7 @@ type mapping struct {
proto string proto string
intport int intport int
extport int extport int
permanent bool
intaddr ma.Multiaddr intaddr ma.Multiaddr
proc goprocess.Process proc goprocess.Process
...@@ -197,6 +198,18 @@ func (m *mapping) setExternalPort(p int) { ...@@ -197,6 +198,18 @@ func (m *mapping) setExternalPort(p int) {
m.extport = p m.extport = p
} }
func (m *mapping) setPermanent(p bool) {
m.Lock()
defer m.Unlock()
m.permanent = p
}
func (m *mapping) isPermanent() bool {
m.Lock()
defer m.Unlock()
return m.permanent
}
func (m *mapping) InternalAddr() ma.Multiaddr { func (m *mapping) InternalAddr() ma.Multiaddr {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
...@@ -333,13 +346,26 @@ func (nat *NAT) NewMapping(maddr ma.Multiaddr) (Mapping, error) { ...@@ -333,13 +346,26 @@ func (nat *NAT) NewMapping(maddr ma.Multiaddr) (Mapping, error) {
func (nat *NAT) establishMapping(m *mapping) { func (nat *NAT) establishMapping(m *mapping) {
oldport := m.ExternalPort() oldport := m.ExternalPort()
if oldport != 0 && m.isPermanent() {
// mapping was already established and it is permanent
return
}
log.Debugf("Attempting port map: %s/%d", m.Protocol(), m.InternalPort()) log.Debugf("Attempting port map: %s/%d", m.Protocol(), m.InternalPort())
newport, err := nat.nat.AddPortMapping(m.Protocol(), m.InternalPort(), "http", MappingDuration) permanent := false
newport, err := nat.nat.AddPortMapping(m.Protocol(), m.InternalPort(), "libp2p", MappingDuration)
if err != nil {
// Some hardware does not support mappings with timeout, so try that
newport, err = nat.nat.AddPortMapping(m.Protocol(), m.InternalPort(), "libp2p", 0)
permanent = (err == nil)
}
failure := func() { failure := func() {
m.setExternalPort(0) // clear mapping m.setExternalPort(0) // clear mapping
// TODO: log.Event // TODO: log.Event
log.Debugf("failed to establish port mapping: %s", err) log.Warningf("failed to establish port mapping: %s", err)
nat.Notifier.notifyAll(func(n Notifiee) { nat.Notifier.notifyAll(func(n Notifiee) {
n.MappingFailed(nat, m, oldport, err) n.MappingFailed(nat, m, oldport, err)
}) })
...@@ -353,6 +379,7 @@ func (nat *NAT) establishMapping(m *mapping) { ...@@ -353,6 +379,7 @@ func (nat *NAT) establishMapping(m *mapping) {
return return
} }
m.setPermanent(permanent)
m.setExternalPort(newport) m.setExternalPort(newport)
ext, err := m.ExternalAddr() ext, err := m.ExternalAddr()
if err != nil { if err != nil {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment