github.com/JFJun/bsc@v1.0.0/p2p/server_test.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 18 19 import ( 20 "crypto/ecdsa" 21 "errors" 22 "io" 23 "math/rand" 24 "net" 25 "reflect" 26 "testing" 27 "time" 28 29 "github.com/JFJun/bsc/crypto" 30 "github.com/JFJun/bsc/internal/testlog" 31 "github.com/JFJun/bsc/log" 32 "github.com/JFJun/bsc/p2p/enode" 33 "github.com/JFJun/bsc/p2p/enr" 34 "golang.org/x/crypto/sha3" 35 ) 36 37 type testTransport struct { 38 rpub *ecdsa.PublicKey 39 *rlpx 40 41 closeErr error 42 } 43 44 func newTestTransport(rpub *ecdsa.PublicKey, fd net.Conn) transport { 45 wrapped := newRLPX(fd).(*rlpx) 46 wrapped.rw = newRLPXFrameRW(fd, secrets{ 47 MAC: zero16, 48 AES: zero16, 49 IngressMAC: sha3.NewLegacyKeccak256(), 50 EgressMAC: sha3.NewLegacyKeccak256(), 51 }) 52 return &testTransport{rpub: rpub, rlpx: wrapped} 53 } 54 55 func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) { 56 return c.rpub, nil 57 } 58 59 func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 60 pubkey := crypto.FromECDSAPub(c.rpub)[1:] 61 return &protoHandshake{ID: pubkey, Name: "test"}, nil 62 } 63 64 func (c *testTransport) close(err error) { 65 c.rlpx.fd.Close() 66 c.closeErr = err 67 } 68 69 func startTestServer(t *testing.T, remoteKey *ecdsa.PublicKey, pf func(*Peer)) *Server { 70 config := Config{ 71 Name: "test", 72 MaxPeers: 10, 73 ListenAddr: "127.0.0.1:0", 74 NoDiscovery: true, 75 PrivateKey: newkey(), 76 Logger: testlog.Logger(t, log.LvlTrace), 77 } 78 server := &Server{ 79 Config: config, 80 newPeerHook: pf, 81 newTransport: func(fd net.Conn) transport { return newTestTransport(remoteKey, fd) }, 82 } 83 if err := server.Start(); err != nil { 84 t.Fatalf("Could not start server: %v", err) 85 } 86 return server 87 } 88 89 func TestServerListen(t *testing.T) { 90 // start the test server 91 connected := make(chan *Peer) 92 remid := &newkey().PublicKey 93 srv := startTestServer(t, remid, func(p *Peer) { 94 if p.ID() != enode.PubkeyToIDV4(remid) { 95 t.Error("peer func called with wrong node id") 96 } 97 connected <- p 98 }) 99 defer close(connected) 100 defer srv.Stop() 101 102 // dial the test server 103 conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second) 104 if err != nil { 105 t.Fatalf("could not dial: %v", err) 106 } 107 defer conn.Close() 108 109 select { 110 case peer := <-connected: 111 if peer.LocalAddr().String() != conn.RemoteAddr().String() { 112 t.Errorf("peer started with wrong conn: got %v, want %v", 113 peer.LocalAddr(), conn.RemoteAddr()) 114 } 115 peers := srv.Peers() 116 if !reflect.DeepEqual(peers, []*Peer{peer}) { 117 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 118 } 119 case <-time.After(1 * time.Second): 120 t.Error("server did not accept within one second") 121 } 122 } 123 124 func TestServerDial(t *testing.T) { 125 // run a one-shot TCP server to handle the connection. 126 listener, err := net.Listen("tcp", "127.0.0.1:0") 127 if err != nil { 128 t.Fatalf("could not setup listener: %v", err) 129 } 130 defer listener.Close() 131 accepted := make(chan net.Conn, 1) 132 go func() { 133 conn, err := listener.Accept() 134 if err != nil { 135 return 136 } 137 accepted <- conn 138 }() 139 140 // start the server 141 connected := make(chan *Peer) 142 remid := &newkey().PublicKey 143 srv := startTestServer(t, remid, func(p *Peer) { connected <- p }) 144 defer close(connected) 145 defer srv.Stop() 146 147 // tell the server to connect 148 tcpAddr := listener.Addr().(*net.TCPAddr) 149 node := enode.NewV4(remid, tcpAddr.IP, tcpAddr.Port, 0) 150 srv.AddPeer(node) 151 152 select { 153 case conn := <-accepted: 154 defer conn.Close() 155 156 select { 157 case peer := <-connected: 158 if peer.ID() != enode.PubkeyToIDV4(remid) { 159 t.Errorf("peer has wrong id") 160 } 161 if peer.Name() != "test" { 162 t.Errorf("peer has wrong name") 163 } 164 if peer.RemoteAddr().String() != conn.LocalAddr().String() { 165 t.Errorf("peer started with wrong conn: got %v, want %v", 166 peer.RemoteAddr(), conn.LocalAddr()) 167 } 168 peers := srv.Peers() 169 if !reflect.DeepEqual(peers, []*Peer{peer}) { 170 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 171 } 172 173 // Test AddTrustedPeer/RemoveTrustedPeer and changing Trusted flags 174 // Particularly for race conditions on changing the flag state. 175 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 176 t.Errorf("peer is trusted prematurely: %v", peer) 177 } 178 done := make(chan bool) 179 go func() { 180 srv.AddTrustedPeer(node) 181 if peer := srv.Peers()[0]; !peer.Info().Network.Trusted { 182 t.Errorf("peer is not trusted after AddTrustedPeer: %v", peer) 183 } 184 srv.RemoveTrustedPeer(node) 185 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 186 t.Errorf("peer is trusted after RemoveTrustedPeer: %v", peer) 187 } 188 done <- true 189 }() 190 // Trigger potential race conditions 191 peer = srv.Peers()[0] 192 _ = peer.Inbound() 193 _ = peer.Info() 194 <-done 195 case <-time.After(1 * time.Second): 196 t.Error("server did not launch peer within one second") 197 } 198 199 case <-time.After(1 * time.Second): 200 t.Error("server did not connect within one second") 201 } 202 } 203 204 // This test checks that RemovePeer disconnects the peer if it is connected. 205 func TestServerRemovePeerDisconnect(t *testing.T) { 206 srv1 := &Server{Config: Config{ 207 PrivateKey: newkey(), 208 MaxPeers: 1, 209 NoDiscovery: true, 210 Logger: testlog.Logger(t, log.LvlTrace).New("server", "1"), 211 }} 212 srv2 := &Server{Config: Config{ 213 PrivateKey: newkey(), 214 MaxPeers: 1, 215 NoDiscovery: true, 216 NoDial: true, 217 ListenAddr: "127.0.0.1:0", 218 Logger: testlog.Logger(t, log.LvlTrace).New("server", "2"), 219 }} 220 srv1.Start() 221 defer srv1.Stop() 222 srv2.Start() 223 defer srv2.Stop() 224 225 if !syncAddPeer(srv1, srv2.Self()) { 226 t.Fatal("peer not connected") 227 } 228 srv1.RemovePeer(srv2.Self()) 229 if srv1.PeerCount() > 0 { 230 t.Fatal("removed peer still connected") 231 } 232 } 233 234 // This test checks that connections are disconnected just after the encryption handshake 235 // when the server is at capacity. Trusted connections should still be accepted. 236 func TestServerAtCap(t *testing.T) { 237 trustedNode := newkey() 238 trustedID := enode.PubkeyToIDV4(&trustedNode.PublicKey) 239 srv := &Server{ 240 Config: Config{ 241 PrivateKey: newkey(), 242 MaxPeers: 10, 243 NoDial: true, 244 NoDiscovery: true, 245 TrustedNodes: []*enode.Node{newNode(trustedID, "")}, 246 Logger: testlog.Logger(t, log.LvlTrace), 247 }, 248 } 249 if err := srv.Start(); err != nil { 250 t.Fatalf("could not start: %v", err) 251 } 252 defer srv.Stop() 253 254 newconn := func(id enode.ID) *conn { 255 fd, _ := net.Pipe() 256 tx := newTestTransport(&trustedNode.PublicKey, fd) 257 node := enode.SignNull(new(enr.Record), id) 258 return &conn{fd: fd, transport: tx, flags: inboundConn, node: node, cont: make(chan error)} 259 } 260 261 // Inject a few connections to fill up the peer set. 262 for i := 0; i < 10; i++ { 263 c := newconn(randomID()) 264 if err := srv.checkpoint(c, srv.checkpointAddPeer); err != nil { 265 t.Fatalf("could not add conn %d: %v", i, err) 266 } 267 } 268 // Try inserting a non-trusted connection. 269 anotherID := randomID() 270 c := newconn(anotherID) 271 if err := srv.checkpoint(c, srv.checkpointPostHandshake); err != DiscTooManyPeers { 272 t.Error("wrong error for insert:", err) 273 } 274 // Try inserting a trusted connection. 275 c = newconn(trustedID) 276 if err := srv.checkpoint(c, srv.checkpointPostHandshake); err != nil { 277 t.Error("unexpected error for trusted conn @posthandshake:", err) 278 } 279 if !c.is(trustedConn) { 280 t.Error("Server did not set trusted flag") 281 } 282 283 // Remove from trusted set and try again 284 srv.RemoveTrustedPeer(newNode(trustedID, "")) 285 c = newconn(trustedID) 286 if err := srv.checkpoint(c, srv.checkpointPostHandshake); err != DiscTooManyPeers { 287 t.Error("wrong error for insert:", err) 288 } 289 290 // Add anotherID to trusted set and try again 291 srv.AddTrustedPeer(newNode(anotherID, "")) 292 c = newconn(anotherID) 293 if err := srv.checkpoint(c, srv.checkpointPostHandshake); err != nil { 294 t.Error("unexpected error for trusted conn @posthandshake:", err) 295 } 296 if !c.is(trustedConn) { 297 t.Error("Server did not set trusted flag") 298 } 299 } 300 301 func TestServerPeerLimits(t *testing.T) { 302 srvkey := newkey() 303 clientkey := newkey() 304 clientnode := enode.NewV4(&clientkey.PublicKey, nil, 0, 0) 305 306 var tp = &setupTransport{ 307 pubkey: &clientkey.PublicKey, 308 phs: protoHandshake{ 309 ID: crypto.FromECDSAPub(&clientkey.PublicKey)[1:], 310 // Force "DiscUselessPeer" due to unmatching caps 311 // Caps: []Cap{discard.cap()}, 312 }, 313 } 314 315 srv := &Server{ 316 Config: Config{ 317 PrivateKey: srvkey, 318 MaxPeers: 0, 319 NoDial: true, 320 NoDiscovery: true, 321 Protocols: []Protocol{discard}, 322 Logger: testlog.Logger(t, log.LvlTrace), 323 }, 324 newTransport: func(fd net.Conn) transport { return tp }, 325 } 326 if err := srv.Start(); err != nil { 327 t.Fatalf("couldn't start server: %v", err) 328 } 329 defer srv.Stop() 330 331 // Check that server is full (MaxPeers=0) 332 flags := dynDialedConn 333 dialDest := clientnode 334 conn, _ := net.Pipe() 335 srv.SetupConn(conn, flags, dialDest) 336 if tp.closeErr != DiscTooManyPeers { 337 t.Errorf("unexpected close error: %q", tp.closeErr) 338 } 339 conn.Close() 340 341 srv.AddTrustedPeer(clientnode) 342 343 // Check that server allows a trusted peer despite being full. 344 conn, _ = net.Pipe() 345 srv.SetupConn(conn, flags, dialDest) 346 if tp.closeErr == DiscTooManyPeers { 347 t.Errorf("failed to bypass MaxPeers with trusted node: %q", tp.closeErr) 348 } 349 350 if tp.closeErr != DiscUselessPeer { 351 t.Errorf("unexpected close error: %q", tp.closeErr) 352 } 353 conn.Close() 354 355 srv.RemoveTrustedPeer(clientnode) 356 357 // Check that server is full again. 358 conn, _ = net.Pipe() 359 srv.SetupConn(conn, flags, dialDest) 360 if tp.closeErr != DiscTooManyPeers { 361 t.Errorf("unexpected close error: %q", tp.closeErr) 362 } 363 conn.Close() 364 } 365 366 func TestServerSetupConn(t *testing.T) { 367 var ( 368 clientkey, srvkey = newkey(), newkey() 369 clientpub = &clientkey.PublicKey 370 srvpub = &srvkey.PublicKey 371 ) 372 tests := []struct { 373 dontstart bool 374 tt *setupTransport 375 flags connFlag 376 dialDest *enode.Node 377 378 wantCloseErr error 379 wantCalls string 380 }{ 381 { 382 dontstart: true, 383 tt: &setupTransport{pubkey: clientpub}, 384 wantCalls: "close,", 385 wantCloseErr: errServerStopped, 386 }, 387 { 388 tt: &setupTransport{pubkey: clientpub, encHandshakeErr: errors.New("read error")}, 389 flags: inboundConn, 390 wantCalls: "doEncHandshake,close,", 391 wantCloseErr: errors.New("read error"), 392 }, 393 { 394 tt: &setupTransport{pubkey: clientpub}, 395 dialDest: enode.NewV4(&newkey().PublicKey, nil, 0, 0), 396 flags: dynDialedConn, 397 wantCalls: "doEncHandshake,close,", 398 wantCloseErr: DiscUnexpectedIdentity, 399 }, 400 { 401 tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{ID: randomID().Bytes()}}, 402 dialDest: enode.NewV4(clientpub, nil, 0, 0), 403 flags: dynDialedConn, 404 wantCalls: "doEncHandshake,doProtoHandshake,close,", 405 wantCloseErr: DiscUnexpectedIdentity, 406 }, 407 { 408 tt: &setupTransport{pubkey: clientpub, protoHandshakeErr: errors.New("foo")}, 409 dialDest: enode.NewV4(clientpub, nil, 0, 0), 410 flags: dynDialedConn, 411 wantCalls: "doEncHandshake,doProtoHandshake,close,", 412 wantCloseErr: errors.New("foo"), 413 }, 414 { 415 tt: &setupTransport{pubkey: srvpub, phs: protoHandshake{ID: crypto.FromECDSAPub(srvpub)[1:]}}, 416 flags: inboundConn, 417 wantCalls: "doEncHandshake,close,", 418 wantCloseErr: DiscSelf, 419 }, 420 { 421 tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{ID: crypto.FromECDSAPub(clientpub)[1:]}}, 422 flags: inboundConn, 423 wantCalls: "doEncHandshake,doProtoHandshake,close,", 424 wantCloseErr: DiscUselessPeer, 425 }, 426 } 427 428 for i, test := range tests { 429 t.Run(test.wantCalls, func(t *testing.T) { 430 cfg := Config{ 431 PrivateKey: srvkey, 432 MaxPeers: 10, 433 NoDial: true, 434 NoDiscovery: true, 435 Protocols: []Protocol{discard}, 436 Logger: testlog.Logger(t, log.LvlTrace), 437 } 438 srv := &Server{ 439 Config: cfg, 440 newTransport: func(fd net.Conn) transport { return test.tt }, 441 log: cfg.Logger, 442 } 443 if !test.dontstart { 444 if err := srv.Start(); err != nil { 445 t.Fatalf("couldn't start server: %v", err) 446 } 447 defer srv.Stop() 448 } 449 p1, _ := net.Pipe() 450 srv.SetupConn(p1, test.flags, test.dialDest) 451 if !reflect.DeepEqual(test.tt.closeErr, test.wantCloseErr) { 452 t.Errorf("test %d: close error mismatch: got %q, want %q", i, test.tt.closeErr, test.wantCloseErr) 453 } 454 if test.tt.calls != test.wantCalls { 455 t.Errorf("test %d: calls mismatch: got %q, want %q", i, test.tt.calls, test.wantCalls) 456 } 457 }) 458 } 459 } 460 461 type setupTransport struct { 462 pubkey *ecdsa.PublicKey 463 encHandshakeErr error 464 phs protoHandshake 465 protoHandshakeErr error 466 467 calls string 468 closeErr error 469 } 470 471 func (c *setupTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) { 472 c.calls += "doEncHandshake," 473 return c.pubkey, c.encHandshakeErr 474 } 475 476 func (c *setupTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 477 c.calls += "doProtoHandshake," 478 if c.protoHandshakeErr != nil { 479 return nil, c.protoHandshakeErr 480 } 481 return &c.phs, nil 482 } 483 func (c *setupTransport) close(err error) { 484 c.calls += "close," 485 c.closeErr = err 486 } 487 488 // setupConn shouldn't write to/read from the connection. 489 func (c *setupTransport) WriteMsg(Msg) error { 490 panic("WriteMsg called on setupTransport") 491 } 492 func (c *setupTransport) ReadMsg() (Msg, error) { 493 panic("ReadMsg called on setupTransport") 494 } 495 496 func newkey() *ecdsa.PrivateKey { 497 key, err := crypto.GenerateKey() 498 if err != nil { 499 panic("couldn't generate key: " + err.Error()) 500 } 501 return key 502 } 503 504 func randomID() (id enode.ID) { 505 for i := range id { 506 id[i] = byte(rand.Intn(255)) 507 } 508 return id 509 } 510 511 // This test checks that inbound connections are throttled by IP. 512 func TestServerInboundThrottle(t *testing.T) { 513 const timeout = 5 * time.Second 514 newTransportCalled := make(chan struct{}) 515 srv := &Server{ 516 Config: Config{ 517 PrivateKey: newkey(), 518 ListenAddr: "127.0.0.1:0", 519 MaxPeers: 10, 520 NoDial: true, 521 NoDiscovery: true, 522 Protocols: []Protocol{discard}, 523 Logger: testlog.Logger(t, log.LvlTrace), 524 }, 525 newTransport: func(fd net.Conn) transport { 526 newTransportCalled <- struct{}{} 527 return newRLPX(fd) 528 }, 529 listenFunc: func(network, laddr string) (net.Listener, error) { 530 fakeAddr := &net.TCPAddr{IP: net.IP{95, 33, 21, 2}, Port: 4444} 531 return listenFakeAddr(network, laddr, fakeAddr) 532 }, 533 } 534 if err := srv.Start(); err != nil { 535 t.Fatal("can't start: ", err) 536 } 537 defer srv.Stop() 538 539 // Dial the test server. 540 conn, err := net.DialTimeout("tcp", srv.ListenAddr, timeout) 541 if err != nil { 542 t.Fatalf("could not dial: %v", err) 543 } 544 select { 545 case <-newTransportCalled: 546 // OK 547 case <-time.After(timeout): 548 t.Error("newTransport not called") 549 } 550 conn.Close() 551 552 // Dial again. This time the server should close the connection immediately. 553 connClosed := make(chan struct{}, 1) 554 conn, err = net.DialTimeout("tcp", srv.ListenAddr, timeout) 555 if err != nil { 556 t.Fatalf("could not dial: %v", err) 557 } 558 defer conn.Close() 559 go func() { 560 conn.SetDeadline(time.Now().Add(timeout)) 561 buf := make([]byte, 10) 562 if n, err := conn.Read(buf); err != io.EOF || n != 0 { 563 t.Errorf("expected io.EOF and n == 0, got error %q and n == %d", err, n) 564 } 565 connClosed <- struct{}{} 566 }() 567 select { 568 case <-connClosed: 569 // OK 570 case <-newTransportCalled: 571 t.Error("newTransport called for second attempt") 572 case <-time.After(timeout): 573 t.Error("connection not closed within timeout") 574 } 575 } 576 577 func listenFakeAddr(network, laddr string, remoteAddr net.Addr) (net.Listener, error) { 578 l, err := net.Listen(network, laddr) 579 if err == nil { 580 l = &fakeAddrListener{l, remoteAddr} 581 } 582 return l, err 583 } 584 585 // fakeAddrListener is a listener that creates connections with a mocked remote address. 586 type fakeAddrListener struct { 587 net.Listener 588 remoteAddr net.Addr 589 } 590 591 type fakeAddrConn struct { 592 net.Conn 593 remoteAddr net.Addr 594 } 595 596 func (l *fakeAddrListener) Accept() (net.Conn, error) { 597 c, err := l.Listener.Accept() 598 if err != nil { 599 return nil, err 600 } 601 return &fakeAddrConn{c, l.remoteAddr}, nil 602 } 603 604 func (c *fakeAddrConn) RemoteAddr() net.Addr { 605 return c.remoteAddr 606 } 607 608 func syncAddPeer(srv *Server, node *enode.Node) bool { 609 var ( 610 ch = make(chan *PeerEvent) 611 sub = srv.SubscribeEvents(ch) 612 timeout = time.After(2 * time.Second) 613 ) 614 defer sub.Unsubscribe() 615 srv.AddPeer(node) 616 for { 617 select { 618 case ev := <-ch: 619 if ev.Type == PeerEventTypeAdd && ev.Peer == node.ID() { 620 return true 621 } 622 case <-timeout: 623 return false 624 } 625 } 626 }