forked from cerc-io/plugeth
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.
This commit is contained in:
parent
5cc1256fd6
commit
cf754b9483
@ -124,35 +124,14 @@ type reply struct {
|
|||||||
|
|
||||||
// ListenUDP returns a new table that listens for UDP packets on laddr.
|
// ListenUDP returns a new table that listens for UDP packets on laddr.
|
||||||
func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface) (*Table, error) {
|
func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface) (*Table, error) {
|
||||||
t, realaddr, err := listen(priv, laddr, natm)
|
addr, err := net.ResolveUDPAddr("udp", laddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
|
||||||
}
|
|
||||||
conn, err := net.ListenUDP("udp", addr)
|
conn, err := net.ListenUDP("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
realaddr := conn.LocalAddr().(*net.UDPAddr)
|
|
||||||
|
|
||||||
udp := &udp{
|
udp := &udp{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
priv: priv,
|
priv: priv,
|
||||||
@ -160,9 +139,23 @@ func listen(priv *ecdsa.PrivateKey, laddr string, nat nat.Interface) (*udp, *net
|
|||||||
addpending: make(chan *pending),
|
addpending: make(chan *pending),
|
||||||
replies: make(chan reply),
|
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.loop()
|
||||||
go udp.readLoop()
|
go udp.readLoop()
|
||||||
return udp, realaddr, nil
|
log.Infoln("Listening, ", udp.self)
|
||||||
|
return udp.Table, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *udp) close() {
|
func (t *udp) close() {
|
||||||
|
Loading…
Reference in New Issue
Block a user