aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/nat/nat.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-05-14 19:06:13 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-05-14 19:06:13 +0800
commit7fa740996cf01b56a734e579fcfcd9c2e8585ac5 (patch)
tree23a9fcf8248a12570e67155c21263f50df014f39 /p2p/nat/nat.go
parentc7a13c9be86417848582a2ab6704586f92dff27c (diff)
parent5f706cd7f5a97b3354b23de4273009f08586ff04 (diff)
downloaddexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar.gz
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar.bz2
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar.lz
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar.xz
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.tar.zst
dexon-7fa740996cf01b56a734e579fcfcd9c2e8585ac5.zip
Merge pull request #960 from fjl/nat-fixes
p2p/nat: fix UPnP auto discovery
Diffstat (limited to 'p2p/nat/nat.go')
-rw-r--r--p2p/nat/nat.go45
1 files changed, 21 insertions, 24 deletions
diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go
index fe00bdab0..9acb34398 100644
--- a/p2p/nat/nat.go
+++ b/p2p/nat/nat.go
@@ -86,13 +86,13 @@ func Map(m Interface, c chan struct{}, protocol string, extport, intport int, na
refresh := time.NewTimer(mapUpdateInterval)
defer func() {
refresh.Stop()
- glog.V(logger.Debug).Infof("Deleting port mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
+ glog.V(logger.Debug).Infof("deleting port mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
m.DeleteMapping(protocol, extport, intport)
}()
- glog.V(logger.Debug).Infof("add mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
if err := m.AddMapping(protocol, intport, extport, name, mapTimeout); err != nil {
- glog.V(logger.Warn).Infof("network port %d could not be mapped: %v\n", intport, err)
- glog.V(logger.Debug).Infof("mapping with %v returned %v\n", m, err)
+ glog.V(logger.Debug).Infof("network port %s:%d could not be mapped: %v\n", protocol, intport, err)
+ } else {
+ glog.V(logger.Info).Infof("mapped network port %s:%d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
}
for {
select {
@@ -101,10 +101,9 @@ func Map(m Interface, c chan struct{}, protocol string, extport, intport int, na
return
}
case <-refresh.C:
- glog.V(logger.Detail).Infof("refresh mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
+ glog.V(logger.Detail).Infof("refresh port mapping %s:%d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
if err := m.AddMapping(protocol, intport, extport, name, mapTimeout); err != nil {
- glog.V(logger.Warn).Infof("network port %d could not be mapped: %v\n", intport, err)
- glog.V(logger.Debug).Infof("mapping with %v returned %v\n", m, err)
+ glog.V(logger.Debug).Infof("network port %s:%d could not be mapped: %v\n", protocol, intport, err)
}
refresh.Reset(mapUpdateInterval)
}
@@ -172,8 +171,9 @@ func PMP(gateway net.IP) Interface {
// This type is useful because discovery can take a while but we
// want return an Interface value from UPnP, PMP and Auto immediately.
type autodisc struct {
- what string
- done <-chan Interface
+ what string // type of interface being autodiscovered
+ once sync.Once
+ doit func() Interface
mu sync.Mutex
found Interface
@@ -181,9 +181,10 @@ type autodisc struct {
func startautodisc(what string, doit func() Interface) Interface {
// TODO: monitor network configuration and rerun doit when it changes.
- done := make(chan Interface)
- ad := &autodisc{what: what, done: done}
- go func() { done <- doit(); close(done) }()
+ ad := &autodisc{what: what, doit: doit}
+ // Start the auto discovery as early as possible so it is already
+ // in progress when the rest of the stack calls the methods.
+ go ad.wait()
return ad
}
@@ -218,19 +219,15 @@ func (n *autodisc) String() string {
}
}
+// wait blocks until auto-discovery has been performed.
func (n *autodisc) wait() error {
- n.mu.Lock()
- found := n.found
- n.mu.Unlock()
- if found != nil {
- // already discovered
- return nil
- }
- if found = <-n.done; found == nil {
- return errors.New("no UPnP or NAT-PMP router discovered")
+ n.once.Do(func() {
+ n.mu.Lock()
+ n.found = n.doit()
+ n.mu.Unlock()
+ })
+ if n.found == nil {
+ return fmt.Errorf("no %s router discovered", n.what)
}
- n.mu.Lock()
- n.found = found
- n.mu.Unlock()
return nil
}