aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/discover/udp.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-02-13 22:04:30 +0800
committerFelix Lange <fjl@twurst.com>2015-02-13 22:06:47 +0800
commitcf754b9483a61075cf50eb4846eeecdc48ad37c0 (patch)
treed2299150b39ba54cc9b9331140cebd96920a22d6 /p2p/discover/udp.go
parent5cc1256fd679cbb8cb80502494b8c02befc757c8 (diff)
downloaddexon-cf754b9483a61075cf50eb4846eeecdc48ad37c0.tar.gz
dexon-cf754b9483a61075cf50eb4846eeecdc48ad37c0.tar.zst
dexon-cf754b9483a61075cf50eb4846eeecdc48ad37c0.zip
p2p/discover: fix race in ListenUDP
udp.Table was assigned after the readLoop started, so packets could arrive and be processed before the Table was there.
Diffstat (limited to 'p2p/discover/udp.go')
-rw-r--r--p2p/discover/udp.go41
1 files changed, 17 insertions, 24 deletions
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index a9ed7fcb8..b2a895442 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -124,35 +124,14 @@ type reply struct {
// ListenUDP returns a new table that listens for UDP packets on laddr.
func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface) (*Table, error) {
- t, realaddr, err := listen(priv, laddr, natm)
- if err != nil {
- return nil, err
- }
- if natm != nil {
- if !realaddr.IP.IsLoopback() {
- go nat.Map(natm, t.closing, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
- }
- // TODO: react to external IP changes over time.
- if ext, err := natm.ExternalIP(); err == nil {
- realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
- }
- }
- t.Table = newTable(t, PubkeyID(&priv.PublicKey), realaddr)
- log.Infoln("Listening, ", t.self)
- return t.Table, nil
-}
-
-func listen(priv *ecdsa.PrivateKey, laddr string, nat nat.Interface) (*udp, *net.UDPAddr, error) {
addr, err := net.ResolveUDPAddr("udp", laddr)
if err != nil {
- return nil, nil, err
+ return nil, err
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
- return nil, nil, err
+ return nil, err
}
- realaddr := conn.LocalAddr().(*net.UDPAddr)
-
udp := &udp{
conn: conn,
priv: priv,
@@ -160,9 +139,23 @@ func listen(priv *ecdsa.PrivateKey, laddr string, nat nat.Interface) (*udp, *net
addpending: make(chan *pending),
replies: make(chan reply),
}
+
+ realaddr := conn.LocalAddr().(*net.UDPAddr)
+ if natm != nil {
+ if !realaddr.IP.IsLoopback() {
+ go nat.Map(natm, udp.closing, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
+ }
+ // TODO: react to external IP changes over time.
+ if ext, err := natm.ExternalIP(); err == nil {
+ realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
+ }
+ }
+ udp.Table = newTable(udp, PubkeyID(&priv.PublicKey), realaddr)
+
go udp.loop()
go udp.readLoop()
- return udp, realaddr, nil
+ log.Infoln("Listening, ", udp.self)
+ return udp.Table, nil
}
func (t *udp) close() {