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