server_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package p2p
  2. import (
  3. "bytes"
  4. "crypto/ecdsa"
  5. "io"
  6. "math/rand"
  7. "net"
  8. "sync"
  9. "testing"
  10. "time"
  11. "github.com/ethereum/go-ethereum/crypto"
  12. "github.com/ethereum/go-ethereum/crypto/sha3"
  13. "github.com/ethereum/go-ethereum/p2p/discover"
  14. )
  15. func startTestServer(t *testing.T, pf newPeerHook) *Server {
  16. server := &Server{
  17. Name: "test",
  18. MaxPeers: 10,
  19. ListenAddr: "127.0.0.1:0",
  20. PrivateKey: newkey(),
  21. newPeerHook: pf,
  22. setupFunc: func(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake, dial *discover.Node) (*conn, error) {
  23. id := randomID()
  24. rw := newRlpxFrameRW(fd, secrets{
  25. MAC: zero16,
  26. AES: zero16,
  27. IngressMAC: sha3.NewKeccak256(),
  28. EgressMAC: sha3.NewKeccak256(),
  29. })
  30. return &conn{
  31. MsgReadWriter: rw,
  32. protoHandshake: &protoHandshake{ID: id, Version: baseProtocolVersion},
  33. }, nil
  34. },
  35. }
  36. if err := server.Start(); err != nil {
  37. t.Fatalf("Could not start server: %v", err)
  38. }
  39. return server
  40. }
  41. func TestServerListen(t *testing.T) {
  42. defer testlog(t).detach()
  43. // start the test server
  44. connected := make(chan *Peer)
  45. srv := startTestServer(t, func(p *Peer) {
  46. if p == nil {
  47. t.Error("peer func called with nil conn")
  48. }
  49. connected <- p
  50. })
  51. defer close(connected)
  52. defer srv.Stop()
  53. // dial the test server
  54. conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second)
  55. if err != nil {
  56. t.Fatalf("could not dial: %v", err)
  57. }
  58. defer conn.Close()
  59. select {
  60. case peer := <-connected:
  61. if peer.LocalAddr().String() != conn.RemoteAddr().String() {
  62. t.Errorf("peer started with wrong conn: got %v, want %v",
  63. peer.LocalAddr(), conn.RemoteAddr())
  64. }
  65. case <-time.After(1 * time.Second):
  66. t.Error("server did not accept within one second")
  67. }
  68. }
  69. func TestServerDial(t *testing.T) {
  70. defer testlog(t).detach()
  71. // run a one-shot TCP server to handle the connection.
  72. listener, err := net.Listen("tcp", "127.0.0.1:0")
  73. if err != nil {
  74. t.Fatalf("could not setup listener: %v")
  75. }
  76. defer listener.Close()
  77. accepted := make(chan net.Conn)
  78. go func() {
  79. conn, err := listener.Accept()
  80. if err != nil {
  81. t.Error("accept error:", err)
  82. return
  83. }
  84. conn.Close()
  85. accepted <- conn
  86. }()
  87. // start the server
  88. connected := make(chan *Peer)
  89. srv := startTestServer(t, func(p *Peer) { connected <- p })
  90. defer close(connected)
  91. defer srv.Stop()
  92. // tell the server to connect
  93. tcpAddr := listener.Addr().(*net.TCPAddr)
  94. srv.SuggestPeer(&discover.Node{IP: tcpAddr.IP, TCPPort: tcpAddr.Port})
  95. select {
  96. case conn := <-accepted:
  97. select {
  98. case peer := <-connected:
  99. if peer.RemoteAddr().String() != conn.LocalAddr().String() {
  100. t.Errorf("peer started with wrong conn: got %v, want %v",
  101. peer.RemoteAddr(), conn.LocalAddr())
  102. }
  103. // TODO: validate more fields
  104. case <-time.After(1 * time.Second):
  105. t.Error("server did not launch peer within one second")
  106. }
  107. case <-time.After(1 * time.Second):
  108. t.Error("server did not connect within one second")
  109. }
  110. }
  111. func TestServerBroadcast(t *testing.T) {
  112. defer testlog(t).detach()
  113. var connected sync.WaitGroup
  114. srv := startTestServer(t, func(p *Peer) {
  115. p.running = matchProtocols([]Protocol{discard}, []Cap{discard.cap()}, p.rw)
  116. connected.Done()
  117. })
  118. defer srv.Stop()
  119. // create a few peers
  120. var conns = make([]net.Conn, 8)
  121. connected.Add(len(conns))
  122. deadline := time.Now().Add(3 * time.Second)
  123. dialer := &net.Dialer{Deadline: deadline}
  124. for i := range conns {
  125. conn, err := dialer.Dial("tcp", srv.ListenAddr)
  126. if err != nil {
  127. t.Fatalf("conn %d: dial error: %v", i, err)
  128. }
  129. defer conn.Close()
  130. conn.SetDeadline(deadline)
  131. conns[i] = conn
  132. }
  133. connected.Wait()
  134. // broadcast one message
  135. srv.Broadcast("discard", 0, []string{"foo"})
  136. golden := unhex("66e94d166f0a2c3b884cfa59ca34")
  137. // check that the message has been written everywhere
  138. for i, conn := range conns {
  139. buf := make([]byte, len(golden))
  140. if _, err := io.ReadFull(conn, buf); err != nil {
  141. t.Errorf("conn %d: read error: %v", i, err)
  142. } else if !bytes.Equal(buf, golden) {
  143. t.Errorf("conn %d: msg mismatch\ngot: %x\nwant: %x", i, buf, golden)
  144. }
  145. }
  146. }
  147. func newkey() *ecdsa.PrivateKey {
  148. key, err := crypto.GenerateKey()
  149. if err != nil {
  150. panic("couldn't generate key: " + err.Error())
  151. }
  152. return key
  153. }
  154. func randomID() (id discover.NodeID) {
  155. for i := range id {
  156. id[i] = byte(rand.Intn(255))
  157. }
  158. return id
  159. }