github.com/Finschia/ostracon@v1.1.5/p2p/transport_test.go (about) 1 package p2p 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "net" 8 "reflect" 9 "runtime" 10 "strconv" 11 "strings" 12 "testing" 13 "time" 14 15 tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p" 16 17 "github.com/Finschia/ostracon/crypto/ed25519" 18 "github.com/Finschia/ostracon/libs/protoio" 19 "github.com/Finschia/ostracon/p2p/conn" 20 "github.com/miekg/dns" 21 "github.com/stretchr/testify/require" 22 ) 23 24 var defaultNodeName = "host_peer" 25 26 func emptyNodeInfo() NodeInfo { 27 return DefaultNodeInfo{} 28 } 29 30 // newMultiplexTransport returns a tcp connected multiplexed peer 31 // using the default MConnConfig. It's a convenience function used 32 // for testing. 33 func newMultiplexTransport( 34 nodeInfo NodeInfo, 35 nodeKey NodeKey, 36 ) *MultiplexTransport { 37 return NewMultiplexTransport( 38 nodeInfo, nodeKey, conn.DefaultMConnConfig(), 39 ) 40 } 41 42 func TestTransportMultiplexConnFilter(t *testing.T) { 43 mt := newMultiplexTransport( 44 emptyNodeInfo(), 45 NodeKey{ 46 PrivKey: ed25519.GenPrivKey(), 47 }, 48 ) 49 id := mt.nodeKey.ID() 50 51 MultiplexTransportConnFilters( 52 func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil }, 53 func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil }, 54 func(_ ConnSet, _ net.Conn, _ []net.IP) error { 55 return fmt.Errorf("rejected") 56 }, 57 )(mt) 58 59 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 60 if err != nil { 61 t.Fatal(err) 62 } 63 64 if err := mt.Listen(*addr); err != nil { 65 t.Fatal(err) 66 } 67 68 errc := make(chan error) 69 70 go func() { 71 addr := NewNetAddress(id, mt.listener.Addr()) 72 73 _, err := addr.Dial() 74 if err != nil { 75 errc <- err 76 return 77 } 78 79 close(errc) 80 }() 81 82 if err := <-errc; err != nil { 83 t.Errorf("connection failed: %v", err) 84 } 85 86 _, err = mt.Accept(peerConfig{}) 87 if e, ok := err.(ErrRejected); ok { 88 if !e.IsFiltered() { 89 t.Errorf("expected peer to be filtered, got %v", e) 90 } 91 } else { 92 t.Errorf("expected ErrRejected, got %v", err) 93 } 94 } 95 96 func TestTransportMultiplexConnFilterTimeout(t *testing.T) { 97 mt := newMultiplexTransport( 98 emptyNodeInfo(), 99 NodeKey{ 100 PrivKey: ed25519.GenPrivKey(), 101 }, 102 ) 103 id := mt.nodeKey.ID() 104 105 MultiplexTransportFilterTimeout(5 * time.Millisecond)(mt) 106 MultiplexTransportConnFilters( 107 func(_ ConnSet, _ net.Conn, _ []net.IP) error { 108 time.Sleep(1 * time.Second) 109 return nil 110 }, 111 )(mt) 112 113 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 if err := mt.Listen(*addr); err != nil { 119 t.Fatal(err) 120 } 121 122 errc := make(chan error) 123 go func() { 124 addr := NewNetAddress(id, mt.listener.Addr()) 125 126 _, err := addr.Dial() 127 if err != nil { 128 errc <- err 129 return 130 } 131 132 close(errc) 133 }() 134 135 if err := <-errc; err != nil { 136 t.Errorf("connection failed: %v", err) 137 } 138 139 _, err = mt.Accept(peerConfig{}) 140 if _, ok := err.(ErrFilterTimeout); !ok { 141 t.Errorf("expected ErrFilterTimeout, got %v", err) 142 } 143 } 144 145 func TestTransportMultiplexMaxIncomingConnections(t *testing.T) { 146 pv := ed25519.GenPrivKey() 147 id := PubKeyToID(pv.PubKey()) 148 mt := newMultiplexTransport( 149 testNodeInfo( 150 id, "transport", 151 ), 152 NodeKey{ 153 PrivKey: pv, 154 }, 155 ) 156 157 MultiplexTransportMaxIncomingConnections(0)(mt) 158 159 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 160 if err != nil { 161 t.Fatal(err) 162 } 163 const maxIncomingConns = 2 164 MultiplexTransportMaxIncomingConnections(maxIncomingConns)(mt) 165 if err := mt.Listen(*addr); err != nil { 166 t.Fatal(err) 167 } 168 169 laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 170 171 // Connect more peers than max 172 for i := 0; i <= maxIncomingConns; i++ { 173 errc := make(chan error) 174 go testDialer(*laddr, errc) 175 176 err = <-errc 177 if i < maxIncomingConns { 178 if err != nil { 179 t.Errorf("dialer connection failed: %v", err) 180 } 181 _, err = mt.Accept(peerConfig{}) 182 if err != nil { 183 t.Errorf("connection failed: %v", err) 184 } 185 } else if err == nil || !strings.Contains(err.Error(), "i/o timeout") { 186 // mt actually blocks forever on trying to accept a new peer into a full channel so 187 // expect the dialer to encounter a timeout error. Calling mt.Accept will block until 188 // mt is closed. 189 t.Errorf("expected i/o timeout error, got %v", err) 190 } 191 } 192 } 193 194 func TestTransportMultiplexAcceptMultiple(t *testing.T) { 195 mt := testSetupMultiplexTransport(t) 196 laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 197 198 var ( 199 seed = rand.New(rand.NewSource(time.Now().UnixNano())) 200 nDialers = seed.Intn(64) + 64 201 errc = make(chan error, nDialers) 202 ) 203 204 // Setup dialers. 205 for i := 0; i < nDialers; i++ { 206 go testDialer(*laddr, errc) 207 } 208 209 // Catch connection errors. 210 for i := 0; i < nDialers; i++ { 211 if err := <-errc; err != nil { 212 t.Fatal(err) 213 } 214 } 215 216 ps := []Peer{} 217 218 // Accept all peers. 219 for i := 0; i < cap(errc); i++ { 220 p, err := mt.Accept(peerConfig{}) 221 if err != nil { 222 t.Fatal(err) 223 } 224 225 if err := p.Start(); err != nil { 226 t.Fatal(err) 227 } 228 229 ps = append(ps, p) 230 } 231 232 if have, want := len(ps), cap(errc); have != want { 233 t.Errorf("have %v, want %v", have, want) 234 } 235 236 // Stop all peers. 237 for _, p := range ps { 238 if err := p.Stop(); err != nil { 239 t.Fatal(err) 240 } 241 } 242 243 if err := mt.Close(); err != nil { 244 t.Errorf("close errored: %v", err) 245 } 246 } 247 248 func testDialer(dialAddr NetAddress, errc chan error) { 249 var ( 250 pv = ed25519.GenPrivKey() 251 dialer = newMultiplexTransport( 252 testNodeInfo(PubKeyToID(pv.PubKey()), defaultNodeName), 253 NodeKey{ 254 PrivKey: pv, 255 }, 256 ) 257 ) 258 259 _, err := dialer.Dial(dialAddr, peerConfig{}) 260 if err != nil { 261 errc <- err 262 return 263 } 264 265 // Signal that the connection was established. 266 errc <- nil 267 } 268 269 func TestTransportMultiplexAcceptNonBlocking(t *testing.T) { 270 mt := testSetupMultiplexTransport(t) 271 272 var ( 273 fastNodePV = ed25519.GenPrivKey() 274 fastNodeInfo = testNodeInfo(PubKeyToID(fastNodePV.PubKey()), "fastnode") 275 errc = make(chan error) 276 fastc = make(chan struct{}) 277 slowc = make(chan struct{}) 278 slowdonec = make(chan struct{}) 279 ) 280 281 // Simulate slow Peer. 282 go func() { 283 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 284 285 c, err := addr.Dial() 286 if err != nil { 287 errc <- err 288 return 289 } 290 291 close(slowc) 292 defer func() { 293 close(slowdonec) 294 }() 295 296 // Make sure we switch to fast peer goroutine. 297 runtime.Gosched() 298 299 select { 300 case <-fastc: 301 // Fast peer connected. 302 case <-time.After(200 * time.Millisecond): 303 // We error if the fast peer didn't succeed. 304 errc <- fmt.Errorf("fast peer timed out") 305 } 306 307 sc, err := upgradeSecretConn(c, 200*time.Millisecond, ed25519.GenPrivKey()) 308 if err != nil { 309 errc <- err 310 return 311 } 312 313 _, err = handshake(sc, 200*time.Millisecond, 314 testNodeInfo( 315 PubKeyToID(ed25519.GenPrivKey().PubKey()), 316 "slow_peer", 317 )) 318 if err != nil { 319 errc <- err 320 } 321 }() 322 323 // Simulate fast Peer. 324 go func() { 325 <-slowc 326 327 var ( 328 dialer = newMultiplexTransport( 329 fastNodeInfo, 330 NodeKey{ 331 PrivKey: fastNodePV, 332 }, 333 ) 334 ) 335 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 336 337 _, err := dialer.Dial(*addr, peerConfig{}) 338 if err != nil { 339 errc <- err 340 return 341 } 342 343 close(fastc) 344 <-slowdonec 345 close(errc) 346 }() 347 348 if err := <-errc; err != nil { 349 t.Logf("connection failed: %v", err) 350 } 351 352 p, err := mt.Accept(peerConfig{}) 353 if err != nil { 354 t.Fatal(err) 355 } 356 357 if have, want := p.NodeInfo(), fastNodeInfo; !reflect.DeepEqual(have, want) { 358 t.Errorf("have %v, want %v", have, want) 359 } 360 } 361 362 func TestTransportMultiplexValidateNodeInfo(t *testing.T) { 363 mt := testSetupMultiplexTransport(t) 364 365 errc := make(chan error) 366 367 go func() { 368 var ( 369 pv = ed25519.GenPrivKey() 370 dialer = newMultiplexTransport( 371 testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty 372 NodeKey{ 373 PrivKey: pv, 374 }, 375 ) 376 ) 377 378 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 379 380 _, err := dialer.Dial(*addr, peerConfig{}) 381 if err != nil { 382 errc <- err 383 return 384 } 385 386 close(errc) 387 }() 388 389 if err := <-errc; err != nil { 390 t.Errorf("connection failed: %v", err) 391 } 392 393 _, err := mt.Accept(peerConfig{}) 394 if e, ok := err.(ErrRejected); ok { 395 if !e.IsNodeInfoInvalid() { 396 t.Errorf("expected NodeInfo to be invalid, got %v", e) 397 } 398 } else { 399 t.Errorf("expected ErrRejected, got %v", err) 400 } 401 } 402 403 func TestTransportMultiplexRejectMissmatchID(t *testing.T) { 404 mt := testSetupMultiplexTransport(t) 405 406 errc := make(chan error) 407 408 go func() { 409 dialer := newMultiplexTransport( 410 testNodeInfo( 411 PubKeyToID(ed25519.GenPrivKey().PubKey()), "dialer", 412 ), 413 NodeKey{ 414 PrivKey: ed25519.GenPrivKey(), 415 }, 416 ) 417 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 418 419 _, err := dialer.Dial(*addr, peerConfig{}) 420 if err != nil { 421 errc <- err 422 return 423 } 424 425 close(errc) 426 }() 427 428 if err := <-errc; err != nil { 429 t.Errorf("connection failed: %v", err) 430 } 431 432 _, err := mt.Accept(peerConfig{}) 433 if e, ok := err.(ErrRejected); ok { 434 if !e.IsAuthFailure() { 435 t.Errorf("expected auth failure, got %v", e) 436 } 437 } else { 438 t.Errorf("expected ErrRejected, got %v", err) 439 } 440 } 441 442 func TestTransportMultiplexDialRejectWrongID(t *testing.T) { 443 mt := testSetupMultiplexTransport(t) 444 445 var ( 446 pv = ed25519.GenPrivKey() 447 dialer = newMultiplexTransport( 448 testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty 449 NodeKey{ 450 PrivKey: pv, 451 }, 452 ) 453 ) 454 455 wrongID := PubKeyToID(ed25519.GenPrivKey().PubKey()) 456 addr := NewNetAddress(wrongID, mt.listener.Addr()) 457 458 _, err := dialer.Dial(*addr, peerConfig{}) 459 if err != nil { 460 t.Logf("connection failed: %v", err) 461 if e, ok := err.(ErrRejected); ok { 462 if !e.IsAuthFailure() { 463 t.Errorf("expected auth failure, got %v", err) 464 } 465 } else { 466 t.Errorf("expected ErrRejected, got %v", err) 467 } 468 } 469 } 470 471 func TestTransportMultiplexRejectIncompatible(t *testing.T) { 472 mt := testSetupMultiplexTransport(t) 473 474 errc := make(chan error) 475 476 go func() { 477 var ( 478 pv = ed25519.GenPrivKey() 479 dialer = newMultiplexTransport( 480 testNodeInfoWithNetwork(PubKeyToID(pv.PubKey()), "dialer", "incompatible-network"), 481 NodeKey{ 482 PrivKey: pv, 483 }, 484 ) 485 ) 486 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 487 488 _, err := dialer.Dial(*addr, peerConfig{}) 489 if err != nil { 490 errc <- err 491 return 492 } 493 494 close(errc) 495 }() 496 497 _, err := mt.Accept(peerConfig{}) 498 if e, ok := err.(ErrRejected); ok { 499 if !e.IsIncompatible() { 500 t.Errorf("expected to reject incompatible, got %v", e) 501 } 502 } else { 503 t.Errorf("expected ErrRejected, got %v", err) 504 } 505 } 506 507 func TestTransportMultiplexRejectSelf(t *testing.T) { 508 mt := testSetupMultiplexTransport(t) 509 510 errc := make(chan error) 511 512 go func() { 513 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 514 515 _, err := mt.Dial(*addr, peerConfig{}) 516 if err != nil { 517 errc <- err 518 return 519 } 520 521 close(errc) 522 }() 523 524 if err := <-errc; err != nil { 525 if e, ok := err.(ErrRejected); ok { 526 if !e.IsSelf() { 527 t.Errorf("expected to reject self, got: %v", e) 528 } 529 } else { 530 t.Errorf("expected ErrRejected, got %v", err) 531 } 532 } else { 533 t.Errorf("expected connection failure") 534 } 535 536 _, err := mt.Accept(peerConfig{}) 537 if e, ok := err.(ErrRejected); ok { 538 if !e.IsSelf() { 539 t.Errorf("expected to reject self, got: %v", e) 540 } 541 } else { 542 t.Errorf("expected ErrRejected, got %v", err) 543 } 544 } 545 546 func TestTransportConnDuplicateIPFilter(t *testing.T) { 547 filter := ConnDuplicateIPFilter() 548 549 if err := filter(nil, &testTransportConn{}, nil); err != nil { 550 t.Fatal(err) 551 } 552 553 var ( 554 c = &testTransportConn{} 555 cs = NewConnSet() 556 ) 557 558 cs.Set(c, []net.IP{ 559 {10, 0, 10, 1}, 560 {10, 0, 10, 2}, 561 {10, 0, 10, 3}, 562 }) 563 564 if err := filter(cs, c, []net.IP{ 565 {10, 0, 10, 2}, 566 }); err == nil { 567 t.Errorf("expected Peer to be rejected as duplicate") 568 } 569 } 570 571 func TestTransportHandshake(t *testing.T) { 572 ln, err := net.Listen("tcp", "127.0.0.1:0") 573 if err != nil { 574 t.Fatal(err) 575 } 576 577 var ( 578 peerPV = ed25519.GenPrivKey() 579 peerNodeInfo = testNodeInfo(PubKeyToID(peerPV.PubKey()), defaultNodeName) 580 ) 581 582 go func() { 583 c, err := net.Dial(ln.Addr().Network(), ln.Addr().String()) 584 if err != nil { 585 t.Error(err) 586 return 587 } 588 589 go func(c net.Conn) { 590 _, err := protoio.NewDelimitedWriter(c).WriteMsg(peerNodeInfo.(DefaultNodeInfo).ToProto()) 591 if err != nil { 592 t.Error(err) 593 } 594 }(c) 595 go func(c net.Conn) { 596 var ( 597 // ni DefaultNodeInfo 598 pbni tmp2p.DefaultNodeInfo 599 ) 600 601 protoReader := protoio.NewDelimitedReader(c, MaxNodeInfoSize()) 602 _, err := protoReader.ReadMsg(&pbni) 603 if err != nil { 604 t.Error(err) 605 } 606 607 _, err = DefaultNodeInfoFromToProto(&pbni) 608 if err != nil { 609 t.Error(err) 610 } 611 }(c) 612 }() 613 614 c, err := ln.Accept() 615 if err != nil { 616 t.Fatal(err) 617 } 618 619 ni, err := handshake(c, 50*time.Millisecond, emptyNodeInfo()) 620 if err != nil { 621 t.Fatal(err) 622 } 623 624 if have, want := ni, peerNodeInfo; !reflect.DeepEqual(have, want) { 625 t.Errorf("have %v, want %v", have, want) 626 } 627 } 628 629 func TestTransportAddChannel(t *testing.T) { 630 mt := newMultiplexTransport( 631 emptyNodeInfo(), 632 NodeKey{ 633 PrivKey: ed25519.GenPrivKey(), 634 }, 635 ) 636 testChannel := byte(0x01) 637 638 err := mt.AddChannel(testChannel) 639 require.NoError(t, err) 640 if !mt.nodeInfo.(DefaultNodeInfo).HasChannel(testChannel) { 641 t.Errorf("missing added channel %v. Got %v", testChannel, mt.nodeInfo.(DefaultNodeInfo).Channels) 642 } 643 } 644 645 func TestTransportResolveIPs(t *testing.T) { 646 server := startFakeDNS() 647 defer func() { 648 err := server.Shutdown() 649 require.NoError(t, err) 650 }() 651 652 r := &net.Resolver{ 653 PreferGo: true, 654 Dial: func(ctx context.Context, network, address string) (net.Conn, error) { 655 d := net.Dialer{ 656 Timeout: time.Millisecond * time.Duration(500), 657 } 658 return d.DialContext(ctx, network, "127.0.0.1:5355") 659 }, 660 } 661 _, err := resolveIPs(r, &testTransportConn{}) 662 require.Contains(t, err.Error(), "lookup test.local: i/o timeout") 663 } 664 665 // create listener 666 func testSetupMultiplexTransport(t *testing.T) *MultiplexTransport { 667 var ( 668 pv = ed25519.GenPrivKey() 669 id = PubKeyToID(pv.PubKey()) 670 mt = newMultiplexTransport( 671 testNodeInfo( 672 id, "transport", 673 ), 674 NodeKey{ 675 PrivKey: pv, 676 }, 677 ) 678 ) 679 680 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 681 if err != nil { 682 t.Fatal(err) 683 } 684 685 if err := mt.Listen(*addr); err != nil { 686 t.Fatal(err) 687 } 688 689 // give the listener some time to get ready 690 time.Sleep(20 * time.Millisecond) 691 692 return mt 693 } 694 695 type testTransportAddr struct{} 696 697 func (a *testTransportAddr) Network() string { return "tcp" } 698 func (a *testTransportAddr) String() string { return "test.local:1234" } 699 700 type testTransportConn struct{} 701 702 func (c *testTransportConn) Close() error { 703 return fmt.Errorf("close() not implemented") 704 } 705 706 func (c *testTransportConn) LocalAddr() net.Addr { 707 return &testTransportAddr{} 708 } 709 710 func (c *testTransportConn) RemoteAddr() net.Addr { 711 return &testTransportAddr{} 712 } 713 714 func (c *testTransportConn) Read(_ []byte) (int, error) { 715 return -1, fmt.Errorf("read() not implemented") 716 } 717 718 func (c *testTransportConn) SetDeadline(_ time.Time) error { 719 return fmt.Errorf("setDeadline() not implemented") 720 } 721 722 func (c *testTransportConn) SetReadDeadline(_ time.Time) error { 723 return fmt.Errorf("setReadDeadline() not implemented") 724 } 725 726 func (c *testTransportConn) SetWriteDeadline(_ time.Time) error { 727 return fmt.Errorf("setWriteDeadline() not implemented") 728 } 729 730 func (c *testTransportConn) Write(_ []byte) (int, error) { 731 return -1, fmt.Errorf("write() not implemented") 732 } 733 734 // fake dns server 735 var records = map[string]string{ 736 "test.local.": "192.168.0.2", 737 } 738 739 func parseQuery(m *dns.Msg) { 740 time.Sleep(5 * time.Second) 741 for _, q := range m.Question { 742 switch q.Qtype { 743 case dns.TypeA: 744 ip := records[q.Name] 745 if ip != "" { 746 rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, ip)) 747 if err == nil { 748 m.Answer = append(m.Answer, rr) 749 } 750 } 751 } 752 } 753 } 754 755 func handleDnsRequest(w dns.ResponseWriter, r *dns.Msg) { 756 m := new(dns.Msg) 757 m.SetReply(r) 758 m.Compress = false 759 switch r.Opcode { 760 case dns.OpcodeQuery: 761 parseQuery(m) 762 } 763 _ = w.WriteMsg(m) 764 } 765 766 func startFakeDNS() *dns.Server { 767 // attach request handler func 768 dns.HandleFunc("local.", handleDnsRequest) 769 770 // start server 771 port := 5355 772 server := &dns.Server{Addr: ":" + strconv.Itoa(port), Net: "udp"} 773 go func() { 774 err := server.ListenAndServe() 775 if err != nil { 776 panic(err.Error()) 777 } 778 }() 779 return server 780 }