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.
poc8
Felix Lange 10 years ago
parent 5cc1256fd6
commit cf754b9483
  1. 41
      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() {

Loading…
Cancel
Save