fix handleWhoareyou

This commit is contained in:
thinkAfCod 2025-04-02 23:36:11 +08:00
parent 9118e46bb8
commit 6952d7b878

View file

@ -522,14 +522,14 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s
func (t *UDPv5) callToNode(n *enode.Node, responseType byte, req v5wire.Packet) *callV5 { func (t *UDPv5) callToNode(n *enode.Node, responseType byte, req v5wire.Packet) *callV5 {
addr, _ := n.UDPEndpoint() addr, _ := n.UDPEndpoint()
c := &callV5{id: n.ID(), addr: addr, node: n} c := &callV5{id: n.ID(), addr: addr, node: n}
t.initCall(c, responseType, req) t.initCallAndDelivery(c, responseType, req)
return c return c
} }
// callToID is like callToNode, but for cases where the node record is not available. // callToID is like callToNode, but for cases where the node record is not available.
func (t *UDPv5) callToID(id enode.ID, addr netip.AddrPort, responseType byte, req v5wire.Packet) *callV5 { func (t *UDPv5) callToID(id enode.ID, addr netip.AddrPort, responseType byte, req v5wire.Packet) *callV5 {
c := &callV5{id: id, addr: addr} c := &callV5{id: id, addr: addr}
t.initCall(c, responseType, req) t.initCallAndDelivery(c, responseType, req)
return c return c
} }
@ -542,6 +542,10 @@ func (t *UDPv5) initCall(c *callV5, responseType byte, packet v5wire.Packet) {
// Assign request ID. // Assign request ID.
crand.Read(c.reqid) crand.Read(c.reqid)
packet.SetRequestID(c.reqid) packet.SetRequestID(c.reqid)
}
func (t *UDPv5) initCallAndDelivery(c *callV5, responseType byte, packet v5wire.Packet) {
t.initCall(c, responseType, packet)
// Send call to dispatch. // Send call to dispatch.
select { select {
case t.callCh <- c: case t.callCh <- c:
@ -592,8 +596,7 @@ func (t *UDPv5) dispatch() {
t.callQueue[c.id] = append(t.callQueue[c.id], c) t.callQueue[c.id] = append(t.callQueue[c.id], c)
t.sendNextCall(c.id) t.sendNextCall(c.id)
case cnr := <-t.sendNoRespCh: case cnr := <-t.sendNoRespCh:
// send a TalkReq call but not waiting for TalkResp // send a TalkReq call but not waiting for response
// may more used by portal network
t.sendCallNotWaitResp(cnr) t.sendCallNotWaitResp(cnr)
case ct := <-t.respTimeoutCh: case ct := <-t.respTimeoutCh:
@ -662,20 +665,19 @@ func (t *UDPv5) startResponseTimeout(c *callV5) {
close(done) close(done)
} }
// sendCallNotWaitResp send a talk request contains utp packet by call, call will not insert into queue // sendCallNotWaitResp send a talk request contains utp packet by call, call will not insert into queue.
// And during handshaking with the target node, new packets may be lost.
func (t *UDPv5) sendCallNotWaitResp(r *sendNoRespRequest) { func (t *UDPv5) sendCallNotWaitResp(r *sendNoRespRequest) {
// send out a TalkRequest that is a UTP packet for portal network // send out a TalkRequest that is a UTP packet for portal network
// todo If the destination node has been handshaked, it may not be necessary to use call id, addr := r.destNode.ID(), r.destAddr.String()
// request should be cached to handle WHOAREYOU if n := t.codec.SessionNode(id, addr); n != nil {
c := &callV5{id: r.destNode.ID(), addr: r.destAddr} // already handshake success
c.node = r.destNode t.send(id, r.destAddr, r.msg, nil)
c.packet = r.msg return
c.reqid = make([]byte, 8) }
c.ch = make(chan v5wire.Packet, 1)
c.err = make(chan error, 1) c := &callV5{id: id, addr: r.destAddr, node: r.destNode}
// Assign request ID. t.initCall(c, v5wire.TalkResponseMsg, r.msg)
crand.Read(c.reqid)
c.packet.SetRequestID(c.reqid)
nonce, _ := t.send(c.id, c.addr, c.packet, nil) nonce, _ := t.send(c.id, c.addr, c.packet, nil)
c.nonce = nonce c.nonce = nonce
@ -689,7 +691,7 @@ func (t *UDPv5) sendNoRespData(c *callV5) {
// Just resend the data and not use call again // Just resend the data and not use call again
delete(t.noRespCallByAuth, c.nonce) delete(t.noRespCallByAuth, c.nonce)
c.timeout.Stop() c.timeout.Stop()
t.send(c.node.ID(), c.addr, c.packet, nil) t.send(c.node.ID(), c.addr, c.packet, c.challenge)
} }
// sendNextCall sends the next call in the call queue if there is no active call. // sendNextCall sends the next call in the call queue if there is no active call.
@ -935,10 +937,10 @@ func (t *UDPv5) handleWhoareyou(p *v5wire.Whoareyou, fromID enode.ID, fromAddr n
} }
t.log.Trace("<< "+p.Name(), "id", c.node.ID(), "addr", fromAddr) t.log.Trace("<< "+p.Name(), "id", c.node.ID(), "addr", fromAddr)
if _, ok := t.noRespCallByAuth[p.Nonce]; !ok {
// Resend the call that was answered by WHOAREYOU.
c.handshakeCount++ c.handshakeCount++
c.challenge = p c.challenge = p
if _, ok := t.noRespCallByAuth[p.Nonce]; !ok {
// Resend the call that was answered by WHOAREYOU.
p.Node = c.node p.Node = c.node
t.sendCall(c) t.sendCall(c)
} else { } else {