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