You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

143 lines
3.3 KiB

  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package proxy
  5. import (
  6. "io"
  7. "net"
  8. "net/url"
  9. "strconv"
  10. "sync"
  11. "testing"
  12. )
  13. func TestFromURL(t *testing.T) {
  14. endSystem, err := net.Listen("tcp", "127.0.0.1:0")
  15. if err != nil {
  16. t.Fatalf("net.Listen failed: %v", err)
  17. }
  18. defer endSystem.Close()
  19. gateway, err := net.Listen("tcp", "127.0.0.1:0")
  20. if err != nil {
  21. t.Fatalf("net.Listen failed: %v", err)
  22. }
  23. defer gateway.Close()
  24. var wg sync.WaitGroup
  25. wg.Add(1)
  26. go socks5Gateway(t, gateway, endSystem, socks5Domain, &wg)
  27. url, err := url.Parse("socks5://user:password@" + gateway.Addr().String())
  28. if err != nil {
  29. t.Fatalf("url.Parse failed: %v", err)
  30. }
  31. proxy, err := FromURL(url, Direct)
  32. if err != nil {
  33. t.Fatalf("FromURL failed: %v", err)
  34. }
  35. _, port, err := net.SplitHostPort(endSystem.Addr().String())
  36. if err != nil {
  37. t.Fatalf("net.SplitHostPort failed: %v", err)
  38. }
  39. if c, err := proxy.Dial("tcp", "localhost:"+port); err != nil {
  40. t.Fatalf("FromURL.Dial failed: %v", err)
  41. } else {
  42. c.Close()
  43. }
  44. wg.Wait()
  45. }
  46. func TestSOCKS5(t *testing.T) {
  47. endSystem, err := net.Listen("tcp", "127.0.0.1:0")
  48. if err != nil {
  49. t.Fatalf("net.Listen failed: %v", err)
  50. }
  51. defer endSystem.Close()
  52. gateway, err := net.Listen("tcp", "127.0.0.1:0")
  53. if err != nil {
  54. t.Fatalf("net.Listen failed: %v", err)
  55. }
  56. defer gateway.Close()
  57. var wg sync.WaitGroup
  58. wg.Add(1)
  59. go socks5Gateway(t, gateway, endSystem, socks5IP4, &wg)
  60. proxy, err := SOCKS5("tcp", gateway.Addr().String(), nil, Direct)
  61. if err != nil {
  62. t.Fatalf("SOCKS5 failed: %v", err)
  63. }
  64. if c, err := proxy.Dial("tcp", endSystem.Addr().String()); err != nil {
  65. t.Fatalf("SOCKS5.Dial failed: %v", err)
  66. } else {
  67. c.Close()
  68. }
  69. wg.Wait()
  70. }
  71. func socks5Gateway(t *testing.T, gateway, endSystem net.Listener, typ byte, wg *sync.WaitGroup) {
  72. defer wg.Done()
  73. c, err := gateway.Accept()
  74. if err != nil {
  75. t.Errorf("net.Listener.Accept failed: %v", err)
  76. return
  77. }
  78. defer c.Close()
  79. b := make([]byte, 32)
  80. var n int
  81. if typ == socks5Domain {
  82. n = 4
  83. } else {
  84. n = 3
  85. }
  86. if _, err := io.ReadFull(c, b[:n]); err != nil {
  87. t.Errorf("io.ReadFull failed: %v", err)
  88. return
  89. }
  90. if _, err := c.Write([]byte{socks5Version, socks5AuthNone}); err != nil {
  91. t.Errorf("net.Conn.Write failed: %v", err)
  92. return
  93. }
  94. if typ == socks5Domain {
  95. n = 16
  96. } else {
  97. n = 10
  98. }
  99. if _, err := io.ReadFull(c, b[:n]); err != nil {
  100. t.Errorf("io.ReadFull failed: %v", err)
  101. return
  102. }
  103. if b[0] != socks5Version || b[1] != socks5Connect || b[2] != 0x00 || b[3] != typ {
  104. t.Errorf("got an unexpected packet: %#02x %#02x %#02x %#02x", b[0], b[1], b[2], b[3])
  105. return
  106. }
  107. if typ == socks5Domain {
  108. copy(b[:5], []byte{socks5Version, 0x00, 0x00, socks5Domain, 9})
  109. b = append(b, []byte("localhost")...)
  110. } else {
  111. copy(b[:4], []byte{socks5Version, 0x00, 0x00, socks5IP4})
  112. }
  113. host, port, err := net.SplitHostPort(endSystem.Addr().String())
  114. if err != nil {
  115. t.Errorf("net.SplitHostPort failed: %v", err)
  116. return
  117. }
  118. b = append(b, []byte(net.ParseIP(host).To4())...)
  119. p, err := strconv.Atoi(port)
  120. if err != nil {
  121. t.Errorf("strconv.Atoi failed: %v", err)
  122. return
  123. }
  124. b = append(b, []byte{byte(p >> 8), byte(p)}...)
  125. if _, err := c.Write(b); err != nil {
  126. t.Errorf("net.Conn.Write failed: %v", err)
  127. return
  128. }
  129. }