github.com/zhiqiangxu/go-ethereum@v1.9.16-0.20210824055606-be91cfdebc48/p2p/discover/v5_udp.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package discover 18 19 import ( 20 "bytes" 21 "context" 22 "crypto/ecdsa" 23 crand "crypto/rand" 24 "errors" 25 "fmt" 26 "io" 27 "math" 28 "net" 29 "sync" 30 "time" 31 32 "github.com/zhiqiangxu/go-ethereum/common/mclock" 33 "github.com/zhiqiangxu/go-ethereum/log" 34 "github.com/zhiqiangxu/go-ethereum/p2p/enode" 35 "github.com/zhiqiangxu/go-ethereum/p2p/enr" 36 "github.com/zhiqiangxu/go-ethereum/p2p/netutil" 37 ) 38 39 const ( 40 lookupRequestLimit = 3 // max requests against a single node during lookup 41 findnodeResultLimit = 15 // applies in FINDNODE handler 42 totalNodesResponseLimit = 5 // applies in waitForNodes 43 nodesResponseItemLimit = 3 // applies in sendNodes 44 45 respTimeoutV5 = 700 * time.Millisecond 46 ) 47 48 // codecV5 is implemented by wireCodec (and testCodec). 49 // 50 // The UDPv5 transport is split into two objects: the codec object deals with 51 // encoding/decoding and with the handshake; the UDPv5 object handles higher-level concerns. 52 type codecV5 interface { 53 // encode encodes a packet. The 'challenge' parameter is non-nil for calls which got a 54 // WHOAREYOU response. 55 encode(fromID enode.ID, fromAddr string, p packetV5, challenge *whoareyouV5) (enc []byte, authTag []byte, err error) 56 57 // decode decodes a packet. It returns an *unknownV5 packet if decryption fails. 58 // The fromNode return value is non-nil when the input contains a handshake response. 59 decode(input []byte, fromAddr string) (fromID enode.ID, fromNode *enode.Node, p packetV5, err error) 60 } 61 62 // packetV5 is implemented by all discv5 packet type structs. 63 type packetV5 interface { 64 // These methods provide information and set the request ID. 65 name() string 66 kind() byte 67 setreqid([]byte) 68 // handle should perform the appropriate action to handle the packet, i.e. this is the 69 // place to send the response. 70 handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) 71 } 72 73 // UDPv5 is the implementation of protocol version 5. 74 type UDPv5 struct { 75 // static fields 76 conn UDPConn 77 tab *Table 78 netrestrict *netutil.Netlist 79 priv *ecdsa.PrivateKey 80 localNode *enode.LocalNode 81 db *enode.DB 82 log log.Logger 83 clock mclock.Clock 84 validSchemes enr.IdentityScheme 85 86 // channels into dispatch 87 packetInCh chan ReadPacket 88 readNextCh chan struct{} 89 callCh chan *callV5 90 callDoneCh chan *callV5 91 respTimeoutCh chan *callTimeout 92 93 // state of dispatch 94 codec codecV5 95 activeCallByNode map[enode.ID]*callV5 96 activeCallByAuth map[string]*callV5 97 callQueue map[enode.ID][]*callV5 98 99 // shutdown stuff 100 closeOnce sync.Once 101 closeCtx context.Context 102 cancelCloseCtx context.CancelFunc 103 wg sync.WaitGroup 104 } 105 106 // callV5 represents a remote procedure call against another node. 107 type callV5 struct { 108 node *enode.Node 109 packet packetV5 110 responseType byte // expected packet type of response 111 reqid []byte 112 ch chan packetV5 // responses sent here 113 err chan error // errors sent here 114 115 // Valid for active calls only: 116 authTag []byte // authTag of request packet 117 handshakeCount int // # times we attempted handshake for this call 118 challenge *whoareyouV5 // last sent handshake challenge 119 timeout mclock.Timer 120 } 121 122 // callTimeout is the response timeout event of a call. 123 type callTimeout struct { 124 c *callV5 125 timer mclock.Timer 126 } 127 128 // ListenV5 listens on the given connection. 129 func ListenV5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { 130 t, err := newUDPv5(conn, ln, cfg) 131 if err != nil { 132 return nil, err 133 } 134 go t.tab.loop() 135 t.wg.Add(2) 136 go t.readLoop() 137 go t.dispatch() 138 return t, nil 139 } 140 141 // newUDPv5 creates a UDPv5 transport, but doesn't start any goroutines. 142 func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { 143 closeCtx, cancelCloseCtx := context.WithCancel(context.Background()) 144 cfg = cfg.withDefaults() 145 t := &UDPv5{ 146 // static fields 147 conn: conn, 148 localNode: ln, 149 db: ln.Database(), 150 netrestrict: cfg.NetRestrict, 151 priv: cfg.PrivateKey, 152 log: cfg.Log, 153 validSchemes: cfg.ValidSchemes, 154 clock: cfg.Clock, 155 // channels into dispatch 156 packetInCh: make(chan ReadPacket, 1), 157 readNextCh: make(chan struct{}, 1), 158 callCh: make(chan *callV5), 159 callDoneCh: make(chan *callV5), 160 respTimeoutCh: make(chan *callTimeout), 161 // state of dispatch 162 codec: newWireCodec(ln, cfg.PrivateKey, cfg.Clock), 163 activeCallByNode: make(map[enode.ID]*callV5), 164 activeCallByAuth: make(map[string]*callV5), 165 callQueue: make(map[enode.ID][]*callV5), 166 // shutdown 167 closeCtx: closeCtx, 168 cancelCloseCtx: cancelCloseCtx, 169 } 170 tab, err := newTable(t, t.db, cfg.Bootnodes, cfg.Log) 171 if err != nil { 172 return nil, err 173 } 174 t.tab = tab 175 return t, nil 176 } 177 178 // Self returns the local node record. 179 func (t *UDPv5) Self() *enode.Node { 180 return t.localNode.Node() 181 } 182 183 // Close shuts down packet processing. 184 func (t *UDPv5) Close() { 185 t.closeOnce.Do(func() { 186 t.cancelCloseCtx() 187 t.conn.Close() 188 t.wg.Wait() 189 t.tab.close() 190 }) 191 } 192 193 // Ping sends a ping message to the given node. 194 func (t *UDPv5) Ping(n *enode.Node) error { 195 _, err := t.ping(n) 196 return err 197 } 198 199 // Resolve searches for a specific node with the given ID and tries to get the most recent 200 // version of the node record for it. It returns n if the node could not be resolved. 201 func (t *UDPv5) Resolve(n *enode.Node) *enode.Node { 202 if intable := t.tab.getNode(n.ID()); intable != nil && intable.Seq() > n.Seq() { 203 n = intable 204 } 205 // Try asking directly. This works if the node is still responding on the endpoint we have. 206 if resp, err := t.RequestENR(n); err == nil { 207 return resp 208 } 209 // Otherwise do a network lookup. 210 result := t.Lookup(n.ID()) 211 for _, rn := range result { 212 if rn.ID() == n.ID() && rn.Seq() > n.Seq() { 213 return rn 214 } 215 } 216 return n 217 } 218 219 // AllNodes returns all the nodes stored in the local table. 220 func (t *UDPv5) AllNodes() []*enode.Node { 221 t.tab.mutex.Lock() 222 defer t.tab.mutex.Unlock() 223 nodes := make([]*enode.Node, 0) 224 225 for _, b := range &t.tab.buckets { 226 for _, n := range b.entries { 227 nodes = append(nodes, unwrapNode(n)) 228 } 229 } 230 return nodes 231 } 232 233 // LocalNode returns the current local node running the 234 // protocol. 235 func (t *UDPv5) LocalNode() *enode.LocalNode { 236 return t.localNode 237 } 238 239 func (t *UDPv5) RandomNodes() enode.Iterator { 240 if t.tab.len() == 0 { 241 // All nodes were dropped, refresh. The very first query will hit this 242 // case and run the bootstrapping logic. 243 <-t.tab.refresh() 244 } 245 246 return newLookupIterator(t.closeCtx, t.newRandomLookup) 247 } 248 249 // Lookup performs a recursive lookup for the given target. 250 // It returns the closest nodes to target. 251 func (t *UDPv5) Lookup(target enode.ID) []*enode.Node { 252 return t.newLookup(t.closeCtx, target).run() 253 } 254 255 // lookupRandom looks up a random target. 256 // This is needed to satisfy the transport interface. 257 func (t *UDPv5) lookupRandom() []*enode.Node { 258 return t.newRandomLookup(t.closeCtx).run() 259 } 260 261 // lookupSelf looks up our own node ID. 262 // This is needed to satisfy the transport interface. 263 func (t *UDPv5) lookupSelf() []*enode.Node { 264 return t.newLookup(t.closeCtx, t.Self().ID()).run() 265 } 266 267 func (t *UDPv5) newRandomLookup(ctx context.Context) *lookup { 268 var target enode.ID 269 crand.Read(target[:]) 270 return t.newLookup(ctx, target) 271 } 272 273 func (t *UDPv5) newLookup(ctx context.Context, target enode.ID) *lookup { 274 return newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) { 275 return t.lookupWorker(n, target) 276 }) 277 } 278 279 // lookupWorker performs FINDNODE calls against a single node during lookup. 280 func (t *UDPv5) lookupWorker(destNode *node, target enode.ID) ([]*node, error) { 281 var ( 282 dists = lookupDistances(target, destNode.ID()) 283 nodes = nodesByDistance{target: target} 284 err error 285 ) 286 for i := 0; i < lookupRequestLimit && len(nodes.entries) < findnodeResultLimit; i++ { 287 var r []*enode.Node 288 r, err = t.findnode(unwrapNode(destNode), dists[i]) 289 if err == errClosed { 290 return nil, err 291 } 292 for _, n := range r { 293 if n.ID() != t.Self().ID() { 294 nodes.push(wrapNode(n), findnodeResultLimit) 295 } 296 } 297 } 298 return nodes.entries, err 299 } 300 301 // lookupDistances computes the distance parameter for FINDNODE calls to dest. 302 // It chooses distances adjacent to logdist(target, dest), e.g. for a target 303 // with logdist(target, dest) = 255 the result is [255, 256, 254]. 304 func lookupDistances(target, dest enode.ID) (dists []int) { 305 td := enode.LogDist(target, dest) 306 dists = append(dists, td) 307 for i := 1; len(dists) < lookupRequestLimit; i++ { 308 if td+i < 256 { 309 dists = append(dists, td+i) 310 } 311 if td-i > 0 { 312 dists = append(dists, td-i) 313 } 314 } 315 return dists 316 } 317 318 // ping calls PING on a node and waits for a PONG response. 319 func (t *UDPv5) ping(n *enode.Node) (uint64, error) { 320 resp := t.call(n, p_pongV5, &pingV5{ENRSeq: t.localNode.Node().Seq()}) 321 defer t.callDone(resp) 322 select { 323 case pong := <-resp.ch: 324 return pong.(*pongV5).ENRSeq, nil 325 case err := <-resp.err: 326 return 0, err 327 } 328 } 329 330 // requestENR requests n's record. 331 func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) { 332 nodes, err := t.findnode(n, 0) 333 if err != nil { 334 return nil, err 335 } 336 if len(nodes) != 1 { 337 return nil, fmt.Errorf("%d nodes in response for distance zero", len(nodes)) 338 } 339 return nodes[0], nil 340 } 341 342 // requestTicket calls REQUESTTICKET on a node and waits for a TICKET response. 343 func (t *UDPv5) requestTicket(n *enode.Node) ([]byte, error) { 344 resp := t.call(n, p_ticketV5, &pingV5{}) 345 defer t.callDone(resp) 346 select { 347 case response := <-resp.ch: 348 return response.(*ticketV5).Ticket, nil 349 case err := <-resp.err: 350 return nil, err 351 } 352 } 353 354 // findnode calls FINDNODE on a node and waits for responses. 355 func (t *UDPv5) findnode(n *enode.Node, distance int) ([]*enode.Node, error) { 356 resp := t.call(n, p_nodesV5, &findnodeV5{Distance: uint(distance)}) 357 return t.waitForNodes(resp, distance) 358 } 359 360 // waitForNodes waits for NODES responses to the given call. 361 func (t *UDPv5) waitForNodes(c *callV5, distance int) ([]*enode.Node, error) { 362 defer t.callDone(c) 363 364 var ( 365 nodes []*enode.Node 366 seen = make(map[enode.ID]struct{}) 367 received, total = 0, -1 368 ) 369 for { 370 select { 371 case responseP := <-c.ch: 372 response := responseP.(*nodesV5) 373 for _, record := range response.Nodes { 374 node, err := t.verifyResponseNode(c, record, distance, seen) 375 if err != nil { 376 t.log.Debug("Invalid record in "+response.name(), "id", c.node.ID(), "err", err) 377 continue 378 } 379 nodes = append(nodes, node) 380 } 381 if total == -1 { 382 total = min(int(response.Total), totalNodesResponseLimit) 383 } 384 if received++; received == total { 385 return nodes, nil 386 } 387 case err := <-c.err: 388 return nodes, err 389 } 390 } 391 } 392 393 // verifyResponseNode checks validity of a record in a NODES response. 394 func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distance int, seen map[enode.ID]struct{}) (*enode.Node, error) { 395 node, err := enode.New(t.validSchemes, r) 396 if err != nil { 397 return nil, err 398 } 399 if err := netutil.CheckRelayIP(c.node.IP(), node.IP()); err != nil { 400 return nil, err 401 } 402 if c.node.UDP() <= 1024 { 403 return nil, errLowPort 404 } 405 if distance != -1 { 406 if d := enode.LogDist(c.node.ID(), node.ID()); d != distance { 407 return nil, fmt.Errorf("wrong distance %d", d) 408 } 409 } 410 if _, ok := seen[node.ID()]; ok { 411 return nil, fmt.Errorf("duplicate record") 412 } 413 seen[node.ID()] = struct{}{} 414 return node, nil 415 } 416 417 // call sends the given call and sets up a handler for response packets (of type c.responseType). 418 // Responses are dispatched to the call's response channel. 419 func (t *UDPv5) call(node *enode.Node, responseType byte, packet packetV5) *callV5 { 420 c := &callV5{ 421 node: node, 422 packet: packet, 423 responseType: responseType, 424 reqid: make([]byte, 8), 425 ch: make(chan packetV5, 1), 426 err: make(chan error, 1), 427 } 428 // Assign request ID. 429 crand.Read(c.reqid) 430 packet.setreqid(c.reqid) 431 // Send call to dispatch. 432 select { 433 case t.callCh <- c: 434 case <-t.closeCtx.Done(): 435 c.err <- errClosed 436 } 437 return c 438 } 439 440 // callDone tells dispatch that the active call is done. 441 func (t *UDPv5) callDone(c *callV5) { 442 select { 443 case t.callDoneCh <- c: 444 case <-t.closeCtx.Done(): 445 } 446 } 447 448 // dispatch runs in its own goroutine, handles incoming packets and deals with calls. 449 // 450 // For any destination node there is at most one 'active call', stored in the t.activeCall* 451 // maps. A call is made active when it is sent. The active call can be answered by a 452 // matching response, in which case c.ch receives the response; or by timing out, in which case 453 // c.err receives the error. When the function that created the call signals the active 454 // call is done through callDone, the next call from the call queue is started. 455 // 456 // Calls may also be answered by a WHOAREYOU packet referencing the call packet's authTag. 457 // When that happens the call is simply re-sent to complete the handshake. We allow one 458 // handshake attempt per call. 459 func (t *UDPv5) dispatch() { 460 defer t.wg.Done() 461 462 // Arm first read. 463 t.readNextCh <- struct{}{} 464 465 for { 466 select { 467 case c := <-t.callCh: 468 id := c.node.ID() 469 t.callQueue[id] = append(t.callQueue[id], c) 470 t.sendNextCall(id) 471 472 case ct := <-t.respTimeoutCh: 473 active := t.activeCallByNode[ct.c.node.ID()] 474 if ct.c == active && ct.timer == active.timeout { 475 ct.c.err <- errTimeout 476 } 477 478 case c := <-t.callDoneCh: 479 id := c.node.ID() 480 active := t.activeCallByNode[id] 481 if active != c { 482 panic("BUG: callDone for inactive call") 483 } 484 c.timeout.Stop() 485 delete(t.activeCallByAuth, string(c.authTag)) 486 delete(t.activeCallByNode, id) 487 t.sendNextCall(id) 488 489 case p := <-t.packetInCh: 490 t.handlePacket(p.Data, p.Addr) 491 // Arm next read. 492 t.readNextCh <- struct{}{} 493 494 case <-t.closeCtx.Done(): 495 close(t.readNextCh) 496 for id, queue := range t.callQueue { 497 for _, c := range queue { 498 c.err <- errClosed 499 } 500 delete(t.callQueue, id) 501 } 502 for id, c := range t.activeCallByNode { 503 c.err <- errClosed 504 delete(t.activeCallByNode, id) 505 delete(t.activeCallByAuth, string(c.authTag)) 506 } 507 return 508 } 509 } 510 } 511 512 // startResponseTimeout sets the response timer for a call. 513 func (t *UDPv5) startResponseTimeout(c *callV5) { 514 if c.timeout != nil { 515 c.timeout.Stop() 516 } 517 var ( 518 timer mclock.Timer 519 done = make(chan struct{}) 520 ) 521 timer = t.clock.AfterFunc(respTimeoutV5, func() { 522 <-done 523 select { 524 case t.respTimeoutCh <- &callTimeout{c, timer}: 525 case <-t.closeCtx.Done(): 526 } 527 }) 528 c.timeout = timer 529 close(done) 530 } 531 532 // sendNextCall sends the next call in the call queue if there is no active call. 533 func (t *UDPv5) sendNextCall(id enode.ID) { 534 queue := t.callQueue[id] 535 if len(queue) == 0 || t.activeCallByNode[id] != nil { 536 return 537 } 538 t.activeCallByNode[id] = queue[0] 539 t.sendCall(t.activeCallByNode[id]) 540 if len(queue) == 1 { 541 delete(t.callQueue, id) 542 } else { 543 copy(queue, queue[1:]) 544 t.callQueue[id] = queue[:len(queue)-1] 545 } 546 } 547 548 // sendCall encodes and sends a request packet to the call's recipient node. 549 // This performs a handshake if needed. 550 func (t *UDPv5) sendCall(c *callV5) { 551 if len(c.authTag) > 0 { 552 // The call already has an authTag from a previous handshake attempt. Remove the 553 // entry for the authTag because we're about to generate a new authTag for this 554 // call. 555 delete(t.activeCallByAuth, string(c.authTag)) 556 } 557 558 addr := &net.UDPAddr{IP: c.node.IP(), Port: c.node.UDP()} 559 newTag, _ := t.send(c.node.ID(), addr, c.packet, c.challenge) 560 c.authTag = newTag 561 t.activeCallByAuth[string(c.authTag)] = c 562 t.startResponseTimeout(c) 563 } 564 565 // sendResponse sends a response packet to the given node. 566 // This doesn't trigger a handshake even if no keys are available. 567 func (t *UDPv5) sendResponse(toID enode.ID, toAddr *net.UDPAddr, packet packetV5) error { 568 _, err := t.send(toID, toAddr, packet, nil) 569 return err 570 } 571 572 // send sends a packet to the given node. 573 func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet packetV5, c *whoareyouV5) ([]byte, error) { 574 addr := toAddr.String() 575 enc, authTag, err := t.codec.encode(toID, addr, packet, c) 576 if err != nil { 577 t.log.Warn(">> "+packet.name(), "id", toID, "addr", addr, "err", err) 578 return authTag, err 579 } 580 _, err = t.conn.WriteToUDP(enc, toAddr) 581 t.log.Trace(">> "+packet.name(), "id", toID, "addr", addr) 582 return authTag, err 583 } 584 585 // readLoop runs in its own goroutine and reads packets from the network. 586 func (t *UDPv5) readLoop() { 587 defer t.wg.Done() 588 589 buf := make([]byte, maxPacketSize) 590 for range t.readNextCh { 591 nbytes, from, err := t.conn.ReadFromUDP(buf) 592 if netutil.IsTemporaryError(err) { 593 // Ignore temporary read errors. 594 t.log.Debug("Temporary UDP read error", "err", err) 595 continue 596 } else if err != nil { 597 // Shut down the loop for permament errors. 598 if err != io.EOF { 599 t.log.Debug("UDP read error", "err", err) 600 } 601 return 602 } 603 t.dispatchReadPacket(from, buf[:nbytes]) 604 } 605 } 606 607 // dispatchReadPacket sends a packet into the dispatch loop. 608 func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool { 609 select { 610 case t.packetInCh <- ReadPacket{content, from}: 611 return true 612 case <-t.closeCtx.Done(): 613 return false 614 } 615 } 616 617 // handlePacket decodes and processes an incoming packet from the network. 618 func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error { 619 addr := fromAddr.String() 620 fromID, fromNode, packet, err := t.codec.decode(rawpacket, addr) 621 if err != nil { 622 t.log.Debug("Bad discv5 packet", "id", fromID, "addr", addr, "err", err) 623 return err 624 } 625 if fromNode != nil { 626 // Handshake succeeded, add to table. 627 t.tab.addSeenNode(wrapNode(fromNode)) 628 } 629 if packet.kind() != p_whoareyouV5 { 630 // WHOAREYOU logged separately to report the sender ID. 631 t.log.Trace("<< "+packet.name(), "id", fromID, "addr", addr) 632 } 633 packet.handle(t, fromID, fromAddr) 634 return nil 635 } 636 637 // handleCallResponse dispatches a response packet to the call waiting for it. 638 func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr *net.UDPAddr, reqid []byte, p packetV5) { 639 ac := t.activeCallByNode[fromID] 640 if ac == nil || !bytes.Equal(reqid, ac.reqid) { 641 t.log.Debug(fmt.Sprintf("Unsolicited/late %s response", p.name()), "id", fromID, "addr", fromAddr) 642 return 643 } 644 if !fromAddr.IP.Equal(ac.node.IP()) || fromAddr.Port != ac.node.UDP() { 645 t.log.Debug(fmt.Sprintf("%s from wrong endpoint", p.name()), "id", fromID, "addr", fromAddr) 646 return 647 } 648 if p.kind() != ac.responseType { 649 t.log.Debug(fmt.Sprintf("Wrong disv5 response type %s", p.name()), "id", fromID, "addr", fromAddr) 650 return 651 } 652 t.startResponseTimeout(ac) 653 ac.ch <- p 654 } 655 656 // getNode looks for a node record in table and database. 657 func (t *UDPv5) getNode(id enode.ID) *enode.Node { 658 if n := t.tab.getNode(id); n != nil { 659 return n 660 } 661 if n := t.localNode.Database().Node(id); n != nil { 662 return n 663 } 664 return nil 665 } 666 667 // UNKNOWN 668 669 func (p *unknownV5) name() string { return "UNKNOWN/v5" } 670 func (p *unknownV5) kind() byte { return p_unknownV5 } 671 func (p *unknownV5) setreqid(id []byte) {} 672 673 func (p *unknownV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 674 challenge := &whoareyouV5{AuthTag: p.AuthTag} 675 crand.Read(challenge.IDNonce[:]) 676 if n := t.getNode(fromID); n != nil { 677 challenge.node = n 678 challenge.RecordSeq = n.Seq() 679 } 680 t.sendResponse(fromID, fromAddr, challenge) 681 } 682 683 // WHOAREYOU 684 685 func (p *whoareyouV5) name() string { return "WHOAREYOU/v5" } 686 func (p *whoareyouV5) kind() byte { return p_whoareyouV5 } 687 func (p *whoareyouV5) setreqid(id []byte) {} 688 689 func (p *whoareyouV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 690 c, err := p.matchWithCall(t, p.AuthTag) 691 if err != nil { 692 t.log.Debug("Invalid WHOAREYOU/v5", "addr", fromAddr, "err", err) 693 return 694 } 695 // Resend the call that was answered by WHOAREYOU. 696 t.log.Trace("<< "+p.name(), "id", c.node.ID(), "addr", fromAddr) 697 c.handshakeCount++ 698 c.challenge = p 699 p.node = c.node 700 t.sendCall(c) 701 } 702 703 var ( 704 errChallengeNoCall = errors.New("no matching call") 705 errChallengeTwice = errors.New("second handshake") 706 ) 707 708 // matchWithCall checks whether the handshake attempt matches the active call. 709 func (p *whoareyouV5) matchWithCall(t *UDPv5, authTag []byte) (*callV5, error) { 710 c := t.activeCallByAuth[string(authTag)] 711 if c == nil { 712 return nil, errChallengeNoCall 713 } 714 if c.handshakeCount > 0 { 715 return nil, errChallengeTwice 716 } 717 return c, nil 718 } 719 720 // PING 721 722 func (p *pingV5) name() string { return "PING/v5" } 723 func (p *pingV5) kind() byte { return p_pingV5 } 724 func (p *pingV5) setreqid(id []byte) { p.ReqID = id } 725 726 func (p *pingV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 727 t.sendResponse(fromID, fromAddr, &pongV5{ 728 ReqID: p.ReqID, 729 ToIP: fromAddr.IP, 730 ToPort: uint16(fromAddr.Port), 731 ENRSeq: t.localNode.Node().Seq(), 732 }) 733 } 734 735 // PONG 736 737 func (p *pongV5) name() string { return "PONG/v5" } 738 func (p *pongV5) kind() byte { return p_pongV5 } 739 func (p *pongV5) setreqid(id []byte) { p.ReqID = id } 740 741 func (p *pongV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 742 t.localNode.UDPEndpointStatement(fromAddr, &net.UDPAddr{IP: p.ToIP, Port: int(p.ToPort)}) 743 t.handleCallResponse(fromID, fromAddr, p.ReqID, p) 744 } 745 746 // FINDNODE 747 748 func (p *findnodeV5) name() string { return "FINDNODE/v5" } 749 func (p *findnodeV5) kind() byte { return p_findnodeV5 } 750 func (p *findnodeV5) setreqid(id []byte) { p.ReqID = id } 751 752 func (p *findnodeV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 753 if p.Distance == 0 { 754 t.sendNodes(fromID, fromAddr, p.ReqID, []*enode.Node{t.Self()}) 755 return 756 } 757 if p.Distance > 256 { 758 p.Distance = 256 759 } 760 // Get bucket entries. 761 t.tab.mutex.Lock() 762 nodes := unwrapNodes(t.tab.bucketAtDistance(int(p.Distance)).entries) 763 t.tab.mutex.Unlock() 764 if len(nodes) > findnodeResultLimit { 765 nodes = nodes[:findnodeResultLimit] 766 } 767 t.sendNodes(fromID, fromAddr, p.ReqID, nodes) 768 } 769 770 // sendNodes sends the given records in one or more NODES packets. 771 func (t *UDPv5) sendNodes(toID enode.ID, toAddr *net.UDPAddr, reqid []byte, nodes []*enode.Node) { 772 // TODO livenessChecks > 1 773 // TODO CheckRelayIP 774 total := uint8(math.Ceil(float64(len(nodes)) / 3)) 775 resp := &nodesV5{ReqID: reqid, Total: total, Nodes: make([]*enr.Record, 3)} 776 sent := false 777 for len(nodes) > 0 { 778 items := min(nodesResponseItemLimit, len(nodes)) 779 resp.Nodes = resp.Nodes[:items] 780 for i := 0; i < items; i++ { 781 resp.Nodes[i] = nodes[i].Record() 782 } 783 t.sendResponse(toID, toAddr, resp) 784 nodes = nodes[items:] 785 sent = true 786 } 787 // Ensure at least one response is sent. 788 if !sent { 789 resp.Total = 1 790 resp.Nodes = nil 791 t.sendResponse(toID, toAddr, resp) 792 } 793 } 794 795 // NODES 796 797 func (p *nodesV5) name() string { return "NODES/v5" } 798 func (p *nodesV5) kind() byte { return p_nodesV5 } 799 func (p *nodesV5) setreqid(id []byte) { p.ReqID = id } 800 801 func (p *nodesV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 802 t.handleCallResponse(fromID, fromAddr, p.ReqID, p) 803 } 804 805 // REQUESTTICKET 806 807 func (p *requestTicketV5) name() string { return "REQUESTTICKET/v5" } 808 func (p *requestTicketV5) kind() byte { return p_requestTicketV5 } 809 func (p *requestTicketV5) setreqid(id []byte) { p.ReqID = id } 810 811 func (p *requestTicketV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 812 t.sendResponse(fromID, fromAddr, &ticketV5{ReqID: p.ReqID}) 813 } 814 815 // TICKET 816 817 func (p *ticketV5) name() string { return "TICKET/v5" } 818 func (p *ticketV5) kind() byte { return p_ticketV5 } 819 func (p *ticketV5) setreqid(id []byte) { p.ReqID = id } 820 821 func (p *ticketV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 822 t.handleCallResponse(fromID, fromAddr, p.ReqID, p) 823 } 824 825 // REGTOPIC 826 827 func (p *regtopicV5) name() string { return "REGTOPIC/v5" } 828 func (p *regtopicV5) kind() byte { return p_regtopicV5 } 829 func (p *regtopicV5) setreqid(id []byte) { p.ReqID = id } 830 831 func (p *regtopicV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 832 t.sendResponse(fromID, fromAddr, ®confirmationV5{ReqID: p.ReqID, Registered: false}) 833 } 834 835 // REGCONFIRMATION 836 837 func (p *regconfirmationV5) name() string { return "REGCONFIRMATION/v5" } 838 func (p *regconfirmationV5) kind() byte { return p_regconfirmationV5 } 839 func (p *regconfirmationV5) setreqid(id []byte) { p.ReqID = id } 840 841 func (p *regconfirmationV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 842 t.handleCallResponse(fromID, fromAddr, p.ReqID, p) 843 } 844 845 // TOPICQUERY 846 847 func (p *topicqueryV5) name() string { return "TOPICQUERY/v5" } 848 func (p *topicqueryV5) kind() byte { return p_topicqueryV5 } 849 func (p *topicqueryV5) setreqid(id []byte) { p.ReqID = id } 850 851 func (p *topicqueryV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) { 852 }