github.com/ylsgit/go-ethereum@v1.6.5/p2p/server.go (about) 1 // Copyright 2014 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 p2p implements the Ethereum p2p network protocols. 18 package p2p 19 20 import ( 21 "crypto/ecdsa" 22 "errors" 23 "fmt" 24 "net" 25 "sync" 26 "time" 27 28 "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/common/mclock" 30 "github.com/ethereum/go-ethereum/log" 31 "github.com/ethereum/go-ethereum/p2p/discover" 32 "github.com/ethereum/go-ethereum/p2p/discv5" 33 "github.com/ethereum/go-ethereum/p2p/nat" 34 "github.com/ethereum/go-ethereum/p2p/netutil" 35 ) 36 37 const ( 38 defaultDialTimeout = 15 * time.Second 39 refreshPeersInterval = 30 * time.Second 40 staticPeerCheckInterval = 15 * time.Second 41 42 // Maximum number of concurrently handshaking inbound connections. 43 maxAcceptConns = 50 44 45 // Maximum number of concurrently dialing outbound connections. 46 maxActiveDialTasks = 16 47 48 // Maximum time allowed for reading a complete message. 49 // This is effectively the amount of time a connection can be idle. 50 frameReadTimeout = 30 * time.Second 51 52 // Maximum amount of time allowed for writing a complete message. 53 frameWriteTimeout = 20 * time.Second 54 ) 55 56 var errServerStopped = errors.New("server stopped") 57 58 // Config holds Server options. 59 type Config struct { 60 // This field must be set to a valid secp256k1 private key. 61 PrivateKey *ecdsa.PrivateKey `toml:"-"` 62 63 // MaxPeers is the maximum number of peers that can be 64 // connected. It must be greater than zero. 65 MaxPeers int 66 67 // MaxPendingPeers is the maximum number of peers that can be pending in the 68 // handshake phase, counted separately for inbound and outbound connections. 69 // Zero defaults to preset values. 70 MaxPendingPeers int `toml:",omitempty"` 71 72 // NoDiscovery can be used to disable the peer discovery mechanism. 73 // Disabling is useful for protocol debugging (manual topology). 74 NoDiscovery bool 75 76 // DiscoveryV5 specifies whether the the new topic-discovery based V5 discovery 77 // protocol should be started or not. 78 DiscoveryV5 bool `toml:",omitempty"` 79 80 // Listener address for the V5 discovery protocol UDP traffic. 81 DiscoveryV5Addr string `toml:",omitempty"` 82 83 // Name sets the node name of this server. 84 // Use common.MakeName to create a name that follows existing conventions. 85 Name string `toml:"-"` 86 87 // BootstrapNodes are used to establish connectivity 88 // with the rest of the network. 89 BootstrapNodes []*discover.Node 90 91 // BootstrapNodesV5 are used to establish connectivity 92 // with the rest of the network using the V5 discovery 93 // protocol. 94 BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` 95 96 // Static nodes are used as pre-configured connections which are always 97 // maintained and re-connected on disconnects. 98 StaticNodes []*discover.Node 99 100 // Trusted nodes are used as pre-configured connections which are always 101 // allowed to connect, even above the peer limit. 102 TrustedNodes []*discover.Node 103 104 // Connectivity can be restricted to certain IP networks. 105 // If this option is set to a non-nil value, only hosts which match one of the 106 // IP networks contained in the list are considered. 107 NetRestrict *netutil.Netlist `toml:",omitempty"` 108 109 // NodeDatabase is the path to the database containing the previously seen 110 // live nodes in the network. 111 NodeDatabase string `toml:",omitempty"` 112 113 // Protocols should contain the protocols supported 114 // by the server. Matching protocols are launched for 115 // each peer. 116 Protocols []Protocol `toml:"-"` 117 118 // If ListenAddr is set to a non-nil address, the server 119 // will listen for incoming connections. 120 // 121 // If the port is zero, the operating system will pick a port. The 122 // ListenAddr field will be updated with the actual address when 123 // the server is started. 124 ListenAddr string 125 126 // If set to a non-nil value, the given NAT port mapper 127 // is used to make the listening port available to the 128 // Internet. 129 NAT nat.Interface `toml:",omitempty"` 130 131 // If Dialer is set to a non-nil value, the given Dialer 132 // is used to dial outbound peer connections. 133 Dialer *net.Dialer `toml:"-"` 134 135 // If NoDial is true, the server will not dial any peers. 136 NoDial bool `toml:",omitempty"` 137 } 138 139 // Server manages all peer connections. 140 type Server struct { 141 // Config fields may not be modified while the server is running. 142 Config 143 144 // Hooks for testing. These are useful because we can inhibit 145 // the whole protocol stack. 146 newTransport func(net.Conn) transport 147 newPeerHook func(*Peer) 148 149 lock sync.Mutex // protects running 150 running bool 151 152 ntab discoverTable 153 listener net.Listener 154 ourHandshake *protoHandshake 155 lastLookup time.Time 156 DiscV5 *discv5.Network 157 158 // These are for Peers, PeerCount (and nothing else). 159 peerOp chan peerOpFunc 160 peerOpDone chan struct{} 161 162 quit chan struct{} 163 addstatic chan *discover.Node 164 removestatic chan *discover.Node 165 posthandshake chan *conn 166 addpeer chan *conn 167 delpeer chan peerDrop 168 loopWG sync.WaitGroup // loop, listenLoop 169 } 170 171 type peerOpFunc func(map[discover.NodeID]*Peer) 172 173 type peerDrop struct { 174 *Peer 175 err error 176 requested bool // true if signaled by the peer 177 } 178 179 type connFlag int 180 181 const ( 182 dynDialedConn connFlag = 1 << iota 183 staticDialedConn 184 inboundConn 185 trustedConn 186 ) 187 188 // conn wraps a network connection with information gathered 189 // during the two handshakes. 190 type conn struct { 191 fd net.Conn 192 transport 193 flags connFlag 194 cont chan error // The run loop uses cont to signal errors to setupConn. 195 id discover.NodeID // valid after the encryption handshake 196 caps []Cap // valid after the protocol handshake 197 name string // valid after the protocol handshake 198 } 199 200 type transport interface { 201 // The two handshakes. 202 doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) 203 doProtoHandshake(our *protoHandshake) (*protoHandshake, error) 204 // The MsgReadWriter can only be used after the encryption 205 // handshake has completed. The code uses conn.id to track this 206 // by setting it to a non-nil value after the encryption handshake. 207 MsgReadWriter 208 // transports must provide Close because we use MsgPipe in some of 209 // the tests. Closing the actual network connection doesn't do 210 // anything in those tests because NsgPipe doesn't use it. 211 close(err error) 212 } 213 214 func (c *conn) String() string { 215 s := c.flags.String() 216 if (c.id != discover.NodeID{}) { 217 s += " " + c.id.String() 218 } 219 s += " " + c.fd.RemoteAddr().String() 220 return s 221 } 222 223 func (f connFlag) String() string { 224 s := "" 225 if f&trustedConn != 0 { 226 s += "-trusted" 227 } 228 if f&dynDialedConn != 0 { 229 s += "-dyndial" 230 } 231 if f&staticDialedConn != 0 { 232 s += "-staticdial" 233 } 234 if f&inboundConn != 0 { 235 s += "-inbound" 236 } 237 if s != "" { 238 s = s[1:] 239 } 240 return s 241 } 242 243 func (c *conn) is(f connFlag) bool { 244 return c.flags&f != 0 245 } 246 247 // Peers returns all connected peers. 248 func (srv *Server) Peers() []*Peer { 249 var ps []*Peer 250 select { 251 // Note: We'd love to put this function into a variable but 252 // that seems to cause a weird compiler error in some 253 // environments. 254 case srv.peerOp <- func(peers map[discover.NodeID]*Peer) { 255 for _, p := range peers { 256 ps = append(ps, p) 257 } 258 }: 259 <-srv.peerOpDone 260 case <-srv.quit: 261 } 262 return ps 263 } 264 265 // PeerCount returns the number of connected peers. 266 func (srv *Server) PeerCount() int { 267 var count int 268 select { 269 case srv.peerOp <- func(ps map[discover.NodeID]*Peer) { count = len(ps) }: 270 <-srv.peerOpDone 271 case <-srv.quit: 272 } 273 return count 274 } 275 276 // AddPeer connects to the given node and maintains the connection until the 277 // server is shut down. If the connection fails for any reason, the server will 278 // attempt to reconnect the peer. 279 func (srv *Server) AddPeer(node *discover.Node) { 280 select { 281 case srv.addstatic <- node: 282 case <-srv.quit: 283 } 284 } 285 286 // RemovePeer disconnects from the given node 287 func (srv *Server) RemovePeer(node *discover.Node) { 288 select { 289 case srv.removestatic <- node: 290 case <-srv.quit: 291 } 292 } 293 294 // Self returns the local node's endpoint information. 295 func (srv *Server) Self() *discover.Node { 296 srv.lock.Lock() 297 defer srv.lock.Unlock() 298 299 if !srv.running { 300 return &discover.Node{IP: net.ParseIP("0.0.0.0")} 301 } 302 return srv.makeSelf(srv.listener, srv.ntab) 303 } 304 305 func (srv *Server) makeSelf(listener net.Listener, ntab discoverTable) *discover.Node { 306 // If the server's not running, return an empty node. 307 // If the node is running but discovery is off, manually assemble the node infos. 308 if ntab == nil { 309 // Inbound connections disabled, use zero address. 310 if listener == nil { 311 return &discover.Node{IP: net.ParseIP("0.0.0.0"), ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)} 312 } 313 // Otherwise inject the listener address too 314 addr := listener.Addr().(*net.TCPAddr) 315 return &discover.Node{ 316 ID: discover.PubkeyID(&srv.PrivateKey.PublicKey), 317 IP: addr.IP, 318 TCP: uint16(addr.Port), 319 } 320 } 321 // Otherwise return the discovery node. 322 return ntab.Self() 323 } 324 325 // Stop terminates the server and all active peer connections. 326 // It blocks until all active connections have been closed. 327 func (srv *Server) Stop() { 328 srv.lock.Lock() 329 defer srv.lock.Unlock() 330 if !srv.running { 331 return 332 } 333 srv.running = false 334 if srv.listener != nil { 335 // this unblocks listener Accept 336 srv.listener.Close() 337 } 338 close(srv.quit) 339 srv.loopWG.Wait() 340 } 341 342 // Start starts running the server. 343 // Servers can not be re-used after stopping. 344 func (srv *Server) Start() (err error) { 345 srv.lock.Lock() 346 defer srv.lock.Unlock() 347 if srv.running { 348 return errors.New("server already running") 349 } 350 srv.running = true 351 log.Info("Starting P2P networking") 352 353 // static fields 354 if srv.PrivateKey == nil { 355 return fmt.Errorf("Server.PrivateKey must be set to a non-nil key") 356 } 357 if srv.newTransport == nil { 358 srv.newTransport = newRLPX 359 } 360 if srv.Dialer == nil { 361 srv.Dialer = &net.Dialer{Timeout: defaultDialTimeout} 362 } 363 srv.quit = make(chan struct{}) 364 srv.addpeer = make(chan *conn) 365 srv.delpeer = make(chan peerDrop) 366 srv.posthandshake = make(chan *conn) 367 srv.addstatic = make(chan *discover.Node) 368 srv.removestatic = make(chan *discover.Node) 369 srv.peerOp = make(chan peerOpFunc) 370 srv.peerOpDone = make(chan struct{}) 371 372 // node table 373 if !srv.NoDiscovery { 374 ntab, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT, srv.NodeDatabase, srv.NetRestrict) 375 if err != nil { 376 return err 377 } 378 if err := ntab.SetFallbackNodes(srv.BootstrapNodes); err != nil { 379 return err 380 } 381 srv.ntab = ntab 382 } 383 384 if srv.DiscoveryV5 { 385 ntab, err := discv5.ListenUDP(srv.PrivateKey, srv.DiscoveryV5Addr, srv.NAT, "", srv.NetRestrict) //srv.NodeDatabase) 386 if err != nil { 387 return err 388 } 389 if err := ntab.SetFallbackNodes(srv.BootstrapNodesV5); err != nil { 390 return err 391 } 392 srv.DiscV5 = ntab 393 } 394 395 dynPeers := (srv.MaxPeers + 1) / 2 396 if srv.NoDiscovery { 397 dynPeers = 0 398 } 399 dialer := newDialState(srv.StaticNodes, srv.BootstrapNodes, srv.ntab, dynPeers, srv.NetRestrict) 400 401 // handshake 402 srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)} 403 for _, p := range srv.Protocols { 404 srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) 405 } 406 // listen/dial 407 if srv.ListenAddr != "" { 408 if err := srv.startListening(); err != nil { 409 return err 410 } 411 } 412 if srv.NoDial && srv.ListenAddr == "" { 413 log.Warn("P2P server will be useless, neither dialing nor listening") 414 } 415 416 srv.loopWG.Add(1) 417 go srv.run(dialer) 418 srv.running = true 419 return nil 420 } 421 422 func (srv *Server) startListening() error { 423 // Launch the TCP listener. 424 listener, err := net.Listen("tcp", srv.ListenAddr) 425 if err != nil { 426 return err 427 } 428 laddr := listener.Addr().(*net.TCPAddr) 429 srv.ListenAddr = laddr.String() 430 srv.listener = listener 431 srv.loopWG.Add(1) 432 go srv.listenLoop() 433 // Map the TCP listening port if NAT is configured. 434 if !laddr.IP.IsLoopback() && srv.NAT != nil { 435 srv.loopWG.Add(1) 436 go func() { 437 nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p") 438 srv.loopWG.Done() 439 }() 440 } 441 return nil 442 } 443 444 type dialer interface { 445 newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task 446 taskDone(task, time.Time) 447 addStatic(*discover.Node) 448 removeStatic(*discover.Node) 449 } 450 451 func (srv *Server) run(dialstate dialer) { 452 defer srv.loopWG.Done() 453 var ( 454 peers = make(map[discover.NodeID]*Peer) 455 trusted = make(map[discover.NodeID]bool, len(srv.TrustedNodes)) 456 taskdone = make(chan task, maxActiveDialTasks) 457 runningTasks []task 458 queuedTasks []task // tasks that can't run yet 459 ) 460 // Put trusted nodes into a map to speed up checks. 461 // Trusted peers are loaded on startup and cannot be 462 // modified while the server is running. 463 for _, n := range srv.TrustedNodes { 464 trusted[n.ID] = true 465 } 466 467 // removes t from runningTasks 468 delTask := func(t task) { 469 for i := range runningTasks { 470 if runningTasks[i] == t { 471 runningTasks = append(runningTasks[:i], runningTasks[i+1:]...) 472 break 473 } 474 } 475 } 476 // starts until max number of active tasks is satisfied 477 startTasks := func(ts []task) (rest []task) { 478 i := 0 479 for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ { 480 t := ts[i] 481 log.Trace("New dial task", "task", t) 482 go func() { t.Do(srv); taskdone <- t }() 483 runningTasks = append(runningTasks, t) 484 } 485 return ts[i:] 486 } 487 scheduleTasks := func() { 488 // Start from queue first. 489 queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...) 490 // Query dialer for new tasks and start as many as possible now. 491 if len(runningTasks) < maxActiveDialTasks { 492 nt := dialstate.newTasks(len(runningTasks)+len(queuedTasks), peers, time.Now()) 493 queuedTasks = append(queuedTasks, startTasks(nt)...) 494 } 495 } 496 497 running: 498 for { 499 scheduleTasks() 500 501 select { 502 case <-srv.quit: 503 // The server was stopped. Run the cleanup logic. 504 break running 505 case n := <-srv.addstatic: 506 // This channel is used by AddPeer to add to the 507 // ephemeral static peer list. Add it to the dialer, 508 // it will keep the node connected. 509 log.Debug("Adding static node", "node", n) 510 dialstate.addStatic(n) 511 case n := <-srv.removestatic: 512 // This channel is used by RemovePeer to send a 513 // disconnect request to a peer and begin the 514 // stop keeping the node connected 515 log.Debug("Removing static node", "node", n) 516 dialstate.removeStatic(n) 517 if p, ok := peers[n.ID]; ok { 518 p.Disconnect(DiscRequested) 519 } 520 case op := <-srv.peerOp: 521 // This channel is used by Peers and PeerCount. 522 op(peers) 523 srv.peerOpDone <- struct{}{} 524 case t := <-taskdone: 525 // A task got done. Tell dialstate about it so it 526 // can update its state and remove it from the active 527 // tasks list. 528 log.Trace("Dial task done", "task", t) 529 dialstate.taskDone(t, time.Now()) 530 delTask(t) 531 case c := <-srv.posthandshake: 532 // A connection has passed the encryption handshake so 533 // the remote identity is known (but hasn't been verified yet). 534 if trusted[c.id] { 535 // Ensure that the trusted flag is set before checking against MaxPeers. 536 c.flags |= trustedConn 537 } 538 // TODO: track in-progress inbound node IDs (pre-Peer) to avoid dialing them. 539 c.cont <- srv.encHandshakeChecks(peers, c) 540 case c := <-srv.addpeer: 541 // At this point the connection is past the protocol handshake. 542 // Its capabilities are known and the remote identity is verified. 543 err := srv.protoHandshakeChecks(peers, c) 544 if err == nil { 545 // The handshakes are done and it passed all checks. 546 p := newPeer(c, srv.Protocols) 547 name := truncateName(c.name) 548 log.Debug("Adding p2p peer", "id", c.id, "name", name, "addr", c.fd.RemoteAddr(), "peers", len(peers)+1) 549 peers[c.id] = p 550 go srv.runPeer(p) 551 } 552 // The dialer logic relies on the assumption that 553 // dial tasks complete after the peer has been added or 554 // discarded. Unblock the task last. 555 c.cont <- err 556 case pd := <-srv.delpeer: 557 // A peer disconnected. 558 d := common.PrettyDuration(mclock.Now() - pd.created) 559 pd.log.Debug("Removing p2p peer", "duration", d, "peers", len(peers)-1, "req", pd.requested, "err", pd.err) 560 delete(peers, pd.ID()) 561 } 562 } 563 564 log.Trace("P2P networking is spinning down") 565 566 // Terminate discovery. If there is a running lookup it will terminate soon. 567 if srv.ntab != nil { 568 srv.ntab.Close() 569 } 570 if srv.DiscV5 != nil { 571 srv.DiscV5.Close() 572 } 573 // Disconnect all peers. 574 for _, p := range peers { 575 p.Disconnect(DiscQuitting) 576 } 577 // Wait for peers to shut down. Pending connections and tasks are 578 // not handled here and will terminate soon-ish because srv.quit 579 // is closed. 580 for len(peers) > 0 { 581 p := <-srv.delpeer 582 p.log.Trace("<-delpeer (spindown)", "remainingTasks", len(runningTasks)) 583 delete(peers, p.ID()) 584 } 585 } 586 587 func (srv *Server) protoHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn) error { 588 // Drop connections with no matching protocols. 589 if len(srv.Protocols) > 0 && countMatchingProtocols(srv.Protocols, c.caps) == 0 { 590 return DiscUselessPeer 591 } 592 // Repeat the encryption handshake checks because the 593 // peer set might have changed between the handshakes. 594 return srv.encHandshakeChecks(peers, c) 595 } 596 597 func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn) error { 598 switch { 599 case !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers: 600 return DiscTooManyPeers 601 case peers[c.id] != nil: 602 return DiscAlreadyConnected 603 case c.id == srv.Self().ID: 604 return DiscSelf 605 default: 606 return nil 607 } 608 } 609 610 type tempError interface { 611 Temporary() bool 612 } 613 614 // listenLoop runs in its own goroutine and accepts 615 // inbound connections. 616 func (srv *Server) listenLoop() { 617 defer srv.loopWG.Done() 618 log.Info("RLPx listener up", "self", srv.makeSelf(srv.listener, srv.ntab)) 619 620 // This channel acts as a semaphore limiting 621 // active inbound connections that are lingering pre-handshake. 622 // If all slots are taken, no further connections are accepted. 623 tokens := maxAcceptConns 624 if srv.MaxPendingPeers > 0 { 625 tokens = srv.MaxPendingPeers 626 } 627 slots := make(chan struct{}, tokens) 628 for i := 0; i < tokens; i++ { 629 slots <- struct{}{} 630 } 631 632 for { 633 // Wait for a handshake slot before accepting. 634 <-slots 635 636 var ( 637 fd net.Conn 638 err error 639 ) 640 for { 641 fd, err = srv.listener.Accept() 642 if tempErr, ok := err.(tempError); ok && tempErr.Temporary() { 643 log.Debug("Temporary read error", "err", err) 644 continue 645 } else if err != nil { 646 log.Debug("Read error", "err", err) 647 return 648 } 649 break 650 } 651 652 // Reject connections that do not match NetRestrict. 653 if srv.NetRestrict != nil { 654 if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok && !srv.NetRestrict.Contains(tcp.IP) { 655 log.Debug("Rejected conn (not whitelisted in NetRestrict)", "addr", fd.RemoteAddr()) 656 fd.Close() 657 slots <- struct{}{} 658 continue 659 } 660 } 661 662 fd = newMeteredConn(fd, true) 663 log.Trace("Accepted connection", "addr", fd.RemoteAddr()) 664 665 // Spawn the handler. It will give the slot back when the connection 666 // has been established. 667 go func() { 668 srv.setupConn(fd, inboundConn, nil) 669 slots <- struct{}{} 670 }() 671 } 672 } 673 674 // setupConn runs the handshakes and attempts to add the connection 675 // as a peer. It returns when the connection has been added as a peer 676 // or the handshakes have failed. 677 func (srv *Server) setupConn(fd net.Conn, flags connFlag, dialDest *discover.Node) { 678 // Prevent leftover pending conns from entering the handshake. 679 srv.lock.Lock() 680 running := srv.running 681 srv.lock.Unlock() 682 c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)} 683 if !running { 684 c.close(errServerStopped) 685 return 686 } 687 // Run the encryption handshake. 688 var err error 689 if c.id, err = c.doEncHandshake(srv.PrivateKey, dialDest); err != nil { 690 log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) 691 c.close(err) 692 return 693 } 694 clog := log.New("id", c.id, "addr", c.fd.RemoteAddr(), "conn", c.flags) 695 // For dialed connections, check that the remote public key matches. 696 if dialDest != nil && c.id != dialDest.ID { 697 c.close(DiscUnexpectedIdentity) 698 clog.Trace("Dialed identity mismatch", "want", c, dialDest.ID) 699 return 700 } 701 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 702 clog.Trace("Rejected peer before protocol handshake", "err", err) 703 c.close(err) 704 return 705 } 706 // Run the protocol handshake 707 phs, err := c.doProtoHandshake(srv.ourHandshake) 708 if err != nil { 709 clog.Trace("Failed proto handshake", "err", err) 710 c.close(err) 711 return 712 } 713 if phs.ID != c.id { 714 clog.Trace("Wrong devp2p handshake identity", "err", phs.ID) 715 c.close(DiscUnexpectedIdentity) 716 return 717 } 718 c.caps, c.name = phs.Caps, phs.Name 719 if err := srv.checkpoint(c, srv.addpeer); err != nil { 720 clog.Trace("Rejected peer", "err", err) 721 c.close(err) 722 return 723 } 724 // If the checks completed successfully, runPeer has now been 725 // launched by run. 726 } 727 728 func truncateName(s string) string { 729 if len(s) > 20 { 730 return s[:20] + "..." 731 } 732 return s 733 } 734 735 // checkpoint sends the conn to run, which performs the 736 // post-handshake checks for the stage (posthandshake, addpeer). 737 func (srv *Server) checkpoint(c *conn, stage chan<- *conn) error { 738 select { 739 case stage <- c: 740 case <-srv.quit: 741 return errServerStopped 742 } 743 select { 744 case err := <-c.cont: 745 return err 746 case <-srv.quit: 747 return errServerStopped 748 } 749 } 750 751 // runPeer runs in its own goroutine for each peer. 752 // it waits until the Peer logic returns and removes 753 // the peer. 754 func (srv *Server) runPeer(p *Peer) { 755 if srv.newPeerHook != nil { 756 srv.newPeerHook(p) 757 } 758 remoteRequested, err := p.run() 759 // Note: run waits for existing peers to be sent on srv.delpeer 760 // before returning, so this send should not select on srv.quit. 761 srv.delpeer <- peerDrop{p, err, remoteRequested} 762 } 763 764 // NodeInfo represents a short summary of the information known about the host. 765 type NodeInfo struct { 766 ID string `json:"id"` // Unique node identifier (also the encryption key) 767 Name string `json:"name"` // Name of the node, including client type, version, OS, custom data 768 Enode string `json:"enode"` // Enode URL for adding this peer from remote peers 769 IP string `json:"ip"` // IP address of the node 770 Ports struct { 771 Discovery int `json:"discovery"` // UDP listening port for discovery protocol 772 Listener int `json:"listener"` // TCP listening port for RLPx 773 } `json:"ports"` 774 ListenAddr string `json:"listenAddr"` 775 Protocols map[string]interface{} `json:"protocols"` 776 } 777 778 // NodeInfo gathers and returns a collection of metadata known about the host. 779 func (srv *Server) NodeInfo() *NodeInfo { 780 node := srv.Self() 781 782 // Gather and assemble the generic node infos 783 info := &NodeInfo{ 784 Name: srv.Name, 785 Enode: node.String(), 786 ID: node.ID.String(), 787 IP: node.IP.String(), 788 ListenAddr: srv.ListenAddr, 789 Protocols: make(map[string]interface{}), 790 } 791 info.Ports.Discovery = int(node.UDP) 792 info.Ports.Listener = int(node.TCP) 793 794 // Gather all the running protocol infos (only once per protocol type) 795 for _, proto := range srv.Protocols { 796 if _, ok := info.Protocols[proto.Name]; !ok { 797 nodeInfo := interface{}("unknown") 798 if query := proto.NodeInfo; query != nil { 799 nodeInfo = proto.NodeInfo() 800 } 801 info.Protocols[proto.Name] = nodeInfo 802 } 803 } 804 return info 805 } 806 807 // PeersInfo returns an array of metadata objects describing connected peers. 808 func (srv *Server) PeersInfo() []*PeerInfo { 809 // Gather all the generic and sub-protocol specific infos 810 infos := make([]*PeerInfo, 0, srv.PeerCount()) 811 for _, peer := range srv.Peers() { 812 if peer != nil { 813 infos = append(infos, peer.Info()) 814 } 815 } 816 // Sort the result array alphabetically by node identifier 817 for i := 0; i < len(infos); i++ { 818 for j := i + 1; j < len(infos); j++ { 819 if infos[i].ID > infos[j].ID { 820 infos[i], infos[j] = infos[j], infos[i] 821 } 822 } 823 } 824 return infos 825 }