mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
p2p/nat: use rateLimiter instead of extra timeout
Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
parent
54d124ba46
commit
2a517dab64
1 changed files with 23 additions and 16 deletions
|
|
@ -35,7 +35,6 @@ import (
|
||||||
const (
|
const (
|
||||||
soapRequestTimeout = 3 * time.Second
|
soapRequestTimeout = 3 * time.Second
|
||||||
rateLimit = 200 * time.Millisecond
|
rateLimit = 200 * time.Millisecond
|
||||||
retryInterval = 1 * time.Second // time to wait between retries
|
|
||||||
retryCount = 3 // number of retries after a failed AddPortMapping
|
retryCount = 3 // number of retries after a failed AddPortMapping
|
||||||
randomCount = 3 // number of random ports to try
|
randomCount = 3 // number of random ports to try
|
||||||
)
|
)
|
||||||
|
|
@ -101,30 +100,26 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to add port mapping, preferring the specified external port.
|
// Try to add port mapping, preferring the specified external port.
|
||||||
err = n.withRateLimit(func() error {
|
return n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS)
|
||||||
p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS)
|
|
||||||
if err == nil {
|
|
||||||
extport = int(p)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
return uint16(extport), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addAnyPortMapping tries to add a port mapping with the specified external port.
|
// addAnyPortMapping tries to add a port mapping with the specified external port.
|
||||||
// If the external port is already in use, it will try to assign another port.
|
// If the external port is already in use, it will try to assign another port.
|
||||||
func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) {
|
func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) {
|
||||||
if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok {
|
if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok {
|
||||||
|
return n.portWithRateLimit(func() (uint16, error) {
|
||||||
return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// For IGDv1 and v1 services we should first try to add with extport.
|
// For IGDv1 and v1 services we should first try to add with extport.
|
||||||
for i := 0; i < retryCount+1; i++ {
|
for i := 0; i < retryCount+1; i++ {
|
||||||
err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
err := n.withRateLimit(func() error {
|
||||||
|
return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return uint16(extport), nil
|
return uint16(extport), nil
|
||||||
}
|
}
|
||||||
log.Trace("Failed to add port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err)
|
log.Trace("Failed to add port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err)
|
||||||
time.Sleep(retryInterval)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If above fails, we retry with a random port.
|
// If above fails, we retry with a random port.
|
||||||
|
|
@ -132,12 +127,13 @@ func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.I
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < randomCount; i++ {
|
for i := 0; i < randomCount; i++ {
|
||||||
extport = n.randomPort()
|
extport = n.randomPort()
|
||||||
err = n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
err := n.withRateLimit(func() error {
|
||||||
|
return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return uint16(extport), nil
|
return uint16(extport), nil
|
||||||
}
|
}
|
||||||
log.Trace("Failed to add random port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err)
|
log.Trace("Failed to add random port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err)
|
||||||
time.Sleep(retryInterval)
|
|
||||||
}
|
}
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +178,17 @@ func (n *upnp) String() string {
|
||||||
return "UPNP " + n.service
|
return "UPNP " + n.service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *upnp) portWithRateLimit(pfn func() (uint16, error)) (uint16, error) {
|
||||||
|
var port uint16
|
||||||
|
var err error
|
||||||
|
fn := func() error {
|
||||||
|
port, err = pfn()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
n.withRateLimit(fn)
|
||||||
|
return port, err
|
||||||
|
}
|
||||||
|
|
||||||
func (n *upnp) withRateLimit(fn func() error) error {
|
func (n *upnp) withRateLimit(fn func() error) error {
|
||||||
n.mu.Lock()
|
n.mu.Lock()
|
||||||
defer n.mu.Unlock()
|
defer n.mu.Unlock()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue