github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/server.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 //包P2P实现以太坊P2P网络协议。 26 package p2p 27 28 import ( 29 "crypto/ecdsa" 30 "errors" 31 "fmt" 32 "net" 33 "sync" 34 "sync/atomic" 35 "time" 36 37 "github.com/ethereum/go-ethereum/common" 38 "github.com/ethereum/go-ethereum/common/mclock" 39 "github.com/ethereum/go-ethereum/event" 40 "github.com/ethereum/go-ethereum/log" 41 "github.com/ethereum/go-ethereum/p2p/discover" 42 "github.com/ethereum/go-ethereum/p2p/discv5" 43 "github.com/ethereum/go-ethereum/p2p/nat" 44 "github.com/ethereum/go-ethereum/p2p/netutil" 45 ) 46 47 const ( 48 defaultDialTimeout = 15 * time.Second 49 50 //连接默认值。 51 maxActiveDialTasks = 16 52 defaultMaxPendingPeers = 50 53 defaultDialRatio = 3 54 55 //读取完整邮件所允许的最长时间。 56 //这实际上是连接可以空闲的时间量。 57 frameReadTimeout = 30 * time.Second 58 59 //写入完整消息所允许的最长时间。 60 frameWriteTimeout = 20 * time.Second 61 ) 62 63 var errServerStopped = errors.New("server stopped") 64 65 //配置保留服务器选项。 66 type Config struct { 67 //此字段必须设置为有效的secp256k1私钥。 68 PrivateKey *ecdsa.PrivateKey `toml:"-"` 69 70 //MaxPeers是可以 71 //有联系的。它必须大于零。 72 MaxPeers int 73 74 //MaxPendingPeers是在 75 //握手阶段,分别为入站和出站连接计数。 76 //零默认为预设值。 77 MaxPendingPeers int `toml:",omitempty"` 78 79 //DialRatio控制入站与拨入连接的比率。 80 //示例:拨号比率2允许拨1/2的连接。 81 //将DialRatio设置为零将默认为3。 82 DialRatio int `toml:",omitempty"` 83 84 //nodiscovery可用于禁用对等发现机制。 85 //禁用对于协议调试(手动拓扑)很有用。 86 NoDiscovery bool 87 88 //discovery v5指定基于新主题发现的v5发现 89 //是否启动协议。 90 DiscoveryV5 bool `toml:",omitempty"` 91 92 //名称设置此服务器的节点名称。 93 //使用common.makename创建遵循现有约定的名称。 94 Name string `toml:"-"` 95 96 //bootstrapnodes用于建立连接 97 //与网络的其他部分。 98 BootstrapNodes []*discover.Node 99 100 //bootstrapnodesv5用于建立连接 101 //与网络的其余部分一起使用v5发现 102 //协议。 103 BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` 104 105 //静态节点用作预先配置的连接,这些连接总是 106 //在断开时保持并重新连接。 107 StaticNodes []*discover.Node 108 109 //受信任节点用作预先配置的连接,这些连接总是 110 //允许连接,甚至高于对等限制。 111 TrustedNodes []*discover.Node 112 113 //连接可以限制到某些IP网络。 114 //如果此选项设置为非nil值,则仅主机与 115 //考虑列表中包含的IP网络。 116 NetRestrict *netutil.Netlist `toml:",omitempty"` 117 118 //nodedatabase是包含以前看到的 119 //网络中的活动节点。 120 NodeDatabase string `toml:",omitempty"` 121 122 //协议应包含支持的协议 123 //由服务器。为启动匹配协议 124 //每个对等体。 125 Protocols []Protocol `toml:"-"` 126 127 //如果listenaddr设置为非nil地址,则服务器 128 //将侦听传入的连接。 129 // 130 //如果端口为零,操作系统将选择一个端口。这个 131 //当 132 //服务器已启动。 133 ListenAddr string 134 135 //如果设置为非零值,则指定的NAT端口映射器 136 //用于使侦听端口对 137 //互联网。 138 NAT nat.Interface `toml:",omitempty"` 139 140 //如果拨号程序设置为非零值,则指定的拨号程序 141 //用于拨号出站对等连接。 142 Dialer NodeDialer `toml:"-"` 143 144 //如果nodial为真,服务器将不会拨任何对等机。 145 NoDial bool `toml:",omitempty"` 146 147 //如果设置了EnableMsgeEvents,则服务器将发出PeerEvents 148 //无论何时向对等端发送或从对等端接收消息 149 EnableMsgEvents bool 150 151 //logger是用于p2p.server的自定义记录器。 152 Logger log.Logger `toml:",omitempty"` 153 } 154 155 //服务器管理所有对等连接。 156 type Server struct { 157 //服务器运行时不能修改配置字段。 158 Config 159 160 //测试用挂钩。这些是有用的,因为我们可以抑制 161 //整个协议栈。 162 newTransport func(net.Conn) transport 163 newPeerHook func(*Peer) 164 165 lock sync.Mutex //保护运行 166 running bool 167 168 ntab discoverTable 169 listener net.Listener 170 ourHandshake *protoHandshake 171 lastLookup time.Time 172 DiscV5 *discv5.Network 173 174 //这些是为对等机,对等机计数(而不是其他任何东西)。 175 peerOp chan peerOpFunc 176 peerOpDone chan struct{} 177 178 quit chan struct{} 179 addstatic chan *discover.Node 180 removestatic chan *discover.Node 181 addtrusted chan *discover.Node 182 removetrusted chan *discover.Node 183 posthandshake chan *conn 184 addpeer chan *conn 185 delpeer chan peerDrop 186 loopWG sync.WaitGroup //循环,listenloop 187 peerFeed event.Feed 188 log log.Logger 189 } 190 191 type peerOpFunc func(map[discover.NodeID]*Peer) 192 193 type peerDrop struct { 194 *Peer 195 err error 196 requested bool //如果对等方发出信号,则为真 197 } 198 199 type connFlag int32 200 201 const ( 202 dynDialedConn connFlag = 1 << iota 203 staticDialedConn 204 inboundConn 205 trustedConn 206 ) 207 208 //conn用收集的信息包装网络连接 209 //在两次握手中。 210 type conn struct { 211 fd net.Conn 212 transport 213 flags connFlag 214 cont chan error //运行循环使用cont向setupconn发送错误信号。 215 id discover.NodeID //加密握手后有效 216 caps []Cap //协议握手后有效 217 name string //协议握手后有效 218 } 219 220 type transport interface { 221 //两人握手。 222 doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) 223 doProtoHandshake(our *protoHandshake) (*protoHandshake, error) 224 //msgreadwriter只能在加密后使用 225 //握手已完成。代码使用conn.id跟踪 226 //通过在加密握手后将其设置为非零值。 227 MsgReadWriter 228 //传输必须提供close,因为我们在 229 //测试。关闭实际网络连接不起作用 230 //这些测试中的任何内容,因为nsgpipe不使用它。 231 close(err error) 232 } 233 234 func (c *conn) String() string { 235 s := c.flags.String() 236 if (c.id != discover.NodeID{}) { 237 s += " " + c.id.String() 238 } 239 s += " " + c.fd.RemoteAddr().String() 240 return s 241 } 242 243 func (f connFlag) String() string { 244 s := "" 245 if f&trustedConn != 0 { 246 s += "-trusted" 247 } 248 if f&dynDialedConn != 0 { 249 s += "-dyndial" 250 } 251 if f&staticDialedConn != 0 { 252 s += "-staticdial" 253 } 254 if f&inboundConn != 0 { 255 s += "-inbound" 256 } 257 if s != "" { 258 s = s[1:] 259 } 260 return s 261 } 262 263 func (c *conn) is(f connFlag) bool { 264 flags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) 265 return flags&f != 0 266 } 267 268 func (c *conn) set(f connFlag, val bool) { 269 for { 270 oldFlags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) 271 flags := oldFlags 272 if val { 273 flags |= f 274 } else { 275 flags &= ^f 276 } 277 if atomic.CompareAndSwapInt32((*int32)(&c.flags), int32(oldFlags), int32(flags)) { 278 return 279 } 280 } 281 } 282 283 //对等端返回所有连接的对等端。 284 func (srv *Server) Peers() []*Peer { 285 var ps []*Peer 286 select { 287 //注意:我们希望将此函数放入变量中,但是 288 //这似乎导致了一些 289 //环境。 290 case srv.peerOp <- func(peers map[discover.NodeID]*Peer) { 291 for _, p := range peers { 292 ps = append(ps, p) 293 } 294 }: 295 <-srv.peerOpDone 296 case <-srv.quit: 297 } 298 return ps 299 } 300 301 //PeerCount返回连接的对等数。 302 func (srv *Server) PeerCount() int { 303 var count int 304 select { 305 case srv.peerOp <- func(ps map[discover.NodeID]*Peer) { count = len(ps) }: 306 <-srv.peerOpDone 307 case <-srv.quit: 308 } 309 return count 310 } 311 312 //addpeer连接到给定的节点并保持连接,直到 313 //服务器已关闭。如果由于任何原因连接失败,服务器将 314 //尝试重新连接对等机。 315 func (srv *Server) AddPeer(node *discover.Node) { 316 select { 317 case srv.addstatic <- node: 318 case <-srv.quit: 319 } 320 } 321 322 //从给定节点删除对等机断开连接 323 func (srv *Server) RemovePeer(node *discover.Node) { 324 select { 325 case srv.removestatic <- node: 326 case <-srv.quit: 327 } 328 } 329 330 //addTrustedPeer将给定节点添加到保留的白名单中,该白名单允许 331 //要始终连接的节点,即使插槽已满。 332 func (srv *Server) AddTrustedPeer(node *discover.Node) { 333 select { 334 case srv.addtrusted <- node: 335 case <-srv.quit: 336 } 337 } 338 339 //removeTrustedPeer从受信任的对等集删除给定节点。 340 func (srv *Server) RemoveTrustedPeer(node *discover.Node) { 341 select { 342 case srv.removetrusted <- node: 343 case <-srv.quit: 344 } 345 } 346 347 //subscribePeers订阅给定的通道到对等事件 348 func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { 349 return srv.peerFeed.Subscribe(ch) 350 } 351 352 //self返回本地节点的端点信息。 353 func (srv *Server) Self() *discover.Node { 354 srv.lock.Lock() 355 defer srv.lock.Unlock() 356 357 if !srv.running { 358 return &discover.Node{IP: net.ParseIP("0.0.0.0")} 359 } 360 return srv.makeSelf(srv.listener, srv.ntab) 361 } 362 363 func (srv *Server) makeSelf(listener net.Listener, ntab discoverTable) *discover.Node { 364 //如果服务器没有运行,则返回一个空节点。 365 //如果节点正在运行但发现已关闭,请手动组装节点信息。 366 if ntab == nil { 367 //已禁用入站连接,请使用零地址。 368 if listener == nil { 369 return &discover.Node{IP: net.ParseIP("0.0.0.0"), ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)} 370 } 371 //否则,也插入侦听器地址 372 addr := listener.Addr().(*net.TCPAddr) 373 return &discover.Node{ 374 ID: discover.PubkeyID(&srv.PrivateKey.PublicKey), 375 IP: addr.IP, 376 TCP: uint16(addr.Port), 377 } 378 } 379 //否则返回发现节点。 380 return ntab.Self() 381 } 382 383 //stop终止服务器和所有活动的对等连接。 384 //它会一直阻塞,直到关闭所有活动连接。 385 func (srv *Server) Stop() { 386 srv.lock.Lock() 387 if !srv.running { 388 srv.lock.Unlock() 389 return 390 } 391 srv.running = false 392 if srv.listener != nil { 393 //此取消阻止侦听器接受 394 srv.listener.Close() 395 } 396 close(srv.quit) 397 srv.lock.Unlock() 398 srv.loopWG.Wait() 399 } 400 401 //sharedudpconn实现共享连接。写将消息发送到基础连接,而读将返回 402 //发现无法处理的消息,并由主侦听器发送到未处理的通道。 403 type sharedUDPConn struct { 404 *net.UDPConn 405 unhandled chan discover.ReadPacket 406 } 407 408 //readfromudp实现discv5.conn 409 func (s *sharedUDPConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { 410 packet, ok := <-s.unhandled 411 if !ok { 412 return 0, nil, fmt.Errorf("Connection was closed") 413 } 414 l := len(packet.Data) 415 if l > len(b) { 416 l = len(b) 417 } 418 copy(b[:l], packet.Data[:l]) 419 return l, packet.Addr, nil 420 } 421 422 //关闭机具discv5.conn 423 func (s *sharedUDPConn) Close() error { 424 return nil 425 } 426 427 //开始运行服务器。 428 //服务器停止后不能重新使用。 429 func (srv *Server) Start() (err error) { 430 srv.lock.Lock() 431 defer srv.lock.Unlock() 432 if srv.running { 433 return errors.New("server already running") 434 } 435 srv.running = true 436 srv.log = srv.Config.Logger 437 if srv.log == nil { 438 srv.log = log.New() 439 } 440 srv.log.Info("Starting P2P networking") 441 442 //静态场 443 if srv.PrivateKey == nil { 444 return fmt.Errorf("Server.PrivateKey must be set to a non-nil key") 445 } 446 if srv.newTransport == nil { 447 srv.newTransport = newRLPX 448 } 449 if srv.Dialer == nil { 450 srv.Dialer = TCPDialer{&net.Dialer{Timeout: defaultDialTimeout}} 451 } 452 srv.quit = make(chan struct{}) 453 srv.addpeer = make(chan *conn) 454 srv.delpeer = make(chan peerDrop) 455 srv.posthandshake = make(chan *conn) 456 srv.addstatic = make(chan *discover.Node) 457 srv.removestatic = make(chan *discover.Node) 458 srv.addtrusted = make(chan *discover.Node) 459 srv.removetrusted = make(chan *discover.Node) 460 srv.peerOp = make(chan peerOpFunc) 461 srv.peerOpDone = make(chan struct{}) 462 463 var ( 464 conn *net.UDPConn 465 sconn *sharedUDPConn 466 realaddr *net.UDPAddr 467 unhandled chan discover.ReadPacket 468 ) 469 470 if !srv.NoDiscovery || srv.DiscoveryV5 { 471 addr, err := net.ResolveUDPAddr("udp", srv.ListenAddr) 472 if err != nil { 473 return err 474 } 475 conn, err = net.ListenUDP("udp", addr) 476 if err != nil { 477 return err 478 } 479 realaddr = conn.LocalAddr().(*net.UDPAddr) 480 if srv.NAT != nil { 481 if !realaddr.IP.IsLoopback() { 482 go nat.Map(srv.NAT, srv.quit, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") 483 } 484 //TODO:随着时间的推移对外部IP更改做出响应。 485 if ext, err := srv.NAT.ExternalIP(); err == nil { 486 realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port} 487 } 488 } 489 } 490 491 if !srv.NoDiscovery && srv.DiscoveryV5 { 492 unhandled = make(chan discover.ReadPacket, 100) 493 sconn = &sharedUDPConn{conn, unhandled} 494 } 495 496 //节点表 497 if !srv.NoDiscovery { 498 cfg := discover.Config{ 499 PrivateKey: srv.PrivateKey, 500 AnnounceAddr: realaddr, 501 NodeDBPath: srv.NodeDatabase, 502 NetRestrict: srv.NetRestrict, 503 Bootnodes: srv.BootstrapNodes, 504 Unhandled: unhandled, 505 } 506 ntab, err := discover.ListenUDP(conn, cfg) 507 if err != nil { 508 return err 509 } 510 srv.ntab = ntab 511 } 512 513 if srv.DiscoveryV5 { 514 var ( 515 ntab *discv5.Network 516 err error 517 ) 518 if sconn != nil { 519 ntab, err = discv5.ListenUDP(srv.PrivateKey, sconn, realaddr, "", srv.NetRestrict) //服务器节点数据库) 520 } else { 521 ntab, err = discv5.ListenUDP(srv.PrivateKey, conn, realaddr, "", srv.NetRestrict) //服务器节点数据库) 522 } 523 if err != nil { 524 return err 525 } 526 if err := ntab.SetFallbackNodes(srv.BootstrapNodesV5); err != nil { 527 return err 528 } 529 srv.DiscV5 = ntab 530 } 531 532 dynPeers := srv.maxDialedConns() 533 dialer := newDialState(srv.StaticNodes, srv.BootstrapNodes, srv.ntab, dynPeers, srv.NetRestrict) 534 535 //握手 536 srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)} 537 for _, p := range srv.Protocols { 538 srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) 539 } 540 //听/拨 541 if srv.ListenAddr != "" { 542 if err := srv.startListening(); err != nil { 543 return err 544 } 545 } 546 if srv.NoDial && srv.ListenAddr == "" { 547 srv.log.Warn("P2P server will be useless, neither dialing nor listening") 548 } 549 550 srv.loopWG.Add(1) 551 go srv.run(dialer) 552 srv.running = true 553 return nil 554 } 555 556 func (srv *Server) startListening() error { 557 //启动TCP侦听器。 558 listener, err := net.Listen("tcp", srv.ListenAddr) 559 if err != nil { 560 return err 561 } 562 laddr := listener.Addr().(*net.TCPAddr) 563 srv.ListenAddr = laddr.String() 564 srv.listener = listener 565 srv.loopWG.Add(1) 566 go srv.listenLoop() 567 //如果配置了NAT,则映射TCP侦听端口。 568 if !laddr.IP.IsLoopback() && srv.NAT != nil { 569 srv.loopWG.Add(1) 570 go func() { 571 nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p") 572 srv.loopWG.Done() 573 }() 574 } 575 return nil 576 } 577 578 type dialer interface { 579 newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task 580 taskDone(task, time.Time) 581 addStatic(*discover.Node) 582 removeStatic(*discover.Node) 583 } 584 585 func (srv *Server) run(dialstate dialer) { 586 defer srv.loopWG.Done() 587 var ( 588 peers = make(map[discover.NodeID]*Peer) 589 inboundCount = 0 590 trusted = make(map[discover.NodeID]bool, len(srv.TrustedNodes)) 591 taskdone = make(chan task, maxActiveDialTasks) 592 runningTasks []task 593 queuedTasks []task //尚未运行的任务 594 ) 595 //将受信任的节点放入映射以加快检查速度。 596 //可信对等机在启动时加载或通过addtrustedpeer rpc添加。 597 for _, n := range srv.TrustedNodes { 598 trusted[n.ID] = true 599 } 600 601 //从运行任务中删除t 602 delTask := func(t task) { 603 for i := range runningTasks { 604 if runningTasks[i] == t { 605 runningTasks = append(runningTasks[:i], runningTasks[i+1:]...) 606 break 607 } 608 } 609 } 610 //在满足最大活动任务数之前启动 611 startTasks := func(ts []task) (rest []task) { 612 i := 0 613 for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ { 614 t := ts[i] 615 srv.log.Trace("New dial task", "task", t) 616 go func() { t.Do(srv); taskdone <- t }() 617 runningTasks = append(runningTasks, t) 618 } 619 return ts[i:] 620 } 621 scheduleTasks := func() { 622 //先从队列开始。 623 queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...) 624 //查询拨号程序以查找新任务,并立即尽可能多地启动。 625 if len(runningTasks) < maxActiveDialTasks { 626 nt := dialstate.newTasks(len(runningTasks)+len(queuedTasks), peers, time.Now()) 627 queuedTasks = append(queuedTasks, startTasks(nt)...) 628 } 629 } 630 631 running: 632 for { 633 scheduleTasks() 634 635 select { 636 case <-srv.quit: 637 //服务器已停止。运行清除逻辑。 638 break running 639 case n := <-srv.addstatic: 640 //addpeer使用此通道添加到 641 //短暂的静态对等列表。把它加到拨号器上, 642 //它将保持节点连接。 643 srv.log.Trace("Adding static node", "node", n) 644 dialstate.addStatic(n) 645 case n := <-srv.removestatic: 646 //removepeer使用此通道发送 647 //断开对对等机的请求并开始 648 //停止保持节点连接。 649 srv.log.Trace("Removing static node", "node", n) 650 dialstate.removeStatic(n) 651 if p, ok := peers[n.ID]; ok { 652 p.Disconnect(DiscRequested) 653 } 654 case n := <-srv.addtrusted: 655 //addTrustedPeer使用此通道添加enode 656 //到受信任的节点集。 657 srv.log.Trace("Adding trusted node", "node", n) 658 trusted[n.ID] = true 659 //将任何已连接的对等机标记为受信任 660 if p, ok := peers[n.ID]; ok { 661 p.rw.set(trustedConn, true) 662 } 663 case n := <-srv.removetrusted: 664 //此通道由removeTrustedPeer用于删除enode 665 //来自受信任的节点集。 666 srv.log.Trace("Removing trusted node", "node", n) 667 if _, ok := trusted[n.ID]; ok { 668 delete(trusted, n.ID) 669 } 670 //将任何已连接的对等机取消标记为受信任 671 if p, ok := peers[n.ID]; ok { 672 p.rw.set(trustedConn, false) 673 } 674 case op := <-srv.peerOp: 675 //此通道由对等方和对等方使用。 676 op(peers) 677 srv.peerOpDone <- struct{}{} 678 case t := <-taskdone: 679 //任务完成了。告诉Dialstate,所以 680 //可以更新其状态并将其从活动 681 //任务列表。 682 srv.log.Trace("Dial task done", "task", t) 683 dialstate.taskDone(t, time.Now()) 684 delTask(t) 685 case c := <-srv.posthandshake: 686 //连接已通过加密握手,因此 687 //远程标识已知(但尚未验证)。 688 if trusted[c.id] { 689 //在对MaxPeers进行检查之前,请确保设置了可信标志。 690 c.flags |= trustedConn 691 } 692 //TODO:跟踪正在进行的入站节点ID(预对等),以避免拨号。 693 select { 694 case c.cont <- srv.encHandshakeChecks(peers, inboundCount, c): 695 case <-srv.quit: 696 break running 697 } 698 case c := <-srv.addpeer: 699 //此时,连接已超过协议握手。 700 //它的功能是已知的,并且远程身份被验证。 701 err := srv.protoHandshakeChecks(peers, inboundCount, c) 702 if err == nil { 703 //握手完成,通过所有检查。 704 p := newPeer(c, srv.Protocols) 705 //如果启用了消息事件,则传递peerfeed 706 //向同行 707 if srv.EnableMsgEvents { 708 p.events = &srv.peerFeed 709 } 710 name := truncateName(c.name) 711 srv.log.Debug("Adding p2p peer", "name", name, "addr", c.fd.RemoteAddr(), "peers", len(peers)+1) 712 go srv.runPeer(p) 713 peers[c.id] = p 714 if p.Inbound() { 715 inboundCount++ 716 } 717 } 718 //拨号程序逻辑依赖于以下假设: 719 //添加对等机后完成拨号任务,或者 720 //丢弃的。最后取消阻止任务。 721 select { 722 case c.cont <- err: 723 case <-srv.quit: 724 break running 725 } 726 case pd := <-srv.delpeer: 727 //已断开连接的对等机。 728 d := common.PrettyDuration(mclock.Now() - pd.created) 729 pd.log.Debug("Removing p2p peer", "duration", d, "peers", len(peers)-1, "req", pd.requested, "err", pd.err) 730 delete(peers, pd.ID()) 731 if pd.Inbound() { 732 inboundCount-- 733 } 734 } 735 } 736 737 srv.log.Trace("P2P networking is spinning down") 738 739 //终止发现。如果有正在运行的查找,它将很快终止。 740 if srv.ntab != nil { 741 srv.ntab.Close() 742 } 743 if srv.DiscV5 != nil { 744 srv.DiscV5.Close() 745 } 746 //断开所有对等机的连接。 747 for _, p := range peers { 748 p.Disconnect(DiscQuitting) 749 } 750 //等待对等机关闭。挂起的连接和任务是 751 //此处未处理,将很快终止,因为srv.quit 752 //关闭。 753 for len(peers) > 0 { 754 p := <-srv.delpeer 755 p.log.Trace("<-delpeer (spindown)", "remainingTasks", len(runningTasks)) 756 delete(peers, p.ID()) 757 } 758 } 759 760 func (srv *Server) protoHandshakeChecks(peers map[discover.NodeID]*Peer, inboundCount int, c *conn) error { 761 //删除没有匹配协议的连接。 762 if len(srv.Protocols) > 0 && countMatchingProtocols(srv.Protocols, c.caps) == 0 { 763 return DiscUselessPeer 764 } 765 //重复加密握手检查,因为 766 //对等机集可能在握手之间发生了更改。 767 return srv.encHandshakeChecks(peers, inboundCount, c) 768 } 769 770 func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, inboundCount int, c *conn) error { 771 switch { 772 case !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers: 773 return DiscTooManyPeers 774 case !c.is(trustedConn) && c.is(inboundConn) && inboundCount >= srv.maxInboundConns(): 775 return DiscTooManyPeers 776 case peers[c.id] != nil: 777 return DiscAlreadyConnected 778 case c.id == srv.Self().ID: 779 return DiscSelf 780 default: 781 return nil 782 } 783 } 784 785 func (srv *Server) maxInboundConns() int { 786 return srv.MaxPeers - srv.maxDialedConns() 787 } 788 789 func (srv *Server) maxDialedConns() int { 790 if srv.NoDiscovery || srv.NoDial { 791 return 0 792 } 793 r := srv.DialRatio 794 if r == 0 { 795 r = defaultDialRatio 796 } 797 return srv.MaxPeers / r 798 } 799 800 type tempError interface { 801 Temporary() bool 802 } 803 804 //listenloop在自己的goroutine中运行并接受 805 //入站连接。 806 func (srv *Server) listenLoop() { 807 defer srv.loopWG.Done() 808 srv.log.Info("RLPx listener up", "self", srv.makeSelf(srv.listener, srv.ntab)) 809 810 tokens := defaultMaxPendingPeers 811 if srv.MaxPendingPeers > 0 { 812 tokens = srv.MaxPendingPeers 813 } 814 slots := make(chan struct{}, tokens) 815 for i := 0; i < tokens; i++ { 816 slots <- struct{}{} 817 } 818 819 for { 820 //在接受前等待握手槽。 821 <-slots 822 823 var ( 824 fd net.Conn 825 err error 826 ) 827 for { 828 fd, err = srv.listener.Accept() 829 if tempErr, ok := err.(tempError); ok && tempErr.Temporary() { 830 srv.log.Debug("Temporary read error", "err", err) 831 continue 832 } else if err != nil { 833 srv.log.Debug("Read error", "err", err) 834 return 835 } 836 break 837 } 838 839 //拒绝与NetRestrict不匹配的连接。 840 if srv.NetRestrict != nil { 841 if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok && !srv.NetRestrict.Contains(tcp.IP) { 842 srv.log.Debug("Rejected conn (not whitelisted in NetRestrict)", "addr", fd.RemoteAddr()) 843 fd.Close() 844 slots <- struct{}{} 845 continue 846 } 847 } 848 849 fd = newMeteredConn(fd, true) 850 srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr()) 851 go func() { 852 srv.SetupConn(fd, inboundConn, nil) 853 slots <- struct{}{} 854 }() 855 } 856 } 857 858 //SetupConn运行握手并尝试添加连接 859 //作为同伴。当连接添加为对等时返回 860 //或者握手失败。 861 func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *discover.Node) error { 862 self := srv.Self() 863 if self == nil { 864 return errors.New("shutdown") 865 } 866 c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)} 867 err := srv.setupConn(c, flags, dialDest) 868 if err != nil { 869 c.close(err) 870 srv.log.Trace("Setting up connection failed", "id", c.id, "err", err) 871 } 872 return err 873 } 874 875 func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *discover.Node) error { 876 //防止剩余的挂起conn进入握手。 877 srv.lock.Lock() 878 running := srv.running 879 srv.lock.Unlock() 880 if !running { 881 return errServerStopped 882 } 883 //运行加密握手。 884 var err error 885 if c.id, err = c.doEncHandshake(srv.PrivateKey, dialDest); err != nil { 886 srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) 887 return err 888 } 889 clog := srv.log.New("id", c.id, "addr", c.fd.RemoteAddr(), "conn", c.flags) 890 //对于拨号连接,请检查远程公钥是否匹配。 891 if dialDest != nil && c.id != dialDest.ID { 892 clog.Trace("Dialed identity mismatch", "want", c, dialDest.ID) 893 return DiscUnexpectedIdentity 894 } 895 err = srv.checkpoint(c, srv.posthandshake) 896 if err != nil { 897 clog.Trace("Rejected peer before protocol handshake", "err", err) 898 return err 899 } 900 //运行协议握手 901 phs, err := c.doProtoHandshake(srv.ourHandshake) 902 if err != nil { 903 clog.Trace("Failed proto handshake", "err", err) 904 return err 905 } 906 if phs.ID != c.id { 907 clog.Trace("Wrong devp2p handshake identity", "err", phs.ID) 908 return DiscUnexpectedIdentity 909 } 910 c.caps, c.name = phs.Caps, phs.Name 911 err = srv.checkpoint(c, srv.addpeer) 912 if err != nil { 913 clog.Trace("Rejected peer", "err", err) 914 return err 915 } 916 //如果检查成功完成,runpeer现在已经 917 //由run启动。 918 clog.Trace("connection set up", "inbound", dialDest == nil) 919 return nil 920 } 921 922 func truncateName(s string) string { 923 if len(s) > 20 { 924 return s[:20] + "..." 925 } 926 return s 927 } 928 929 //检查点发送conn运行,它执行 930 //阶段的后握手检查(后握手,addpeer)。 931 func (srv *Server) checkpoint(c *conn, stage chan<- *conn) error { 932 select { 933 case stage <- c: 934 case <-srv.quit: 935 return errServerStopped 936 } 937 select { 938 case err := <-c.cont: 939 return err 940 case <-srv.quit: 941 return errServerStopped 942 } 943 } 944 945 //runpeer为每个对等运行自己的goroutine。 946 //它等待直到对等逻辑返回并删除 947 //同辈。 948 func (srv *Server) runPeer(p *Peer) { 949 if srv.newPeerHook != nil { 950 srv.newPeerHook(p) 951 } 952 953 //广播对等添加 954 srv.peerFeed.Send(&PeerEvent{ 955 Type: PeerEventTypeAdd, 956 Peer: p.ID(), 957 }) 958 959 //运行协议 960 remoteRequested, err := p.run() 961 962 //广播对等丢弃 963 srv.peerFeed.Send(&PeerEvent{ 964 Type: PeerEventTypeDrop, 965 Peer: p.ID(), 966 Error: err.Error(), 967 }) 968 969 //注意:run等待现有对等机在srv.delpeer上发送 970 //返回之前,不应在srv.quit上选择此发送。 971 srv.delpeer <- peerDrop{p, err, remoteRequested} 972 } 973 974 //nodeinfo表示有关主机的已知信息的简短摘要。 975 type NodeInfo struct { 976 ID string `json:"id"` //唯一节点标识符(也是加密密钥) 977 Name string `json:"name"` //节点的名称,包括客户端类型、版本、操作系统、自定义数据 978 Enode string `json:"enode"` //用于从远程对等添加此对等的enode url 979 IP string `json:"ip"` //节点的IP地址 980 Ports struct { 981 Discovery int `json:"discovery"` //发现协议的UDP侦听端口 982 Listener int `json:"listener"` //rlpx的TCP侦听端口 983 } `json:"ports"` 984 ListenAddr string `json:"listenAddr"` 985 Protocols map[string]interface{} `json:"protocols"` 986 } 987 988 // 989 func (srv *Server) NodeInfo() *NodeInfo { 990 node := srv.Self() 991 992 //收集和组装通用节点信息 993 info := &NodeInfo{ 994 Name: srv.Name, 995 Enode: node.String(), 996 ID: node.ID.String(), 997 IP: node.IP.String(), 998 ListenAddr: srv.ListenAddr, 999 Protocols: make(map[string]interface{}), 1000 } 1001 info.Ports.Discovery = int(node.UDP) 1002 info.Ports.Listener = int(node.TCP) 1003 1004 //收集所有正在运行的协议信息(每个协议类型仅一次) 1005 for _, proto := range srv.Protocols { 1006 if _, ok := info.Protocols[proto.Name]; !ok { 1007 nodeInfo := interface{}("unknown") 1008 if query := proto.NodeInfo; query != nil { 1009 nodeInfo = proto.NodeInfo() 1010 } 1011 info.Protocols[proto.Name] = nodeInfo 1012 } 1013 } 1014 return info 1015 } 1016 1017 //PeerSinfo返回描述已连接对等端的元数据对象数组。 1018 func (srv *Server) PeersInfo() []*PeerInfo { 1019 //收集所有通用和子协议特定的信息 1020 infos := make([]*PeerInfo, 0, srv.PeerCount()) 1021 for _, peer := range srv.Peers() { 1022 if peer != nil { 1023 infos = append(infos, peer.Info()) 1024 } 1025 } 1026 //按节点标识符的字母顺序对结果数组排序 1027 for i := 0; i < len(infos); i++ { 1028 for j := i + 1; j < len(infos); j++ { 1029 if infos[i].ID > infos[j].ID { 1030 infos[i], infos[j] = infos[j], infos[i] 1031 } 1032 } 1033 } 1034 return infos 1035 }