github.com/luckypickle/go-ethereum-vet@v1.14.2/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 "math/rand" 23 "net" 24 "reflect" 25 "testing" 26 "time" 27 28 "github.com/luckypickle/go-ethereum-vet/crypto" 29 "github.com/luckypickle/go-ethereum-vet/crypto/sha3" 30 "github.com/luckypickle/go-ethereum-vet/log" 31 "github.com/luckypickle/go-ethereum-vet/p2p/discover" 32 ) 33 34 func init() { 35 // log.Root().SetHandler(log.LvlFilterHandler(log.LvlError, log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) 36 } 37 38 type testTransport struct { 39 id discover.NodeID 40 *rlpx 41 42 closeErr error 43 } 44 45 func newTestTransport(id discover.NodeID, fd net.Conn) transport { 46 wrapped := newRLPX(fd).(*rlpx) 47 wrapped.rw = newRLPXFrameRW(fd, secrets{ 48 MAC: zero16, 49 AES: zero16, 50 IngressMAC: sha3.NewKeccak256(), 51 EgressMAC: sha3.NewKeccak256(), 52 }) 53 return &testTransport{id: id, rlpx: wrapped} 54 } 55 56 func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) { 57 return c.id, nil 58 } 59 60 func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 61 return &protoHandshake{ID: c.id, 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, id discover.NodeID, pf func(*Peer)) *Server { 70 config := Config{ 71 Name: "test", 72 MaxPeers: 10, 73 ListenAddr: "127.0.0.1:0", 74 PrivateKey: newkey(), 75 } 76 server := &Server{ 77 Config: config, 78 newPeerHook: pf, 79 newTransport: func(fd net.Conn) transport { return newTestTransport(id, fd) }, 80 } 81 if err := server.Start(); err != nil { 82 t.Fatalf("Could not start server: %v", err) 83 } 84 return server 85 } 86 87 func TestServerListen(t *testing.T) { 88 // start the test server 89 connected := make(chan *Peer) 90 remid := randomID() 91 srv := startTestServer(t, remid, func(p *Peer) { 92 if p.ID() != remid { 93 t.Error("peer func called with wrong node id") 94 } 95 if p == nil { 96 t.Error("peer func called with nil conn") 97 } 98 connected <- p 99 }) 100 defer close(connected) 101 defer srv.Stop() 102 103 // dial the test server 104 conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second) 105 if err != nil { 106 t.Fatalf("could not dial: %v", err) 107 } 108 defer conn.Close() 109 110 select { 111 case peer := <-connected: 112 if peer.LocalAddr().String() != conn.RemoteAddr().String() { 113 t.Errorf("peer started with wrong conn: got %v, want %v", 114 peer.LocalAddr(), conn.RemoteAddr()) 115 } 116 peers := srv.Peers() 117 if !reflect.DeepEqual(peers, []*Peer{peer}) { 118 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 119 } 120 case <-time.After(1 * time.Second): 121 t.Error("server did not accept within one second") 122 } 123 } 124 125 func TestServerDial(t *testing.T) { 126 // run a one-shot TCP server to handle the connection. 127 listener, err := net.Listen("tcp", "127.0.0.1:0") 128 if err != nil { 129 t.Fatalf("could not setup listener: %v", err) 130 } 131 defer listener.Close() 132 accepted := make(chan net.Conn) 133 go func() { 134 conn, err := listener.Accept() 135 if err != nil { 136 t.Error("accept error:", err) 137 return 138 } 139 accepted <- conn 140 }() 141 142 // start the server 143 connected := make(chan *Peer) 144 remid := randomID() 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 := &discover.Node{ID: remid, IP: tcpAddr.IP, TCP: uint16(tcpAddr.Port)} 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() != 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 tasks generated by dialstate are 207 // actually executed and taskdone is called for them. 208 func TestServerTaskScheduling(t *testing.T) { 209 var ( 210 done = make(chan *testTask) 211 quit, returned = make(chan struct{}), make(chan struct{}) 212 tc = 0 213 tg = taskgen{ 214 newFunc: func(running int, peers map[discover.NodeID]*Peer) []task { 215 tc++ 216 return []task{&testTask{index: tc - 1}} 217 }, 218 doneFunc: func(t task) { 219 select { 220 case done <- t.(*testTask): 221 case <-quit: 222 } 223 }, 224 } 225 ) 226 227 // The Server in this test isn't actually running 228 // because we're only interested in what run does. 229 srv := &Server{ 230 Config: Config{MaxPeers: 10}, 231 quit: make(chan struct{}), 232 ntab: fakeTable{}, 233 running: true, 234 log: log.New(), 235 } 236 srv.loopWG.Add(1) 237 go func() { 238 srv.run(tg) 239 close(returned) 240 }() 241 242 var gotdone []*testTask 243 for i := 0; i < 100; i++ { 244 gotdone = append(gotdone, <-done) 245 } 246 for i, task := range gotdone { 247 if task.index != i { 248 t.Errorf("task %d has wrong index, got %d", i, task.index) 249 break 250 } 251 if !task.called { 252 t.Errorf("task %d was not called", i) 253 break 254 } 255 } 256 257 close(quit) 258 srv.Stop() 259 select { 260 case <-returned: 261 case <-time.After(500 * time.Millisecond): 262 t.Error("Server.run did not return within 500ms") 263 } 264 } 265 266 // This test checks that Server doesn't drop tasks, 267 // even if newTasks returns more than the maximum number of tasks. 268 func TestServerManyTasks(t *testing.T) { 269 alltasks := make([]task, 300) 270 for i := range alltasks { 271 alltasks[i] = &testTask{index: i} 272 } 273 274 var ( 275 srv = &Server{ 276 quit: make(chan struct{}), 277 ntab: fakeTable{}, 278 running: true, 279 log: log.New(), 280 } 281 done = make(chan *testTask) 282 start, end = 0, 0 283 ) 284 defer srv.Stop() 285 srv.loopWG.Add(1) 286 go srv.run(taskgen{ 287 newFunc: func(running int, peers map[discover.NodeID]*Peer) []task { 288 start, end = end, end+maxActiveDialTasks+10 289 if end > len(alltasks) { 290 end = len(alltasks) 291 } 292 return alltasks[start:end] 293 }, 294 doneFunc: func(tt task) { 295 done <- tt.(*testTask) 296 }, 297 }) 298 299 doneset := make(map[int]bool) 300 timeout := time.After(2 * time.Second) 301 for len(doneset) < len(alltasks) { 302 select { 303 case tt := <-done: 304 if doneset[tt.index] { 305 t.Errorf("task %d got done more than once", tt.index) 306 } else { 307 doneset[tt.index] = true 308 } 309 case <-timeout: 310 t.Errorf("%d of %d tasks got done within 2s", len(doneset), len(alltasks)) 311 for i := 0; i < len(alltasks); i++ { 312 if !doneset[i] { 313 t.Logf("task %d not done", i) 314 } 315 } 316 return 317 } 318 } 319 } 320 321 type taskgen struct { 322 newFunc func(running int, peers map[discover.NodeID]*Peer) []task 323 doneFunc func(task) 324 } 325 326 func (tg taskgen) newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task { 327 return tg.newFunc(running, peers) 328 } 329 func (tg taskgen) taskDone(t task, now time.Time) { 330 tg.doneFunc(t) 331 } 332 func (tg taskgen) addStatic(*discover.Node) { 333 } 334 func (tg taskgen) removeStatic(*discover.Node) { 335 } 336 337 type testTask struct { 338 index int 339 called bool 340 } 341 342 func (t *testTask) Do(srv *Server) { 343 t.called = true 344 } 345 346 // This test checks that connections are disconnected 347 // just after the encryption handshake when the server is 348 // at capacity. Trusted connections should still be accepted. 349 func TestServerAtCap(t *testing.T) { 350 trustedID := randomID() 351 srv := &Server{ 352 Config: Config{ 353 PrivateKey: newkey(), 354 MaxPeers: 10, 355 NoDial: true, 356 TrustedNodes: []*discover.Node{{ID: trustedID}}, 357 }, 358 } 359 if err := srv.Start(); err != nil { 360 t.Fatalf("could not start: %v", err) 361 } 362 defer srv.Stop() 363 364 newconn := func(id discover.NodeID) *conn { 365 fd, _ := net.Pipe() 366 tx := newTestTransport(id, fd) 367 return &conn{fd: fd, transport: tx, flags: inboundConn, id: id, cont: make(chan error)} 368 } 369 370 // Inject a few connections to fill up the peer set. 371 for i := 0; i < 10; i++ { 372 c := newconn(randomID()) 373 if err := srv.checkpoint(c, srv.addpeer); err != nil { 374 t.Fatalf("could not add conn %d: %v", i, err) 375 } 376 } 377 // Try inserting a non-trusted connection. 378 anotherID := randomID() 379 c := newconn(anotherID) 380 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 381 t.Error("wrong error for insert:", err) 382 } 383 // Try inserting a trusted connection. 384 c = newconn(trustedID) 385 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 386 t.Error("unexpected error for trusted conn @posthandshake:", err) 387 } 388 if !c.is(trustedConn) { 389 t.Error("Server did not set trusted flag") 390 } 391 392 // Remove from trusted set and try again 393 srv.RemoveTrustedPeer(&discover.Node{ID: trustedID}) 394 c = newconn(trustedID) 395 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 396 t.Error("wrong error for insert:", err) 397 } 398 399 // Add anotherID to trusted set and try again 400 srv.AddTrustedPeer(&discover.Node{ID: anotherID}) 401 c = newconn(anotherID) 402 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 403 t.Error("unexpected error for trusted conn @posthandshake:", err) 404 } 405 if !c.is(trustedConn) { 406 t.Error("Server did not set trusted flag") 407 } 408 } 409 410 func TestServerPeerLimits(t *testing.T) { 411 srvkey := newkey() 412 413 clientid := randomID() 414 clientnode := &discover.Node{ID: clientid} 415 416 var tp *setupTransport = &setupTransport{ 417 id: clientid, 418 phs: &protoHandshake{ 419 ID: clientid, 420 // Force "DiscUselessPeer" due to unmatching caps 421 // Caps: []Cap{discard.cap()}, 422 }, 423 } 424 var flags connFlag = dynDialedConn 425 var dialDest *discover.Node = &discover.Node{ID: clientid} 426 427 srv := &Server{ 428 Config: Config{ 429 PrivateKey: srvkey, 430 MaxPeers: 0, 431 NoDial: true, 432 Protocols: []Protocol{discard}, 433 }, 434 newTransport: func(fd net.Conn) transport { return tp }, 435 log: log.New(), 436 } 437 if err := srv.Start(); err != nil { 438 t.Fatalf("couldn't start server: %v", err) 439 } 440 defer srv.Stop() 441 442 // Check that server is full (MaxPeers=0) 443 conn, _ := net.Pipe() 444 srv.SetupConn(conn, flags, dialDest) 445 if tp.closeErr != DiscTooManyPeers { 446 t.Errorf("unexpected close error: %q", tp.closeErr) 447 } 448 conn.Close() 449 450 srv.AddTrustedPeer(clientnode) 451 452 // Check that server allows a trusted peer despite being full. 453 conn, _ = net.Pipe() 454 srv.SetupConn(conn, flags, dialDest) 455 if tp.closeErr == DiscTooManyPeers { 456 t.Errorf("failed to bypass MaxPeers with trusted node: %q", tp.closeErr) 457 } 458 459 if tp.closeErr != DiscUselessPeer { 460 t.Errorf("unexpected close error: %q", tp.closeErr) 461 } 462 conn.Close() 463 464 srv.RemoveTrustedPeer(clientnode) 465 466 // Check that server is full again. 467 conn, _ = net.Pipe() 468 srv.SetupConn(conn, flags, dialDest) 469 if tp.closeErr != DiscTooManyPeers { 470 t.Errorf("unexpected close error: %q", tp.closeErr) 471 } 472 conn.Close() 473 } 474 475 func TestServerSetupConn(t *testing.T) { 476 id := randomID() 477 srvkey := newkey() 478 srvid := discover.PubkeyID(&srvkey.PublicKey) 479 tests := []struct { 480 dontstart bool 481 tt *setupTransport 482 flags connFlag 483 dialDest *discover.Node 484 485 wantCloseErr error 486 wantCalls string 487 }{ 488 { 489 dontstart: true, 490 tt: &setupTransport{id: id}, 491 wantCalls: "close,", 492 wantCloseErr: errServerStopped, 493 }, 494 { 495 tt: &setupTransport{id: id, encHandshakeErr: errors.New("read error")}, 496 flags: inboundConn, 497 wantCalls: "doEncHandshake,close,", 498 wantCloseErr: errors.New("read error"), 499 }, 500 { 501 tt: &setupTransport{id: id}, 502 dialDest: &discover.Node{ID: randomID()}, 503 flags: dynDialedConn, 504 wantCalls: "doEncHandshake,close,", 505 wantCloseErr: DiscUnexpectedIdentity, 506 }, 507 { 508 tt: &setupTransport{id: id, phs: &protoHandshake{ID: randomID()}}, 509 dialDest: &discover.Node{ID: id}, 510 flags: dynDialedConn, 511 wantCalls: "doEncHandshake,doProtoHandshake,close,", 512 wantCloseErr: DiscUnexpectedIdentity, 513 }, 514 { 515 tt: &setupTransport{id: id, protoHandshakeErr: errors.New("foo")}, 516 dialDest: &discover.Node{ID: id}, 517 flags: dynDialedConn, 518 wantCalls: "doEncHandshake,doProtoHandshake,close,", 519 wantCloseErr: errors.New("foo"), 520 }, 521 { 522 tt: &setupTransport{id: srvid, phs: &protoHandshake{ID: srvid}}, 523 flags: inboundConn, 524 wantCalls: "doEncHandshake,close,", 525 wantCloseErr: DiscSelf, 526 }, 527 { 528 tt: &setupTransport{id: id, phs: &protoHandshake{ID: id}}, 529 flags: inboundConn, 530 wantCalls: "doEncHandshake,doProtoHandshake,close,", 531 wantCloseErr: DiscUselessPeer, 532 }, 533 } 534 535 for i, test := range tests { 536 srv := &Server{ 537 Config: Config{ 538 PrivateKey: srvkey, 539 MaxPeers: 10, 540 NoDial: true, 541 Protocols: []Protocol{discard}, 542 }, 543 newTransport: func(fd net.Conn) transport { return test.tt }, 544 log: log.New(), 545 } 546 if !test.dontstart { 547 if err := srv.Start(); err != nil { 548 t.Fatalf("couldn't start server: %v", err) 549 } 550 } 551 p1, _ := net.Pipe() 552 srv.SetupConn(p1, test.flags, test.dialDest) 553 if !reflect.DeepEqual(test.tt.closeErr, test.wantCloseErr) { 554 t.Errorf("test %d: close error mismatch: got %q, want %q", i, test.tt.closeErr, test.wantCloseErr) 555 } 556 if test.tt.calls != test.wantCalls { 557 t.Errorf("test %d: calls mismatch: got %q, want %q", i, test.tt.calls, test.wantCalls) 558 } 559 } 560 } 561 562 type setupTransport struct { 563 id discover.NodeID 564 encHandshakeErr error 565 566 phs *protoHandshake 567 protoHandshakeErr error 568 569 calls string 570 closeErr error 571 } 572 573 func (c *setupTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) { 574 c.calls += "doEncHandshake," 575 return c.id, c.encHandshakeErr 576 } 577 func (c *setupTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 578 c.calls += "doProtoHandshake," 579 if c.protoHandshakeErr != nil { 580 return nil, c.protoHandshakeErr 581 } 582 return c.phs, nil 583 } 584 func (c *setupTransport) close(err error) { 585 c.calls += "close," 586 c.closeErr = err 587 } 588 589 // setupConn shouldn't write to/read from the connection. 590 func (c *setupTransport) WriteMsg(Msg) error { 591 panic("WriteMsg called on setupTransport") 592 } 593 func (c *setupTransport) ReadMsg() (Msg, error) { 594 panic("ReadMsg called on setupTransport") 595 } 596 597 func newkey() *ecdsa.PrivateKey { 598 key, err := crypto.GenerateKey() 599 if err != nil { 600 panic("couldn't generate key: " + err.Error()) 601 } 602 return key 603 } 604 605 func randomID() (id discover.NodeID) { 606 for i := range id { 607 id[i] = byte(rand.Intn(255)) 608 } 609 return id 610 }