socks.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package socks
  2. import (
  3. "errors"
  4. "net"
  5. socksio "github.com/v2ray/v2ray-core/io/socks"
  6. )
  7. var (
  8. ErrorAuthenticationFailed = errors.New("None of the authentication methods is allowed.")
  9. ErrorCommandNotSupported = errors.New("Client requested an unsupported command.")
  10. )
  11. // SocksServer is a SOCKS 5 proxy server
  12. type SocksServer struct {
  13. accepting bool
  14. }
  15. func (server *SocksServer) Listen(port uint8) error {
  16. listener, err := net.Listen("tcp", ":"+string(port))
  17. if err != nil {
  18. return err
  19. }
  20. server.accepting = true
  21. go server.AcceptConnections(listener)
  22. return nil
  23. }
  24. func (server *SocksServer) AcceptConnections(listener net.Listener) error {
  25. for server.accepting {
  26. connection, err := listener.Accept()
  27. if err != nil {
  28. return err
  29. }
  30. go server.HandleConnection(connection)
  31. }
  32. return nil
  33. }
  34. func (server *SocksServer) HandleConnection(connection net.Conn) error {
  35. defer connection.Close()
  36. auth, err := socksio.ReadAuthentication(connection)
  37. if err != nil {
  38. return err
  39. }
  40. if auth.HasAuthMethod(socksio.AuthNotRequired) {
  41. return ErrorAuthenticationFailed
  42. }
  43. authResponse := socksio.NewAuthenticationResponse(socksio.AuthNotRequired)
  44. socksio.WriteAuthentication(connection, authResponse)
  45. request, err := socksio.ReadRequest(connection)
  46. if err != nil {
  47. return err
  48. }
  49. if request.Command == socksio.CmdBind || request.Command == socksio.CmdUdpAssociate {
  50. response := socksio.NewSocks5Response()
  51. response.Error = socksio.ErrorCommandNotSupported
  52. socksio.WriteResponse(connection, response)
  53. return ErrorCommandNotSupported
  54. }
  55. // TODO: establish connection with VNext
  56. return nil
  57. }