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