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