socks_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package socks
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "testing"
  8. "golang.org/x/net/proxy"
  9. "github.com/v2ray/v2ray-core/app/point"
  10. v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
  11. "github.com/v2ray/v2ray-core/proxy/common/connhandler"
  12. "github.com/v2ray/v2ray-core/proxy/socks/config/json"
  13. proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
  14. "github.com/v2ray/v2ray-core/testing/mocks"
  15. "github.com/v2ray/v2ray-core/testing/unit"
  16. )
  17. func TestSocksTcpConnect(t *testing.T) {
  18. assert := unit.Assert(t)
  19. port := v2nettesting.PickPort()
  20. connInput := []byte("The data to be returned to socks server.")
  21. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  22. och := &proxymocks.OutboundConnectionHandler{
  23. ConnOutput: connOutput,
  24. ConnInput: bytes.NewReader(connInput),
  25. }
  26. connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och)
  27. config := mocks.Config{
  28. PortValue: port,
  29. InboundConfigValue: &mocks.ConnectionConfig{
  30. ProtocolValue: "socks",
  31. SettingsValue: &json.SocksConfig{
  32. AuthMethod: "noauth",
  33. },
  34. },
  35. OutboundConfigValue: &mocks.ConnectionConfig{
  36. ProtocolValue: "mock_och",
  37. SettingsValue: nil,
  38. },
  39. }
  40. point, err := point.NewPoint(&config)
  41. assert.Error(err).IsNil()
  42. err = point.Start()
  43. assert.Error(err).IsNil()
  44. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), nil, proxy.Direct)
  45. assert.Error(err).IsNil()
  46. targetServer := "google.com:80"
  47. conn, err := socks5Client.Dial("tcp", targetServer)
  48. assert.Error(err).IsNil()
  49. data2Send := "The data to be sent to remote server."
  50. conn.Write([]byte(data2Send))
  51. if tcpConn, ok := conn.(*net.TCPConn); ok {
  52. tcpConn.CloseWrite()
  53. }
  54. dataReturned, err := ioutil.ReadAll(conn)
  55. assert.Error(err).IsNil()
  56. conn.Close()
  57. assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
  58. assert.Bytes(dataReturned).Equals(connInput)
  59. assert.String(targetServer).Equals(och.Destination.Address().String())
  60. }
  61. func TestSocksTcpConnectWithUserPass(t *testing.T) {
  62. assert := unit.Assert(t)
  63. port := v2nettesting.PickPort()
  64. connInput := []byte("The data to be returned to socks server.")
  65. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  66. och := &proxymocks.OutboundConnectionHandler{
  67. ConnInput: bytes.NewReader(connInput),
  68. ConnOutput: connOutput,
  69. }
  70. connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och)
  71. config := mocks.Config{
  72. PortValue: port,
  73. InboundConfigValue: &mocks.ConnectionConfig{
  74. ProtocolValue: "socks",
  75. SettingsValue: &json.SocksConfig{
  76. AuthMethod: "password",
  77. Accounts: []json.SocksAccount{
  78. json.SocksAccount{
  79. Username: "userx",
  80. Password: "passy",
  81. },
  82. },
  83. },
  84. },
  85. OutboundConfigValue: &mocks.ConnectionConfig{
  86. ProtocolValue: "mock_och",
  87. SettingsValue: nil,
  88. },
  89. }
  90. point, err := point.NewPoint(&config)
  91. assert.Error(err).IsNil()
  92. err = point.Start()
  93. assert.Error(err).IsNil()
  94. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), &proxy.Auth{"userx", "passy"}, proxy.Direct)
  95. assert.Error(err).IsNil()
  96. targetServer := "1.2.3.4:443"
  97. conn, err := socks5Client.Dial("tcp", targetServer)
  98. assert.Error(err).IsNil()
  99. data2Send := "The data to be sent to remote server."
  100. conn.Write([]byte(data2Send))
  101. if tcpConn, ok := conn.(*net.TCPConn); ok {
  102. tcpConn.CloseWrite()
  103. }
  104. dataReturned, err := ioutil.ReadAll(conn)
  105. assert.Error(err).IsNil()
  106. conn.Close()
  107. assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
  108. assert.Bytes(dataReturned).Equals(connInput)
  109. assert.String(targetServer).Equals(och.Destination.Address().String())
  110. }
  111. func TestSocksTcpConnectWithWrongUserPass(t *testing.T) {
  112. assert := unit.Assert(t)
  113. port := v2nettesting.PickPort()
  114. connInput := []byte("The data to be returned to socks server.")
  115. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  116. och := &proxymocks.OutboundConnectionHandler{
  117. ConnInput: bytes.NewReader(connInput),
  118. ConnOutput: connOutput,
  119. }
  120. connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och)
  121. config := mocks.Config{
  122. PortValue: port,
  123. InboundConfigValue: &mocks.ConnectionConfig{
  124. ProtocolValue: "socks",
  125. SettingsValue: &json.SocksConfig{
  126. AuthMethod: "password",
  127. Accounts: []json.SocksAccount{
  128. json.SocksAccount{
  129. Username: "userx",
  130. Password: "passy",
  131. },
  132. },
  133. },
  134. },
  135. OutboundConfigValue: &mocks.ConnectionConfig{
  136. ProtocolValue: "mock_och",
  137. SettingsValue: nil,
  138. },
  139. }
  140. point, err := point.NewPoint(&config)
  141. assert.Error(err).IsNil()
  142. err = point.Start()
  143. assert.Error(err).IsNil()
  144. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), &proxy.Auth{"userx", "passz"}, proxy.Direct)
  145. assert.Error(err).IsNil()
  146. targetServer := "1.2.3.4:443"
  147. _, err = socks5Client.Dial("tcp", targetServer)
  148. assert.Error(err).IsNotNil()
  149. }
  150. func TestSocksTcpConnectWithWrongAuthMethod(t *testing.T) {
  151. assert := unit.Assert(t)
  152. port := v2nettesting.PickPort()
  153. connInput := []byte("The data to be returned to socks server.")
  154. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  155. och := &proxymocks.OutboundConnectionHandler{
  156. ConnInput: bytes.NewReader(connInput),
  157. ConnOutput: connOutput,
  158. }
  159. connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och)
  160. config := mocks.Config{
  161. PortValue: port,
  162. InboundConfigValue: &mocks.ConnectionConfig{
  163. ProtocolValue: "socks",
  164. SettingsValue: &json.SocksConfig{
  165. AuthMethod: "password",
  166. Accounts: []json.SocksAccount{
  167. json.SocksAccount{
  168. Username: "userx",
  169. Password: "passy",
  170. },
  171. },
  172. },
  173. },
  174. OutboundConfigValue: &mocks.ConnectionConfig{
  175. ProtocolValue: "mock_och",
  176. SettingsValue: nil,
  177. },
  178. }
  179. point, err := point.NewPoint(&config)
  180. assert.Error(err).IsNil()
  181. err = point.Start()
  182. assert.Error(err).IsNil()
  183. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), nil, proxy.Direct)
  184. assert.Error(err).IsNil()
  185. targetServer := "1.2.3.4:443"
  186. _, err = socks5Client.Dial("tcp", targetServer)
  187. assert.Error(err).IsNotNil()
  188. }
  189. func TestSocksUdpSend(t *testing.T) {
  190. assert := unit.Assert(t)
  191. port := v2nettesting.PickPort()
  192. connInput := []byte("The data to be returned to socks server.")
  193. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  194. och := &proxymocks.OutboundConnectionHandler{
  195. ConnInput: bytes.NewReader(connInput),
  196. ConnOutput: connOutput,
  197. }
  198. connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och)
  199. config := mocks.Config{
  200. PortValue: port,
  201. InboundConfigValue: &mocks.ConnectionConfig{
  202. ProtocolValue: "socks",
  203. SettingsValue: &json.SocksConfig{
  204. AuthMethod: "noauth",
  205. UDPEnabled: true,
  206. },
  207. },
  208. OutboundConfigValue: &mocks.ConnectionConfig{
  209. ProtocolValue: "mock_och",
  210. SettingsValue: nil,
  211. },
  212. }
  213. point, err := point.NewPoint(&config)
  214. assert.Error(err).IsNil()
  215. err = point.Start()
  216. assert.Error(err).IsNil()
  217. conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
  218. IP: []byte{127, 0, 0, 1},
  219. Port: int(port),
  220. Zone: "",
  221. })
  222. assert.Error(err).IsNil()
  223. data2Send := []byte("Fake DNS request")
  224. buffer := make([]byte, 0, 1024)
  225. buffer = append(buffer, 0, 0, 0)
  226. buffer = append(buffer, 1, 8, 8, 4, 4, 0, 53)
  227. buffer = append(buffer, data2Send...)
  228. conn.Write(buffer)
  229. response := make([]byte, 1024)
  230. nBytes, err := conn.Read(response)
  231. assert.Error(err).IsNil()
  232. assert.Bytes(response[10:nBytes]).Equals(connInput)
  233. assert.Bytes(data2Send).Equals(connOutput.Bytes())
  234. assert.String(och.Destination.String()).Equals("udp:8.8.4.4:53")
  235. }