socks.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. package socks
  2. import (
  3. "errors"
  4. "io"
  5. "net"
  6. "strconv"
  7. "sync"
  8. "time"
  9. "github.com/v2ray/v2ray-core"
  10. "github.com/v2ray/v2ray-core/common/alloc"
  11. "github.com/v2ray/v2ray-core/common/log"
  12. v2net "github.com/v2ray/v2ray-core/common/net"
  13. "github.com/v2ray/v2ray-core/proxy"
  14. jsonconfig "github.com/v2ray/v2ray-core/proxy/socks/config/json"
  15. "github.com/v2ray/v2ray-core/proxy/socks/protocol"
  16. )
  17. var (
  18. UnsupportedSocksCommand = errors.New("Unsupported socks command.")
  19. UnsupportedAuthMethod = errors.New("Unsupported auth method.")
  20. )
  21. // SocksServer is a SOCKS 5 proxy server
  22. type SocksServer struct {
  23. accepting bool
  24. vPoint *core.Point
  25. config *jsonconfig.SocksConfig
  26. }
  27. func NewSocksServer(vp *core.Point, config *jsonconfig.SocksConfig) *SocksServer {
  28. return &SocksServer{
  29. vPoint: vp,
  30. config: config,
  31. }
  32. }
  33. func (server *SocksServer) Listen(port uint16) error {
  34. listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
  35. if err != nil {
  36. log.Error("Socks failed to listen on port %d: %v", port, err)
  37. return err
  38. }
  39. server.accepting = true
  40. go server.AcceptConnections(listener)
  41. if server.config.UDPEnabled {
  42. server.ListenUDP(port)
  43. }
  44. return nil
  45. }
  46. func (server *SocksServer) AcceptConnections(listener net.Listener) {
  47. for server.accepting {
  48. connection, err := listener.Accept()
  49. if err != nil {
  50. log.Error("Socks failed to accept new connection %v", err)
  51. continue
  52. }
  53. go server.HandleConnection(connection)
  54. }
  55. }
  56. func (server *SocksServer) HandleConnection(connection net.Conn) error {
  57. defer connection.Close()
  58. reader := v2net.NewTimeOutReader(120, connection)
  59. auth, auth4, err := protocol.ReadAuthentication(reader)
  60. if err != nil && err != protocol.Socks4Downgrade {
  61. log.Error("Socks failed to read authentication: %v", err)
  62. return err
  63. }
  64. if err != nil && err == protocol.Socks4Downgrade {
  65. return server.handleSocks4(reader, connection, auth4)
  66. } else {
  67. return server.handleSocks5(reader, connection, auth)
  68. }
  69. }
  70. func (server *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Writer, auth protocol.Socks5AuthenticationRequest) error {
  71. expectedAuthMethod := protocol.AuthNotRequired
  72. if server.config.IsPassword() {
  73. expectedAuthMethod = protocol.AuthUserPass
  74. }
  75. if !auth.HasAuthMethod(expectedAuthMethod) {
  76. authResponse := protocol.NewAuthenticationResponse(protocol.AuthNoMatchingMethod)
  77. err := protocol.WriteAuthentication(writer, authResponse)
  78. if err != nil {
  79. log.Error("Socks failed to write authentication: %v", err)
  80. return err
  81. }
  82. log.Warning("Socks client doesn't support allowed any auth methods.")
  83. return UnsupportedAuthMethod
  84. }
  85. authResponse := protocol.NewAuthenticationResponse(expectedAuthMethod)
  86. err := protocol.WriteAuthentication(writer, authResponse)
  87. if err != nil {
  88. log.Error("Socks failed to write authentication: %v", err)
  89. return err
  90. }
  91. if server.config.IsPassword() {
  92. upRequest, err := protocol.ReadUserPassRequest(reader)
  93. if err != nil {
  94. log.Error("Socks failed to read username and password: %v", err)
  95. return err
  96. }
  97. status := byte(0)
  98. if !server.config.HasAccount(upRequest.Username(), upRequest.Password()) {
  99. status = byte(0xFF)
  100. }
  101. upResponse := protocol.NewSocks5UserPassResponse(status)
  102. err = protocol.WriteUserPassResponse(writer, upResponse)
  103. if err != nil {
  104. log.Error("Socks failed to write user pass response: %v", err)
  105. return err
  106. }
  107. if status != byte(0) {
  108. log.Warning("Invalid user account: %s", upRequest.AuthDetail())
  109. return proxy.InvalidAuthentication
  110. }
  111. }
  112. request, err := protocol.ReadRequest(reader)
  113. if err != nil {
  114. log.Error("Socks failed to read request: %v", err)
  115. return err
  116. }
  117. if request.Command == protocol.CmdUdpAssociate && server.config.UDPEnabled {
  118. return server.handleUDP(reader, writer)
  119. }
  120. if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
  121. response := protocol.NewSocks5Response()
  122. response.Error = protocol.ErrorCommandNotSupported
  123. responseBuffer := alloc.NewSmallBuffer().Clear()
  124. response.Write(responseBuffer)
  125. _, err = writer.Write(responseBuffer.Value)
  126. responseBuffer.Release()
  127. if err != nil {
  128. log.Error("Socks failed to write response: %v", err)
  129. return err
  130. }
  131. log.Warning("Unsupported socks command %d", request.Command)
  132. return UnsupportedSocksCommand
  133. }
  134. response := protocol.NewSocks5Response()
  135. response.Error = protocol.ErrorSuccess
  136. // Some SOCKS software requires a value other than dest. Let's fake one:
  137. response.Port = uint16(1717)
  138. response.AddrType = protocol.AddrTypeIPv4
  139. response.IPv4[0] = 0
  140. response.IPv4[1] = 0
  141. response.IPv4[2] = 0
  142. response.IPv4[3] = 0
  143. responseBuffer := alloc.NewSmallBuffer().Clear()
  144. response.Write(responseBuffer)
  145. _, err = writer.Write(responseBuffer.Value)
  146. responseBuffer.Release()
  147. if err != nil {
  148. log.Error("Socks failed to write response: %v", err)
  149. return err
  150. }
  151. dest := request.Destination()
  152. data, err := v2net.ReadFrom(reader, nil)
  153. if err != nil {
  154. return err
  155. }
  156. packet := v2net.NewPacket(dest, data, true)
  157. server.transport(reader, writer, packet)
  158. return nil
  159. }
  160. func (server *SocksServer) handleUDP(reader *v2net.TimeOutReader, writer io.Writer) error {
  161. response := protocol.NewSocks5Response()
  162. response.Error = protocol.ErrorSuccess
  163. udpAddr := server.getUDPAddr()
  164. response.Port = udpAddr.Port()
  165. switch {
  166. case udpAddr.IsIPv4():
  167. response.AddrType = protocol.AddrTypeIPv4
  168. copy(response.IPv4[:], udpAddr.IP())
  169. case udpAddr.IsIPv6():
  170. response.AddrType = protocol.AddrTypeIPv6
  171. copy(response.IPv6[:], udpAddr.IP())
  172. case udpAddr.IsDomain():
  173. response.AddrType = protocol.AddrTypeDomain
  174. response.Domain = udpAddr.Domain()
  175. }
  176. responseBuffer := alloc.NewSmallBuffer().Clear()
  177. response.Write(responseBuffer)
  178. _, err := writer.Write(responseBuffer.Value)
  179. responseBuffer.Release()
  180. if err != nil {
  181. log.Error("Socks failed to write response: %v", err)
  182. return err
  183. }
  184. reader.SetTimeOut(300) /* 5 minutes */
  185. v2net.ReadFrom(reader, nil) // Just in case of anything left in the socket
  186. // The TCP connection closes after this method returns. We need to wait until
  187. // the client closes it.
  188. // TODO: get notified from UDP part
  189. <-time.After(5 * time.Minute)
  190. return nil
  191. }
  192. func (server *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth protocol.Socks4AuthenticationRequest) error {
  193. result := protocol.Socks4RequestGranted
  194. if auth.Command == protocol.CmdBind {
  195. result = protocol.Socks4RequestRejected
  196. }
  197. socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])
  198. responseBuffer := alloc.NewSmallBuffer().Clear()
  199. socks4Response.Write(responseBuffer)
  200. writer.Write(responseBuffer.Value)
  201. responseBuffer.Release()
  202. if result == protocol.Socks4RequestRejected {
  203. log.Warning("Unsupported socks 4 command %d", auth.Command)
  204. return UnsupportedSocksCommand
  205. }
  206. dest := v2net.NewTCPDestination(v2net.IPAddress(auth.IP[:], auth.Port))
  207. data, err := v2net.ReadFrom(reader, nil)
  208. if err != nil {
  209. return err
  210. }
  211. packet := v2net.NewPacket(dest, data, true)
  212. server.transport(reader, writer, packet)
  213. return nil
  214. }
  215. func (server *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) {
  216. ray := server.vPoint.DispatchToOutbound(firstPacket)
  217. input := ray.InboundInput()
  218. output := ray.InboundOutput()
  219. var inputFinish, outputFinish sync.Mutex
  220. inputFinish.Lock()
  221. outputFinish.Lock()
  222. go dumpInput(reader, input, &inputFinish)
  223. go dumpOutput(writer, output, &outputFinish)
  224. outputFinish.Lock()
  225. }
  226. func dumpInput(reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
  227. v2net.ReaderToChan(input, reader)
  228. finish.Unlock()
  229. close(input)
  230. }
  231. func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
  232. v2net.ChanToWriter(writer, output)
  233. finish.Unlock()
  234. }