diff options
author | Felix Lange <fjl@twurst.com> | 2015-02-13 22:04:30 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-02-13 22:06:47 +0800 |
commit | cf754b9483a61075cf50eb4846eeecdc48ad37c0 (patch) | |
tree | d2299150b39ba54cc9b9331140cebd96920a22d6 /p2p/discover/udp.go | |
parent | 5cc1256fd679cbb8cb80502494b8c02befc757c8 (diff) | |
download | dexon-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.go | 41 |
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() { |