network_proxy_test.go 5.4 KB

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