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