mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
p2p/nat: retry UPnP several times before resetting port to 0
Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
parent
fe9056f29f
commit
78930c11fb
1 changed files with 15 additions and 4 deletions
|
|
@ -31,12 +31,14 @@ const (
|
||||||
portMapRefreshInterval = 8 * time.Minute
|
portMapRefreshInterval = 8 * time.Minute
|
||||||
portMapRetryInterval = 5 * time.Minute
|
portMapRetryInterval = 5 * time.Minute
|
||||||
extipRetryInterval = 2 * time.Minute
|
extipRetryInterval = 2 * time.Minute
|
||||||
|
maxRetries = 5 // max number of failed attempts to refresh the mapping
|
||||||
)
|
)
|
||||||
|
|
||||||
type portMapping struct {
|
type portMapping struct {
|
||||||
protocol string
|
protocol string
|
||||||
name string
|
name string
|
||||||
port int
|
port int
|
||||||
|
retries int // number of failed attempts to refresh the mapping
|
||||||
|
|
||||||
// for use by the portMappingLoop goroutine:
|
// for use by the portMappingLoop goroutine:
|
||||||
extPort int // the mapped port returned by the NAT interface
|
extPort int // the mapped port returned by the NAT interface
|
||||||
|
|
@ -158,17 +160,26 @@ func (srv *Server) portMappingLoop() {
|
||||||
if m.extPort == 0 {
|
if m.extPort == 0 {
|
||||||
log.Debug("Couldn't add port mapping", "err", err)
|
log.Debug("Couldn't add port mapping", "err", err)
|
||||||
} else {
|
} else {
|
||||||
// Since UPnP implementation are often buggy,
|
// Failed refresh. Since UPnP implementation are often buggy, and lifetime is
|
||||||
// and lifetime is larger than the retry interval, this does not mean we lost our
|
// larger than the retry interval, this does not mean we lost our existing
|
||||||
// existing mapping. We do not reset the external port, as it is still our best chance,
|
// mapping. We do not reset the external port, as it is still our best chance,
|
||||||
// but we do retry soon.
|
// but we do retry soon.
|
||||||
// TODO: we could check the error code, but again, UPnP implementations are buggy.
|
// TODO: we could check the error code, but again, UPnP implementations are buggy.
|
||||||
log.Debug("Couldn't refresh port mapping", "err", err)
|
log.Debug("Couldn't refresh port mapping", "err", err)
|
||||||
|
m.retries++
|
||||||
|
if m.retries > maxRetries {
|
||||||
|
m.retries = 0
|
||||||
|
err := srv.NAT.DeleteMapping(m.protocol, m.extPort, m.port)
|
||||||
|
log.Debug("Couldn't refresh port mapping, trying to delete it:", "err", err)
|
||||||
|
m.extPort = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m.nextTime = srv.clock.Now().Add(portMapRetryInterval)
|
m.nextTime = srv.clock.Now().Add(portMapRetryInterval)
|
||||||
continue
|
continue //TODO: this means we never reset the ENR. Is that what we want?
|
||||||
}
|
}
|
||||||
|
|
||||||
// It was mapped!
|
// It was mapped!
|
||||||
|
m.retries = 0
|
||||||
log = newLogger(m.protocol, int(p), m.port)
|
log = newLogger(m.protocol, int(p), m.port)
|
||||||
if int(p) != m.extPort {
|
if int(p) != m.extPort {
|
||||||
m.extPort = int(p)
|
m.extPort = int(p)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue