network_proxy_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package main
  2. import (
  3. "bytes"
  4. "flag"
  5. "fmt"
  6. "io"
  7. "net"
  8. "strings"
  9. "testing"
  10. "time"
  11. )
  12. var _ = flag.Bool("incontainer", false, "Indicates if the test is running in a container")
  13. var testBuf = []byte("Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo")
  14. var testBufSize = len(testBuf)
  15. type EchoServer interface {
  16. Run()
  17. Close()
  18. LocalAddr() net.Addr
  19. }
  20. type TCPEchoServer struct {
  21. listener net.Listener
  22. testCtx *testing.T
  23. }
  24. type UDPEchoServer struct {
  25. conn net.PacketConn
  26. testCtx *testing.T
  27. }
  28. func NewEchoServer(t *testing.T, proto, address string) EchoServer {
  29. var server EchoServer
  30. if strings.HasPrefix(proto, "tcp") {
  31. listener, err := net.Listen(proto, address)
  32. if err != nil {
  33. t.Fatal(err)
  34. }
  35. server = &TCPEchoServer{listener: listener, testCtx: t}
  36. } else {
  37. socket, err := net.ListenPacket(proto, address)
  38. if err != nil {
  39. t.Fatal(err)
  40. }
  41. server = &UDPEchoServer{conn: socket, testCtx: t}
  42. }
  43. return server
  44. }
  45. func (server *TCPEchoServer) Run() {
  46. go func() {
  47. for {
  48. client, err := server.listener.Accept()
  49. if err != nil {
  50. return
  51. }
  52. go func(client net.Conn) {
  53. if _, err := io.Copy(client, client); err != nil {
  54. server.testCtx.Logf("can't echo to the client: %v\n", err.Error())
  55. }
  56. client.Close()
  57. }(client)
  58. }
  59. }()
  60. }
  61. func (server *TCPEchoServer) LocalAddr() net.Addr { return server.listener.Addr() }
  62. func (server *TCPEchoServer) Close() { server.listener.Close() }
  63. func (server *UDPEchoServer) Run() {
  64. go func() {
  65. readBuf := make([]byte, 1024)
  66. for {
  67. read, from, err := server.conn.ReadFrom(readBuf)
  68. if err != nil {
  69. return
  70. }
  71. for i := 0; i != read; {
  72. written, err := server.conn.WriteTo(readBuf[i:read], from)
  73. if err != nil {
  74. break
  75. }
  76. i += written
  77. }
  78. }
  79. }()
  80. }
  81. func (server *UDPEchoServer) LocalAddr() net.Addr { return server.conn.LocalAddr() }
  82. func (server *UDPEchoServer) Close() { server.conn.Close() }
  83. func testProxyAt(t *testing.T, proto string, proxy Proxy, addr string) {
  84. defer proxy.Close()
  85. go proxy.Run()
  86. client, err := net.Dial(proto, addr)
  87. if err != nil {
  88. t.Fatalf("Can't connect to the proxy: %v", err)
  89. }
  90. defer client.Close()
  91. client.SetDeadline(time.Now().Add(10 * time.Second))
  92. if _, err = client.Write(testBuf); err != nil {
  93. t.Fatal(err)
  94. }
  95. recvBuf := make([]byte, testBufSize)
  96. if _, err = client.Read(recvBuf); err != nil {
  97. t.Fatal(err)
  98. }
  99. if !bytes.Equal(testBuf, recvBuf) {
  100. t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
  101. }
  102. }
  103. func testProxy(t *testing.T, proto string, proxy Proxy) {
  104. testProxyAt(t, proto, proxy, proxy.FrontendAddr().String())
  105. }
  106. func TestTCP4Proxy(t *testing.T) {
  107. backend := NewEchoServer(t, "tcp", "127.0.0.1:0")
  108. defer backend.Close()
  109. backend.Run()
  110. frontendAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
  111. proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
  112. if err != nil {
  113. t.Fatal(err)
  114. }
  115. testProxy(t, "tcp", proxy)
  116. }
  117. func TestTCP6Proxy(t *testing.T) {
  118. backend := NewEchoServer(t, "tcp", "[::1]:0")
  119. defer backend.Close()
  120. backend.Run()
  121. frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
  122. proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. testProxy(t, "tcp", proxy)
  127. }
  128. func TestTCPDualStackProxy(t *testing.T) {
  129. // If I understand `godoc -src net favoriteAddrFamily` (used by the
  130. // net.Listen* functions) correctly this should work, but it doesn't.
  131. t.Skip("No support for dual stack yet")
  132. backend := NewEchoServer(t, "tcp", "[::1]:0")
  133. defer backend.Close()
  134. backend.Run()
  135. frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
  136. proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
  137. if err != nil {
  138. t.Fatal(err)
  139. }
  140. ipv4ProxyAddr := &net.TCPAddr{
  141. IP: net.IPv4(127, 0, 0, 1),
  142. Port: proxy.FrontendAddr().(*net.TCPAddr).Port,
  143. }
  144. testProxyAt(t, "tcp", proxy, ipv4ProxyAddr.String())
  145. }
  146. func TestUDP4Proxy(t *testing.T) {
  147. backend := NewEchoServer(t, "udp", "127.0.0.1:0")
  148. defer backend.Close()
  149. backend.Run()
  150. frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
  151. proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. testProxy(t, "udp", proxy)
  156. }
  157. func TestUDP6Proxy(t *testing.T) {
  158. backend := NewEchoServer(t, "udp", "[::1]:0")
  159. defer backend.Close()
  160. backend.Run()
  161. frontendAddr := &net.UDPAddr{IP: net.IPv6loopback, Port: 0}
  162. proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
  163. if err != nil {
  164. t.Fatal(err)
  165. }
  166. testProxy(t, "udp", proxy)
  167. }
  168. func TestUDPWriteError(t *testing.T) {
  169. frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
  170. // Hopefully, this port will be free: */
  171. backendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 25587}
  172. proxy, err := NewProxy(frontendAddr, backendAddr)
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. defer proxy.Close()
  177. go proxy.Run()
  178. client, err := net.Dial("udp", "127.0.0.1:25587")
  179. if err != nil {
  180. t.Fatalf("Can't connect to the proxy: %v", err)
  181. }
  182. defer client.Close()
  183. // Make sure the proxy doesn't stop when there is no actual backend:
  184. client.Write(testBuf)
  185. client.Write(testBuf)
  186. backend := NewEchoServer(t, "udp", "127.0.0.1:25587")
  187. defer backend.Close()
  188. backend.Run()
  189. client.SetDeadline(time.Now().Add(10 * time.Second))
  190. if _, err = client.Write(testBuf); err != nil {
  191. t.Fatal(err)
  192. }
  193. recvBuf := make([]byte, testBufSize)
  194. if _, err = client.Read(recvBuf); err != nil {
  195. t.Fatal(err)
  196. }
  197. if !bytes.Equal(testBuf, recvBuf) {
  198. t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
  199. }
  200. }