github.com/HugePages/go-ethereum@v1.9.7/p2p/discover/v4_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 "container/list" 22 "context" 23 "crypto/ecdsa" 24 crand "crypto/rand" 25 "errors" 26 "fmt" 27 "io" 28 "net" 29 "sync" 30 "time" 31 32 "github.com/ethereum/go-ethereum/crypto" 33 "github.com/ethereum/go-ethereum/log" 34 "github.com/ethereum/go-ethereum/p2p/enode" 35 "github.com/ethereum/go-ethereum/p2p/enr" 36 "github.com/ethereum/go-ethereum/p2p/netutil" 37 "github.com/ethereum/go-ethereum/rlp" 38 ) 39 40 // Errors 41 var ( 42 errPacketTooSmall = errors.New("too small") 43 errBadHash = errors.New("bad hash") 44 errExpired = errors.New("expired") 45 errUnsolicitedReply = errors.New("unsolicited reply") 46 errUnknownNode = errors.New("unknown node") 47 errTimeout = errors.New("RPC timeout") 48 errClockWarp = errors.New("reply deadline too far in the future") 49 errClosed = errors.New("socket closed") 50 ) 51 52 const ( 53 respTimeout = 500 * time.Millisecond 54 expiration = 20 * time.Second 55 bondExpiration = 24 * time.Hour 56 57 maxFindnodeFailures = 5 // nodes exceeding this limit are dropped 58 ntpFailureThreshold = 32 // Continuous timeouts after which to check NTP 59 ntpWarningCooldown = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning 60 driftThreshold = 10 * time.Second // Allowed clock drift before warning user 61 62 // Discovery packets are defined to be no larger than 1280 bytes. 63 // Packets larger than this size will be cut at the end and treated 64 // as invalid because their hash won't match. 65 maxPacketSize = 1280 66 ) 67 68 // RPC packet types 69 const ( 70 p_pingV4 = iota + 1 // zero is 'reserved' 71 p_pongV4 72 p_findnodeV4 73 p_neighborsV4 74 p_enrRequestV4 75 p_enrResponseV4 76 ) 77 78 // RPC request structures 79 type ( 80 pingV4 struct { 81 senderKey *ecdsa.PublicKey // filled in by preverify 82 83 Version uint 84 From, To rpcEndpoint 85 Expiration uint64 86 // Ignore additional fields (for forward compatibility). 87 Rest []rlp.RawValue `rlp:"tail"` 88 } 89 90 // pongV4 is the reply to pingV4. 91 pongV4 struct { 92 // This field should mirror the UDP envelope address 93 // of the ping packet, which provides a way to discover the 94 // the external address (after NAT). 95 To rpcEndpoint 96 97 ReplyTok []byte // This contains the hash of the ping packet. 98 Expiration uint64 // Absolute timestamp at which the packet becomes invalid. 99 // Ignore additional fields (for forward compatibility). 100 Rest []rlp.RawValue `rlp:"tail"` 101 } 102 103 // findnodeV4 is a query for nodes close to the given target. 104 findnodeV4 struct { 105 Target encPubkey 106 Expiration uint64 107 // Ignore additional fields (for forward compatibility). 108 Rest []rlp.RawValue `rlp:"tail"` 109 } 110 111 // neighborsV4 is the reply to findnodeV4. 112 neighborsV4 struct { 113 Nodes []rpcNode 114 Expiration uint64 115 // Ignore additional fields (for forward compatibility). 116 Rest []rlp.RawValue `rlp:"tail"` 117 } 118 119 // enrRequestV4 queries for the remote node's record. 120 enrRequestV4 struct { 121 Expiration uint64 122 // Ignore additional fields (for forward compatibility). 123 Rest []rlp.RawValue `rlp:"tail"` 124 } 125 126 // enrResponseV4 is the reply to enrRequestV4. 127 enrResponseV4 struct { 128 ReplyTok []byte // Hash of the enrRequest packet. 129 Record enr.Record 130 // Ignore additional fields (for forward compatibility). 131 Rest []rlp.RawValue `rlp:"tail"` 132 } 133 134 rpcNode struct { 135 IP net.IP // len 4 for IPv4 or 16 for IPv6 136 UDP uint16 // for discovery protocol 137 TCP uint16 // for RLPx protocol 138 ID encPubkey 139 } 140 141 rpcEndpoint struct { 142 IP net.IP // len 4 for IPv4 or 16 for IPv6 143 UDP uint16 // for discovery protocol 144 TCP uint16 // for RLPx protocol 145 } 146 ) 147 148 // packetV4 is implemented by all v4 protocol messages. 149 type packetV4 interface { 150 // preverify checks whether the packet is valid and should be handled at all. 151 preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error 152 // handle handles the packet. 153 handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) 154 // packet name and type for logging purposes. 155 name() string 156 kind() byte 157 } 158 159 func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint { 160 ip := net.IP{} 161 if ip4 := addr.IP.To4(); ip4 != nil { 162 ip = ip4 163 } else if ip6 := addr.IP.To16(); ip6 != nil { 164 ip = ip6 165 } 166 return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort} 167 } 168 169 func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) { 170 if rn.UDP <= 1024 { 171 return nil, errors.New("low port") 172 } 173 if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil { 174 return nil, err 175 } 176 if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) { 177 return nil, errors.New("not contained in netrestrict whitelist") 178 } 179 key, err := decodePubkey(rn.ID) 180 if err != nil { 181 return nil, err 182 } 183 n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP))) 184 err = n.ValidateComplete() 185 return n, err 186 } 187 188 func nodeToRPC(n *node) rpcNode { 189 var key ecdsa.PublicKey 190 var ekey encPubkey 191 if err := n.Load((*enode.Secp256k1)(&key)); err == nil { 192 ekey = encodePubkey(&key) 193 } 194 return rpcNode{ID: ekey, IP: n.IP(), UDP: uint16(n.UDP()), TCP: uint16(n.TCP())} 195 } 196 197 // UDPv4 implements the v4 wire protocol. 198 type UDPv4 struct { 199 conn UDPConn 200 log log.Logger 201 netrestrict *netutil.Netlist 202 priv *ecdsa.PrivateKey 203 localNode *enode.LocalNode 204 db *enode.DB 205 tab *Table 206 closeOnce sync.Once 207 wg sync.WaitGroup 208 209 addReplyMatcher chan *replyMatcher 210 gotreply chan reply 211 closeCtx context.Context 212 cancelCloseCtx func() 213 } 214 215 // replyMatcher represents a pending reply. 216 // 217 // Some implementations of the protocol wish to send more than one 218 // reply packet to findnode. In general, any neighbors packet cannot 219 // be matched up with a specific findnode packet. 220 // 221 // Our implementation handles this by storing a callback function for 222 // each pending reply. Incoming packets from a node are dispatched 223 // to all callback functions for that node. 224 type replyMatcher struct { 225 // these fields must match in the reply. 226 from enode.ID 227 ip net.IP 228 ptype byte 229 230 // time when the request must complete 231 deadline time.Time 232 233 // callback is called when a matching reply arrives. If it returns matched == true, the 234 // reply was acceptable. The second return value indicates whether the callback should 235 // be removed from the pending reply queue. If it returns false, the reply is considered 236 // incomplete and the callback will be invoked again for the next matching reply. 237 callback replyMatchFunc 238 239 // errc receives nil when the callback indicates completion or an 240 // error if no further reply is received within the timeout. 241 errc chan error 242 243 // reply contains the most recent reply. This field is safe for reading after errc has 244 // received a value. 245 reply packetV4 246 } 247 248 type replyMatchFunc func(interface{}) (matched bool, requestDone bool) 249 250 // reply is a reply packet from a certain node. 251 type reply struct { 252 from enode.ID 253 ip net.IP 254 data packetV4 255 // loop indicates whether there was 256 // a matching request by sending on this channel. 257 matched chan<- bool 258 } 259 260 func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { 261 closeCtx, cancel := context.WithCancel(context.Background()) 262 t := &UDPv4{ 263 conn: c, 264 priv: cfg.PrivateKey, 265 netrestrict: cfg.NetRestrict, 266 localNode: ln, 267 db: ln.Database(), 268 gotreply: make(chan reply), 269 addReplyMatcher: make(chan *replyMatcher), 270 closeCtx: closeCtx, 271 cancelCloseCtx: cancel, 272 log: cfg.Log, 273 } 274 if t.log == nil { 275 t.log = log.Root() 276 } 277 278 tab, err := newTable(t, ln.Database(), cfg.Bootnodes, t.log) 279 if err != nil { 280 return nil, err 281 } 282 t.tab = tab 283 go tab.loop() 284 285 t.wg.Add(2) 286 go t.loop() 287 go t.readLoop(cfg.Unhandled) 288 return t, nil 289 } 290 291 // Self returns the local node. 292 func (t *UDPv4) Self() *enode.Node { 293 return t.localNode.Node() 294 } 295 296 // Close shuts down the socket and aborts any running queries. 297 func (t *UDPv4) Close() { 298 t.closeOnce.Do(func() { 299 t.cancelCloseCtx() 300 t.conn.Close() 301 t.wg.Wait() 302 t.tab.close() 303 }) 304 } 305 306 // Resolve searches for a specific node with the given ID and tries to get the most recent 307 // version of the node record for it. It returns n if the node could not be resolved. 308 func (t *UDPv4) Resolve(n *enode.Node) *enode.Node { 309 // Try asking directly. This works if the node is still responding on the endpoint we have. 310 if rn, err := t.RequestENR(n); err == nil { 311 return rn 312 } 313 // Check table for the ID, we might have a newer version there. 314 if intable := t.tab.getNode(n.ID()); intable != nil && intable.Seq() > n.Seq() { 315 n = intable 316 if rn, err := t.RequestENR(n); err == nil { 317 return rn 318 } 319 } 320 // Otherwise perform a network lookup. 321 var key enode.Secp256k1 322 if n.Load(&key) != nil { 323 return n // no secp256k1 key 324 } 325 result := t.LookupPubkey((*ecdsa.PublicKey)(&key)) 326 for _, rn := range result { 327 if rn.ID() == n.ID() { 328 if rn, err := t.RequestENR(rn); err == nil { 329 return rn 330 } 331 } 332 } 333 return n 334 } 335 336 func (t *UDPv4) ourEndpoint() rpcEndpoint { 337 n := t.Self() 338 a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} 339 return makeEndpoint(a, uint16(n.TCP())) 340 } 341 342 // Ping sends a ping message to the given node. 343 func (t *UDPv4) Ping(n *enode.Node) error { 344 _, err := t.ping(n) 345 return err 346 } 347 348 // ping sends a ping message to the given node and waits for a reply. 349 func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) { 350 rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil) 351 if err = <-rm.errc; err == nil { 352 seq = seqFromTail(rm.reply.(*pongV4).Rest) 353 } 354 return seq, err 355 } 356 357 // sendPing sends a ping message to the given node and invokes the callback 358 // when the reply arrives. 359 func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher { 360 req := t.makePing(toaddr) 361 packet, hash, err := t.encode(t.priv, req) 362 if err != nil { 363 errc := make(chan error, 1) 364 errc <- err 365 return &replyMatcher{errc: errc} 366 } 367 // Add a matcher for the reply to the pending reply queue. Pongs are matched if they 368 // reference the ping we're about to send. 369 rm := t.pending(toid, toaddr.IP, p_pongV4, func(p interface{}) (matched bool, requestDone bool) { 370 matched = bytes.Equal(p.(*pongV4).ReplyTok, hash) 371 if matched && callback != nil { 372 callback() 373 } 374 return matched, matched 375 }) 376 // Send the packet. 377 t.localNode.UDPContact(toaddr) 378 t.write(toaddr, toid, req.name(), packet) 379 return rm 380 } 381 382 func (t *UDPv4) makePing(toaddr *net.UDPAddr) *pingV4 { 383 seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq()) 384 return &pingV4{ 385 Version: 4, 386 From: t.ourEndpoint(), 387 To: makeEndpoint(toaddr, 0), 388 Expiration: uint64(time.Now().Add(expiration).Unix()), 389 Rest: []rlp.RawValue{seq}, 390 } 391 } 392 393 // LookupPubkey finds the closest nodes to the given public key. 394 func (t *UDPv4) LookupPubkey(key *ecdsa.PublicKey) []*enode.Node { 395 if t.tab.len() == 0 { 396 // All nodes were dropped, refresh. The very first query will hit this 397 // case and run the bootstrapping logic. 398 <-t.tab.refresh() 399 } 400 return t.newLookup(t.closeCtx, encodePubkey(key)).run() 401 } 402 403 // RandomNodes is an iterator yielding nodes from a random walk of the DHT. 404 func (t *UDPv4) RandomNodes() enode.Iterator { 405 return newLookupIterator(t.closeCtx, t.newRandomLookup) 406 } 407 408 // lookupRandom implements transport. 409 func (t *UDPv4) lookupRandom() []*enode.Node { 410 return t.newRandomLookup(t.closeCtx).run() 411 } 412 413 // lookupSelf implements transport. 414 func (t *UDPv4) lookupSelf() []*enode.Node { 415 return t.newLookup(t.closeCtx, encodePubkey(&t.priv.PublicKey)).run() 416 } 417 418 func (t *UDPv4) newRandomLookup(ctx context.Context) *lookup { 419 var target encPubkey 420 crand.Read(target[:]) 421 return t.newLookup(ctx, target) 422 } 423 424 func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup { 425 target := enode.ID(crypto.Keccak256Hash(targetKey[:])) 426 it := newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) { 427 return t.findnode(n.ID(), n.addr(), targetKey) 428 }) 429 return it 430 } 431 432 // findnode sends a findnode request to the given node and waits until 433 // the node has sent up to k neighbors. 434 func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target encPubkey) ([]*node, error) { 435 t.ensureBond(toid, toaddr) 436 437 // Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is 438 // active until enough nodes have been received. 439 nodes := make([]*node, 0, bucketSize) 440 nreceived := 0 441 rm := t.pending(toid, toaddr.IP, p_neighborsV4, func(r interface{}) (matched bool, requestDone bool) { 442 reply := r.(*neighborsV4) 443 for _, rn := range reply.Nodes { 444 nreceived++ 445 n, err := t.nodeFromRPC(toaddr, rn) 446 if err != nil { 447 t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err) 448 continue 449 } 450 nodes = append(nodes, n) 451 } 452 return true, nreceived >= bucketSize 453 }) 454 t.send(toaddr, toid, &findnodeV4{ 455 Target: target, 456 Expiration: uint64(time.Now().Add(expiration).Unix()), 457 }) 458 return nodes, <-rm.errc 459 } 460 461 // RequestENR sends enrRequest to the given node and waits for a response. 462 func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { 463 addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} 464 t.ensureBond(n.ID(), addr) 465 466 req := &enrRequestV4{ 467 Expiration: uint64(time.Now().Add(expiration).Unix()), 468 } 469 packet, hash, err := t.encode(t.priv, req) 470 if err != nil { 471 return nil, err 472 } 473 // Add a matcher for the reply to the pending reply queue. Responses are matched if 474 // they reference the request we're about to send. 475 rm := t.pending(n.ID(), addr.IP, p_enrResponseV4, func(r interface{}) (matched bool, requestDone bool) { 476 matched = bytes.Equal(r.(*enrResponseV4).ReplyTok, hash) 477 return matched, matched 478 }) 479 // Send the packet and wait for the reply. 480 t.write(addr, n.ID(), req.name(), packet) 481 if err := <-rm.errc; err != nil { 482 return nil, err 483 } 484 // Verify the response record. 485 respN, err := enode.New(enode.ValidSchemes, &rm.reply.(*enrResponseV4).Record) 486 if err != nil { 487 return nil, err 488 } 489 if respN.ID() != n.ID() { 490 return nil, fmt.Errorf("invalid ID in response record") 491 } 492 if respN.Seq() < n.Seq() { 493 return n, nil // response record is older 494 } 495 if err := netutil.CheckRelayIP(addr.IP, respN.IP()); err != nil { 496 return nil, fmt.Errorf("invalid IP in response record: %v", err) 497 } 498 return respN, nil 499 } 500 501 // pending adds a reply matcher to the pending reply queue. 502 // see the documentation of type replyMatcher for a detailed explanation. 503 func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchFunc) *replyMatcher { 504 ch := make(chan error, 1) 505 p := &replyMatcher{from: id, ip: ip, ptype: ptype, callback: callback, errc: ch} 506 select { 507 case t.addReplyMatcher <- p: 508 // loop will handle it 509 case <-t.closeCtx.Done(): 510 ch <- errClosed 511 } 512 return p 513 } 514 515 // handleReply dispatches a reply packet, invoking reply matchers. It returns 516 // whether any matcher considered the packet acceptable. 517 func (t *UDPv4) handleReply(from enode.ID, fromIP net.IP, req packetV4) bool { 518 matched := make(chan bool, 1) 519 select { 520 case t.gotreply <- reply{from, fromIP, req, matched}: 521 // loop will handle it 522 return <-matched 523 case <-t.closeCtx.Done(): 524 return false 525 } 526 } 527 528 // loop runs in its own goroutine. it keeps track of 529 // the refresh timer and the pending reply queue. 530 func (t *UDPv4) loop() { 531 defer t.wg.Done() 532 533 var ( 534 plist = list.New() 535 timeout = time.NewTimer(0) 536 nextTimeout *replyMatcher // head of plist when timeout was last reset 537 contTimeouts = 0 // number of continuous timeouts to do NTP checks 538 ntpWarnTime = time.Unix(0, 0) 539 ) 540 <-timeout.C // ignore first timeout 541 defer timeout.Stop() 542 543 resetTimeout := func() { 544 if plist.Front() == nil || nextTimeout == plist.Front().Value { 545 return 546 } 547 // Start the timer so it fires when the next pending reply has expired. 548 now := time.Now() 549 for el := plist.Front(); el != nil; el = el.Next() { 550 nextTimeout = el.Value.(*replyMatcher) 551 if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout { 552 timeout.Reset(dist) 553 return 554 } 555 // Remove pending replies whose deadline is too far in the 556 // future. These can occur if the system clock jumped 557 // backwards after the deadline was assigned. 558 nextTimeout.errc <- errClockWarp 559 plist.Remove(el) 560 } 561 nextTimeout = nil 562 timeout.Stop() 563 } 564 565 for { 566 resetTimeout() 567 568 select { 569 case <-t.closeCtx.Done(): 570 for el := plist.Front(); el != nil; el = el.Next() { 571 el.Value.(*replyMatcher).errc <- errClosed 572 } 573 return 574 575 case p := <-t.addReplyMatcher: 576 p.deadline = time.Now().Add(respTimeout) 577 plist.PushBack(p) 578 579 case r := <-t.gotreply: 580 var matched bool // whether any replyMatcher considered the reply acceptable. 581 for el := plist.Front(); el != nil; el = el.Next() { 582 p := el.Value.(*replyMatcher) 583 if p.from == r.from && p.ptype == r.data.kind() && p.ip.Equal(r.ip) { 584 ok, requestDone := p.callback(r.data) 585 matched = matched || ok 586 // Remove the matcher if callback indicates that all replies have been received. 587 if requestDone { 588 p.reply = r.data 589 p.errc <- nil 590 plist.Remove(el) 591 } 592 // Reset the continuous timeout counter (time drift detection) 593 contTimeouts = 0 594 } 595 } 596 r.matched <- matched 597 598 case now := <-timeout.C: 599 nextTimeout = nil 600 601 // Notify and remove callbacks whose deadline is in the past. 602 for el := plist.Front(); el != nil; el = el.Next() { 603 p := el.Value.(*replyMatcher) 604 if now.After(p.deadline) || now.Equal(p.deadline) { 605 p.errc <- errTimeout 606 plist.Remove(el) 607 contTimeouts++ 608 } 609 } 610 // If we've accumulated too many timeouts, do an NTP time sync check 611 if contTimeouts > ntpFailureThreshold { 612 if time.Since(ntpWarnTime) >= ntpWarningCooldown { 613 ntpWarnTime = time.Now() 614 go checkClockDrift() 615 } 616 contTimeouts = 0 617 } 618 } 619 } 620 } 621 622 const ( 623 macSize = 256 / 8 624 sigSize = 520 / 8 625 headSize = macSize + sigSize // space of packet frame data 626 ) 627 628 var ( 629 headSpace = make([]byte, headSize) 630 631 // Neighbors replies are sent across multiple packets to 632 // stay below the packet size limit. We compute the maximum number 633 // of entries by stuffing a packet until it grows too large. 634 maxNeighbors int 635 ) 636 637 func init() { 638 p := neighborsV4{Expiration: ^uint64(0)} 639 maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)} 640 for n := 0; ; n++ { 641 p.Nodes = append(p.Nodes, maxSizeNode) 642 size, _, err := rlp.EncodeToReader(p) 643 if err != nil { 644 // If this ever happens, it will be caught by the unit tests. 645 panic("cannot encode: " + err.Error()) 646 } 647 if headSize+size+1 >= maxPacketSize { 648 maxNeighbors = n 649 break 650 } 651 } 652 } 653 654 func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req packetV4) ([]byte, error) { 655 packet, hash, err := t.encode(t.priv, req) 656 if err != nil { 657 return hash, err 658 } 659 return hash, t.write(toaddr, toid, req.name(), packet) 660 } 661 662 func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error { 663 _, err := t.conn.WriteToUDP(packet, toaddr) 664 t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err) 665 return err 666 } 667 668 func (t *UDPv4) encode(priv *ecdsa.PrivateKey, req packetV4) (packet, hash []byte, err error) { 669 name := req.name() 670 b := new(bytes.Buffer) 671 b.Write(headSpace) 672 b.WriteByte(req.kind()) 673 if err := rlp.Encode(b, req); err != nil { 674 t.log.Error(fmt.Sprintf("Can't encode %s packet", name), "err", err) 675 return nil, nil, err 676 } 677 packet = b.Bytes() 678 sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv) 679 if err != nil { 680 t.log.Error(fmt.Sprintf("Can't sign %s packet", name), "err", err) 681 return nil, nil, err 682 } 683 copy(packet[macSize:], sig) 684 // add the hash to the front. Note: this doesn't protect the 685 // packet in any way. Our public key will be part of this hash in 686 // The future. 687 hash = crypto.Keccak256(packet[macSize:]) 688 copy(packet, hash) 689 return packet, hash, nil 690 } 691 692 // readLoop runs in its own goroutine. it handles incoming UDP packets. 693 func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { 694 defer t.wg.Done() 695 if unhandled != nil { 696 defer close(unhandled) 697 } 698 699 buf := make([]byte, maxPacketSize) 700 for { 701 nbytes, from, err := t.conn.ReadFromUDP(buf) 702 if netutil.IsTemporaryError(err) { 703 // Ignore temporary read errors. 704 t.log.Debug("Temporary UDP read error", "err", err) 705 continue 706 } else if err != nil { 707 // Shut down the loop for permament errors. 708 if err != io.EOF { 709 t.log.Debug("UDP read error", "err", err) 710 } 711 return 712 } 713 if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil { 714 select { 715 case unhandled <- ReadPacket{buf[:nbytes], from}: 716 default: 717 } 718 } 719 } 720 } 721 722 func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error { 723 packet, fromKey, hash, err := decodeV4(buf) 724 if err != nil { 725 t.log.Debug("Bad discv4 packet", "addr", from, "err", err) 726 return err 727 } 728 fromID := fromKey.id() 729 if err == nil { 730 err = packet.preverify(t, from, fromID, fromKey) 731 } 732 t.log.Trace("<< "+packet.name(), "id", fromID, "addr", from, "err", err) 733 if err == nil { 734 packet.handle(t, from, fromID, hash) 735 } 736 return err 737 } 738 739 func decodeV4(buf []byte) (packetV4, encPubkey, []byte, error) { 740 if len(buf) < headSize+1 { 741 return nil, encPubkey{}, nil, errPacketTooSmall 742 } 743 hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:] 744 shouldhash := crypto.Keccak256(buf[macSize:]) 745 if !bytes.Equal(hash, shouldhash) { 746 return nil, encPubkey{}, nil, errBadHash 747 } 748 fromKey, err := recoverNodeKey(crypto.Keccak256(buf[headSize:]), sig) 749 if err != nil { 750 return nil, fromKey, hash, err 751 } 752 753 var req packetV4 754 switch ptype := sigdata[0]; ptype { 755 case p_pingV4: 756 req = new(pingV4) 757 case p_pongV4: 758 req = new(pongV4) 759 case p_findnodeV4: 760 req = new(findnodeV4) 761 case p_neighborsV4: 762 req = new(neighborsV4) 763 case p_enrRequestV4: 764 req = new(enrRequestV4) 765 case p_enrResponseV4: 766 req = new(enrResponseV4) 767 default: 768 return nil, fromKey, hash, fmt.Errorf("unknown type: %d", ptype) 769 } 770 s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0) 771 err = s.Decode(req) 772 return req, fromKey, hash, err 773 } 774 775 // checkBond checks if the given node has a recent enough endpoint proof. 776 func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool { 777 return time.Since(t.db.LastPongReceived(id, ip)) < bondExpiration 778 } 779 780 // ensureBond solicits a ping from a node if we haven't seen a ping from it for a while. 781 // This ensures there is a valid endpoint proof on the remote end. 782 func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) { 783 tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration 784 if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures { 785 rm := t.sendPing(toid, toaddr, nil) 786 <-rm.errc 787 // Wait for them to ping back and process our pong. 788 time.Sleep(respTimeout) 789 } 790 } 791 792 // expired checks whether the given UNIX time stamp is in the past. 793 func expired(ts uint64) bool { 794 return time.Unix(int64(ts), 0).Before(time.Now()) 795 } 796 797 func seqFromTail(tail []rlp.RawValue) uint64 { 798 if len(tail) == 0 { 799 return 0 800 } 801 var seq uint64 802 rlp.DecodeBytes(tail[0], &seq) 803 return seq 804 } 805 806 // PING/v4 807 808 func (req *pingV4) name() string { return "PING/v4" } 809 func (req *pingV4) kind() byte { return p_pingV4 } 810 811 func (req *pingV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 812 if expired(req.Expiration) { 813 return errExpired 814 } 815 key, err := decodePubkey(fromKey) 816 if err != nil { 817 return errors.New("invalid public key") 818 } 819 req.senderKey = key 820 return nil 821 } 822 823 func (req *pingV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 824 // Reply. 825 seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq()) 826 t.send(from, fromID, &pongV4{ 827 To: makeEndpoint(from, req.From.TCP), 828 ReplyTok: mac, 829 Expiration: uint64(time.Now().Add(expiration).Unix()), 830 Rest: []rlp.RawValue{seq}, 831 }) 832 833 // Ping back if our last pong on file is too far in the past. 834 n := wrapNode(enode.NewV4(req.senderKey, from.IP, int(req.From.TCP), from.Port)) 835 if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration { 836 t.sendPing(fromID, from, func() { 837 t.tab.addVerifiedNode(n) 838 }) 839 } else { 840 t.tab.addVerifiedNode(n) 841 } 842 843 // Update node database and endpoint predictor. 844 t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now()) 845 t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) 846 } 847 848 // PONG/v4 849 850 func (req *pongV4) name() string { return "PONG/v4" } 851 func (req *pongV4) kind() byte { return p_pongV4 } 852 853 func (req *pongV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 854 if expired(req.Expiration) { 855 return errExpired 856 } 857 if !t.handleReply(fromID, from.IP, req) { 858 return errUnsolicitedReply 859 } 860 return nil 861 } 862 863 func (req *pongV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 864 t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) 865 t.db.UpdateLastPongReceived(fromID, from.IP, time.Now()) 866 } 867 868 // FINDNODE/v4 869 870 func (req *findnodeV4) name() string { return "FINDNODE/v4" } 871 func (req *findnodeV4) kind() byte { return p_findnodeV4 } 872 873 func (req *findnodeV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 874 if expired(req.Expiration) { 875 return errExpired 876 } 877 if !t.checkBond(fromID, from.IP) { 878 // No endpoint proof pong exists, we don't process the packet. This prevents an 879 // attack vector where the discovery protocol could be used to amplify traffic in a 880 // DDOS attack. A malicious actor would send a findnode request with the IP address 881 // and UDP port of the target as the source address. The recipient of the findnode 882 // packet would then send a neighbors packet (which is a much bigger packet than 883 // findnode) to the victim. 884 return errUnknownNode 885 } 886 return nil 887 } 888 889 func (req *findnodeV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 890 // Determine closest nodes. 891 target := enode.ID(crypto.Keccak256Hash(req.Target[:])) 892 t.tab.mutex.Lock() 893 closest := t.tab.closest(target, bucketSize, true).entries 894 t.tab.mutex.Unlock() 895 896 // Send neighbors in chunks with at most maxNeighbors per packet 897 // to stay below the packet size limit. 898 p := neighborsV4{Expiration: uint64(time.Now().Add(expiration).Unix())} 899 var sent bool 900 for _, n := range closest { 901 if netutil.CheckRelayIP(from.IP, n.IP()) == nil { 902 p.Nodes = append(p.Nodes, nodeToRPC(n)) 903 } 904 if len(p.Nodes) == maxNeighbors { 905 t.send(from, fromID, &p) 906 p.Nodes = p.Nodes[:0] 907 sent = true 908 } 909 } 910 if len(p.Nodes) > 0 || !sent { 911 t.send(from, fromID, &p) 912 } 913 } 914 915 // NEIGHBORS/v4 916 917 func (req *neighborsV4) name() string { return "NEIGHBORS/v4" } 918 func (req *neighborsV4) kind() byte { return p_neighborsV4 } 919 920 func (req *neighborsV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 921 if expired(req.Expiration) { 922 return errExpired 923 } 924 if !t.handleReply(fromID, from.IP, req) { 925 return errUnsolicitedReply 926 } 927 return nil 928 } 929 930 func (req *neighborsV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 931 } 932 933 // ENRREQUEST/v4 934 935 func (req *enrRequestV4) name() string { return "ENRREQUEST/v4" } 936 func (req *enrRequestV4) kind() byte { return p_enrRequestV4 } 937 938 func (req *enrRequestV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 939 if expired(req.Expiration) { 940 return errExpired 941 } 942 if !t.checkBond(fromID, from.IP) { 943 return errUnknownNode 944 } 945 return nil 946 } 947 948 func (req *enrRequestV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 949 t.send(from, fromID, &enrResponseV4{ 950 ReplyTok: mac, 951 Record: *t.localNode.Node().Record(), 952 }) 953 } 954 955 // ENRRESPONSE/v4 956 957 func (req *enrResponseV4) name() string { return "ENRRESPONSE/v4" } 958 func (req *enrResponseV4) kind() byte { return p_enrResponseV4 } 959 960 func (req *enrResponseV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { 961 if !t.handleReply(fromID, from.IP, req) { 962 return errUnsolicitedReply 963 } 964 return nil 965 } 966 967 func (req *enrResponseV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { 968 }