network_proxy_test.go 5.6 KB

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