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