github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/vntp2p/server.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt 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-vnt 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-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vntp2p 18 19 import ( 20 "context" 21 "crypto/ecdsa" 22 "errors" 23 "fmt" 24 "net" 25 "sync" 26 27 libp2p "github.com/libp2p/go-libp2p" 28 p2phost "github.com/libp2p/go-libp2p-host" 29 inet "github.com/libp2p/go-libp2p-net" 30 protocol "github.com/libp2p/go-libp2p-protocol" 31 "github.com/vntchain/go-vnt/event" 32 "github.com/vntchain/go-vnt/log" 33 34 // inet "github.com/libp2p/go-libp2p-net" 35 peer "github.com/libp2p/go-libp2p-peer" 36 peerstore "github.com/libp2p/go-libp2p-peerstore" 37 ma "github.com/multiformats/go-multiaddr" 38 // kb "github.com/libp2p/go-libp2p-kbucket" 39 ) 40 41 const ( 42 maxActiveDialTasks = 16 43 defaultDialRatio = 3 44 ) 45 46 var errServerStopped = errors.New("server stopped") 47 48 type dialFlag int 49 50 const ( 51 dynDialedDail dialFlag = 1 << iota 52 staticDialedDail 53 ) 54 55 type Config struct { 56 PrivateKey *ecdsa.PrivateKey `toml:"-"` 57 MaxPeers int 58 MaxPendingPeers int `toml:",omitempty"` 59 DialRatio int `toml:",omitempty"` 60 NoDiscovery bool 61 Name string `toml:"-"` 62 63 BootstrapNodes []*Node 64 StaticNodes []*Node 65 TrustedNodes []*Node 66 67 NetRestrict []*net.IPNet `toml:",omitempty"` 68 NodeDatabase string `toml:",omitempty"` 69 Protocols []Protocol `toml:"-"` 70 ListenAddr string 71 NAT libp2p.Option `toml:"-"` 72 // Dialer NodeDialer `toml:"-"` 73 // NoDial bool `toml:",omitempty"` 74 75 EnableMsgEvents bool 76 Logger log.Logger `toml:",omitempty"` 77 } 78 79 type Server struct { 80 Config 81 table DhtTable 82 host p2phost.Host 83 running bool 84 85 peerFeed event.Feed 86 loopWG sync.WaitGroup 87 cancel context.CancelFunc 88 89 lock sync.Mutex 90 91 quit chan struct{} 92 addstatic chan *Node 93 removestatic chan *Node 94 95 addpeer chan *Stream 96 delpeer chan peerDrop 97 98 peerOp chan peerOpFunc 99 peerOpDone chan struct{} 100 101 protomap map[string][]Protocol 102 } 103 104 type peerOpFunc func(map[peer.ID]*Peer) 105 106 // func NewServer() (*Server, error) { 107 // return newServer() 108 // } 109 110 // func newServer() (*Server, error) { 111 // return &Server{}, nil 112 // } 113 114 type peerDrop struct { 115 *Peer 116 err error 117 requested bool // true if signaled by the peer 118 } 119 120 // close server.quit to broadcast the server shutdown 121 func (server *Server) Close() { 122 log.Info("P2P server is being closed...") 123 close(server.quit) 124 } 125 126 func (server *Server) Start() error { 127 log.Trace("P2P server starting...", "protocols", server.Protocols) 128 if server.running { 129 return errors.New("server already running") 130 } 131 132 server.lock.Lock() 133 defer server.lock.Unlock() 134 135 server.addpeer = make(chan *Stream) 136 server.delpeer = make(chan peerDrop) 137 server.addstatic = make(chan *Node) 138 server.removestatic = make(chan *Node) 139 server.quit = make(chan struct{}) 140 server.peerOp = make(chan peerOpFunc) 141 server.peerOpDone = make(chan struct{}) 142 143 // 协议映射初始化 144 server.protomap = make(map[string][]Protocol) 145 146 server.protomap[PID] = server.Protocols 147 148 // Listen 149 // run 150 if server.ListenAddr == "" { 151 return fmt.Errorf("P2P Server can't start for no listening") 152 } 153 154 listenPort := server.Config.ListenAddr[1:] 155 ctx, cancel := context.WithCancel(context.Background()) 156 server.cancel = cancel 157 158 d := server.NodeDatabase 159 vdht, host, err := ConstructDHT(ctx, MakePort(listenPort), nil, d, server.Config.NetRestrict, server.Config.NAT) 160 if err != nil { 161 log.Error("ConstructDHT failed", "error", err) 162 return err 163 } 164 165 // setStreamHandler can only handle request message 166 // it can not hear response 167 host.SetStreamHandler(PID, server.HandleStream) 168 169 server.table = NewDHTTable(vdht, host.ID()) 170 server.host = host 171 172 bootnodes := server.LoadConfig(ctx) 173 174 maxdials := server.maxDialedConns() 175 176 taskState := newTaskState(maxdials, bootnodes, server.table) 177 178 server.loopWG.Add(1) 179 go server.run(ctx, taskState) 180 181 server.running = true 182 return nil 183 } 184 185 func (server *Server) LoadConfig(ctx context.Context) []peer.ID { 186 // 创建初始连接 187 188 bootnodes := []peer.ID{} 189 190 for _, bootnode := range server.Config.BootstrapNodes { 191 server.host.Peerstore().AddAddrs(bootnode.Id, []ma.Multiaddr{bootnode.Addr}, peerstore.PermanentAddrTTL) 192 _ = server.table.Update(ctx, bootnode.Id) 193 194 bootnodes = append(bootnodes, bootnode.Id) 195 } 196 197 return bootnodes 198 199 } 200 201 func (server *Server) run(ctx context.Context, tasker taskworker) { 202 // run the blacklist daemon to handle mismatched peers 203 go blacklist.run() 204 205 defer server.loopWG.Done() 206 _ = server.table.Start(ctx) 207 var ( 208 runningTasks []task 209 queuedTasks []task 210 taskdone = make(chan task, maxActiveDialTasks) 211 peers = make(map[peer.ID]*Peer) 212 ) 213 214 delTask := func(t task) { 215 for i := range runningTasks { 216 if runningTasks[i] == t { 217 runningTasks = append(runningTasks[:i], runningTasks[i+1:]...) 218 break 219 } 220 } 221 } 222 startTasks := func(ts []task) (rest []task) { 223 i := 0 224 for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ { 225 t := ts[i] 226 go func() { t.Do(ctx, server); taskdone <- t }() 227 runningTasks = append(runningTasks, t) 228 } 229 return ts[i:] 230 } 231 scheduleTasks := func() { 232 queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...) 233 if len(runningTasks) < maxActiveDialTasks { 234 // fmt.Println("begin new task") 235 nt := tasker.newTasks(peers) 236 queuedTasks = append(queuedTasks, startTasks(nt)...) 237 } 238 } 239 240 for { 241 scheduleTasks() 242 243 select { 244 case t := <-taskdone: 245 tasker.taskDone(t) 246 delTask(t) 247 248 case t := <-server.addpeer: 249 remoteID := t.stream.Conn().RemotePeer() 250 log.Debug("Adding peer", "peer id", remoteID) 251 if p, ok := peers[remoteID]; ok { 252 p.log.Debug("Already exist peer") 253 break 254 } 255 p := newPeer(t, server) 256 257 if server.EnableMsgEvents { 258 p.events = &server.peerFeed 259 } 260 go server.runPeer(p) 261 peers[p.RemoteID()] = p 262 p.log.Debug("Added peer", "peers", peers) 263 264 case t := <-server.addstatic: 265 log.Debug("Adding static", "peer id", t.Id) 266 tasker.addStatic(t) 267 log.Debug("Added static", "peer id", t.Id) 268 case t := <-server.removestatic: 269 tasker.removeStatic(t) 270 if p, ok := peers[t.Id]; ok { 271 p.Disconnect(DiscRequested) 272 } 273 274 case op := <-server.peerOp: 275 // This channel is used by Peers and PeerCount. 276 op(peers) 277 server.peerOpDone <- struct{}{} 278 279 case pd := <-server.delpeer: 280 // A peer disconnected. 281 pid := pd.RemoteID() 282 log.Info("Removing p2p peer", "peer", pid.ToString(), "error", pd.err) 283 if _, ok := peers[pid]; ok { 284 delete(peers, pid) 285 } 286 } 287 } 288 } 289 290 func (server *Server) Stop() { 291 log.Info("Server is Stopping!") 292 defer server.cancel() 293 } 294 295 func (server *Server) AddPeer(ctx context.Context, node *Node) { 296 if blacklist.exists(node.Id) { 297 log.Trace("node is blacklisted", "pid", node.Id) 298 return 299 } 300 server.host.Peerstore().AddAddrs(node.Id, []ma.Multiaddr{node.Addr}, peerstore.PermanentAddrTTL) 301 _ = server.table.Update(ctx, node.Id) 302 303 select { 304 case <-server.quit: 305 case server.addstatic <- node: 306 } 307 } 308 309 func (server *Server) RemovePeer(node *Node) { 310 select { 311 case <-server.quit: 312 case server.removestatic <- node: 313 } 314 } 315 316 func (server *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { 317 return server.peerFeed.Subscribe(ch) 318 } 319 320 func (server *Server) PeersInfo() []*PeerInfo { 321 infos := make([]*PeerInfo, 0, server.PeerCount()) 322 323 for _, peer := range server.Peers() { 324 if peer != nil { 325 infos = append(infos, peer.Info()) 326 } 327 } 328 for i := 0; i < len(infos); i++ { 329 for j := i + 1; j < len(infos); j++ { 330 if infos[i].ID > infos[j].ID { 331 infos[i], infos[j] = infos[j], infos[i] 332 } 333 } 334 } 335 return infos 336 } 337 338 func (server *Server) Self() *Node { 339 server.lock.Lock() 340 defer server.lock.Unlock() 341 342 if !server.running { 343 return &Node{} 344 } 345 346 // hostAddr, _ := ma.NewMultiaddr(fmt.Sprintf("/ipfs/%s", server.host.ID().Pretty())) 347 348 addr := server.host.Addrs()[0] 349 // fullAddr := addr.Encapsulate(hostAddr) 350 351 return &Node{Addr: addr, Id: server.host.ID()} 352 } 353 354 // GetPeerByRemoteID get specific peer by remoteID 355 // if it doesn't exist, new it 356 // this function guarantee get the wanted peer 357 func (server *Server) GetPeerByRemoteID(s inet.Stream) *Peer { 358 var p *Peer 359 360 // always try to new this peer 361 err := server.dispatch(&Stream{stream: s, Protocols: server.protomap[PID]}, server.addpeer) 362 if err != nil { 363 log.Error("GetPeerByRemoteID()", "new peer error", err) 364 return nil 365 } 366 367 select { 368 case <-server.quit: 369 case server.peerOp <- func(peers map[peer.ID]*Peer) { 370 remoteID := s.Conn().RemotePeer() 371 if val, ok := peers[remoteID]; ok { 372 p = val 373 } 374 }: 375 <-server.peerOpDone 376 } 377 378 pid := s.Conn().RemotePeer() 379 log.Debug("Got peer by remote id", "peerid", pid, "peer got", p) 380 381 return p 382 } 383 384 func (server *Server) Peers() []*Peer { 385 var ps []*Peer 386 select { 387 case <-server.quit: 388 case server.peerOp <- func(peers map[peer.ID]*Peer) { 389 for _, p := range peers { 390 ps = append(ps, p) 391 } 392 }: 393 <-server.peerOpDone 394 } 395 return ps 396 } 397 398 func (server *Server) PeerCount() int { 399 var count int 400 select { 401 case <-server.quit: 402 case server.peerOp <- func(ps map[peer.ID]*Peer) { count = len(ps) }: 403 <-server.peerOpDone 404 } 405 return count 406 } 407 408 func (server *Server) maxDialedConns() int { 409 r := server.DialRatio 410 if r == 0 { 411 r = defaultDialRatio 412 } 413 return server.MaxPeers / r 414 } 415 416 // SetupStream 主动发起连接 417 func (server *Server) SetupStream(ctx context.Context, target peer.ID, pid string) error { 418 s, err := server.host.NewStream(ctx, target, protocol.ID(pid)) 419 if err != nil { 420 // fmt.Println("SetupStream NewStream Error: ", err) 421 return err 422 } 423 424 // handle response message 425 go server.HandleStream(s) 426 /* rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s)) 427 vntMessenger := &VNTMsger{ 428 protocol: Protocol{}, 429 in: make(chan Msg), 430 w: rw, 431 } 432 433 their, err := doProtocolHandshake(vntMessenger, server.ourHandshake) 434 if err != nil { 435 log.Error("SetupStream()", "failed protocolHandshake", err) 436 return err 437 } */ 438 439 err = server.dispatch(&Stream{stream: s, Protocols: server.protomap[pid]}, server.addpeer) 440 if err != nil { 441 fmt.Println("SetupStream dispatch Error: ", err) 442 return err 443 } 444 return nil 445 } 446 447 func (server *Server) runPeer(p *Peer) { 448 // broadcast peer add 449 server.peerFeed.Send(&PeerEvent{ 450 Type: PeerEventTypeAdd, 451 Peer: p.RemoteID(), 452 }) 453 454 // run the protocol 455 remoteRequested, err := p.run() 456 if err != nil { 457 log.Debug("Run peer failed", "peer id", p.RemoteID(), "peer addr", p.RemoteAddr()) 458 } 459 460 // broadcast peer drop 461 server.peerFeed.Send(&PeerEvent{ 462 Type: PeerEventTypeDrop, 463 Peer: p.RemoteID(), 464 Error: err.Error(), 465 }) 466 467 // Note: run waits for existing peers to be sent on srv.delpeer 468 // before returning, so this send should not select on srv.quit. 469 server.delpeer <- peerDrop{p, err, remoteRequested} 470 } 471 472 func (server *Server) dispatch(s *Stream, stage chan<- *Stream) error { 473 select { 474 case <-server.quit: 475 return errServerStopped 476 case stage <- s: 477 } 478 return nil 479 } 480 481 type NodeInfo struct { 482 ID string `json:"id"` // Unique node identifier (also the encryption key) 483 Name string `json:"name"` // Name of the node, including client type, version, OS, custom data 484 VNTNode string `json:"vnode"` // Vnode URL for adding this peer from remote peers 485 IP string `json:"ip"` // IP address of the node 486 Ports struct { 487 Discovery int `json:"discovery"` // UDP listening port for discovery protocol 488 Listener int `json:"listener"` // TCP listening port for RLPx 489 } `json:"ports"` 490 ListenAddr string `json:"listenAddr"` 491 Protocols map[string]interface{} `json:"protocols"` 492 } 493 494 func (server *Server) NodeInfo() *NodeInfo { 495 node := server.Self() 496 497 info := &NodeInfo{ 498 ID: node.Id.ToString(), 499 VNTNode: node.String(), 500 Name: server.Name, 501 IP: GetIPfromAddr(node.Addr), 502 ListenAddr: server.ListenAddr, 503 Protocols: make(map[string]interface{}), 504 } 505 506 // for _, proto := range server.Protocols { 507 // if _, ok := info.Protocols[proto.Name]; !ok { 508 // nodeInfo := interface{}("unknown") 509 // if query := proto.NodeInfo; query != nil { 510 // nodeInfo = proto.NodeInfo() 511 // } 512 // info.Protocols[proto.Name] = nodeInfo 513 // } 514 // } 515 return info 516 } 517 518 type taskworker interface { 519 newTasks(map[peer.ID]*Peer) []task 520 addStatic(n *Node) 521 removeStatic(n *Node) 522 taskDone(t task) 523 }