socks.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package socks
  2. import (
  3. "io"
  4. "net"
  5. "strconv"
  6. "sync"
  7. "github.com/v2ray/v2ray-core"
  8. "github.com/v2ray/v2ray-core/common/errors"
  9. "github.com/v2ray/v2ray-core/common/log"
  10. v2net "github.com/v2ray/v2ray-core/common/net"
  11. "github.com/v2ray/v2ray-core/proxy/socks/protocol"
  12. )
  13. // SocksServer is a SOCKS 5 proxy server
  14. type SocksServer struct {
  15. accepting bool
  16. vPoint *core.Point
  17. config SocksConfig
  18. }
  19. func NewSocksServer(vp *core.Point, rawConfig []byte) *SocksServer {
  20. config, err := loadConfig(rawConfig)
  21. if err != nil {
  22. log.Error("Unable to load socks config: %v", err)
  23. panic(errors.NewConfigurationError())
  24. }
  25. return &SocksServer{
  26. vPoint: vp,
  27. config: config,
  28. }
  29. }
  30. func (server *SocksServer) Listen(port uint16) error {
  31. listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
  32. if err != nil {
  33. log.Error("Socks failed to listen on port %d: %v", port, err)
  34. return err
  35. }
  36. server.accepting = true
  37. go server.AcceptConnections(listener)
  38. return nil
  39. }
  40. func (server *SocksServer) AcceptConnections(listener net.Listener) {
  41. for server.accepting {
  42. connection, err := listener.Accept()
  43. if err != nil {
  44. log.Error("Socks failed to accept new connection %v", err)
  45. return
  46. }
  47. go server.HandleConnection(connection)
  48. }
  49. }
  50. func (server *SocksServer) HandleConnection(connection net.Conn) error {
  51. defer connection.Close()
  52. reader := v2net.NewTimeOutReader(4, connection)
  53. auth, auth4, err := protocol.ReadAuthentication(reader)
  54. if err != nil && !errors.HasCode(err, 1000) {
  55. log.Error("Socks failed to read authentication: %v", err)
  56. return err
  57. }
  58. var dest v2net.Destination
  59. // TODO refactor this part
  60. if errors.HasCode(err, 1000) {
  61. result := protocol.Socks4RequestGranted
  62. if auth4.Command == protocol.CmdBind {
  63. result = protocol.Socks4RequestRejected
  64. }
  65. socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth4.Port, auth4.IP[:])
  66. connection.Write(socks4Response.ToBytes(nil))
  67. if result == protocol.Socks4RequestRejected {
  68. return errors.NewInvalidOperationError("Socks4 command " + strconv.Itoa(int(auth4.Command)))
  69. }
  70. dest = v2net.NewTCPDestination(v2net.IPAddress(auth4.IP[:], auth4.Port))
  71. } else {
  72. expectedAuthMethod := protocol.AuthNotRequired
  73. if server.config.AuthMethod == JsonAuthMethodUserPass {
  74. expectedAuthMethod = protocol.AuthUserPass
  75. }
  76. if !auth.HasAuthMethod(expectedAuthMethod) {
  77. authResponse := protocol.NewAuthenticationResponse(protocol.AuthNoMatchingMethod)
  78. err = protocol.WriteAuthentication(connection, authResponse)
  79. if err != nil {
  80. log.Error("Socks failed to write authentication: %v", err)
  81. return err
  82. }
  83. log.Warning("Socks client doesn't support allowed any auth methods.")
  84. return errors.NewInvalidOperationError("Unsupported auth methods.")
  85. }
  86. authResponse := protocol.NewAuthenticationResponse(expectedAuthMethod)
  87. err = protocol.WriteAuthentication(connection, authResponse)
  88. if err != nil {
  89. log.Error("Socks failed to write authentication: %v", err)
  90. return err
  91. }
  92. if server.config.AuthMethod == JsonAuthMethodUserPass {
  93. upRequest, err := protocol.ReadUserPassRequest(reader)
  94. if err != nil {
  95. log.Error("Socks failed to read username and password: %v", err)
  96. return err
  97. }
  98. status := byte(0)
  99. if !upRequest.IsValid(server.config.Username, server.config.Password) {
  100. status = byte(0xFF)
  101. }
  102. upResponse := protocol.NewSocks5UserPassResponse(status)
  103. err = protocol.WriteUserPassResponse(connection, upResponse)
  104. if err != nil {
  105. log.Error("Socks failed to write user pass response: %v", err)
  106. return err
  107. }
  108. if status != byte(0) {
  109. err = errors.NewAuthenticationError(upRequest.AuthDetail())
  110. log.Warning(err.Error())
  111. return err
  112. }
  113. }
  114. request, err := protocol.ReadRequest(reader)
  115. if err != nil {
  116. log.Error("Socks failed to read request: %v", err)
  117. return err
  118. }
  119. response := protocol.NewSocks5Response()
  120. if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
  121. response := protocol.NewSocks5Response()
  122. response.Error = protocol.ErrorCommandNotSupported
  123. err = protocol.WriteResponse(connection, response)
  124. if err != nil {
  125. log.Error("Socks failed to write response: %v", err)
  126. return err
  127. }
  128. log.Warning("Unsupported socks command %d", request.Command)
  129. return errors.NewInvalidOperationError("Socks command " + strconv.Itoa(int(request.Command)))
  130. }
  131. response.Error = protocol.ErrorSuccess
  132. response.Port = request.Port
  133. response.AddrType = request.AddrType
  134. switch response.AddrType {
  135. case protocol.AddrTypeIPv4:
  136. copy(response.IPv4[:], request.IPv4[:])
  137. case protocol.AddrTypeIPv6:
  138. copy(response.IPv6[:], request.IPv6[:])
  139. case protocol.AddrTypeDomain:
  140. response.Domain = request.Domain
  141. }
  142. err = protocol.WriteResponse(connection, response)
  143. if err != nil {
  144. log.Error("Socks failed to write response: %v", err)
  145. return err
  146. }
  147. dest = request.Destination()
  148. }
  149. ray := server.vPoint.DispatchToOutbound(v2net.NewTCPPacket(dest))
  150. input := ray.InboundInput()
  151. output := ray.InboundOutput()
  152. var readFinish, writeFinish sync.Mutex
  153. readFinish.Lock()
  154. writeFinish.Lock()
  155. go dumpInput(reader, input, &readFinish)
  156. go dumpOutput(connection, output, &writeFinish)
  157. writeFinish.Lock()
  158. return nil
  159. }
  160. func dumpInput(reader io.Reader, input chan<- []byte, finish *sync.Mutex) {
  161. v2net.ReaderToChan(input, reader)
  162. finish.Unlock()
  163. close(input)
  164. }
  165. func dumpOutput(writer io.Writer, output <-chan []byte, finish *sync.Mutex) {
  166. v2net.ChanToWriter(writer, output)
  167. finish.Unlock()
  168. }