mixed.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package inbound
  2. import (
  3. std_bufio "bufio"
  4. "context"
  5. "net"
  6. "github.com/sagernet/sing-box/adapter"
  7. "github.com/sagernet/sing-box/common/uot"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/log"
  10. "github.com/sagernet/sing-box/option"
  11. "github.com/sagernet/sing/common/auth"
  12. E "github.com/sagernet/sing/common/exceptions"
  13. N "github.com/sagernet/sing/common/network"
  14. "github.com/sagernet/sing/protocol/http"
  15. "github.com/sagernet/sing/protocol/socks"
  16. "github.com/sagernet/sing/protocol/socks/socks4"
  17. "github.com/sagernet/sing/protocol/socks/socks5"
  18. )
  19. var (
  20. _ adapter.Inbound = (*Mixed)(nil)
  21. _ adapter.TCPInjectableInbound = (*Mixed)(nil)
  22. )
  23. type Mixed struct {
  24. myInboundAdapter
  25. authenticator *auth.Authenticator
  26. }
  27. func NewMixed(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPMixedInboundOptions) *Mixed {
  28. inbound := &Mixed{
  29. myInboundAdapter{
  30. protocol: C.TypeMixed,
  31. network: []string{N.NetworkTCP},
  32. ctx: ctx,
  33. router: uot.NewRouter(router, logger),
  34. logger: logger,
  35. tag: tag,
  36. listenOptions: options.ListenOptions,
  37. setSystemProxy: options.SetSystemProxy,
  38. },
  39. auth.NewAuthenticator(options.Users),
  40. }
  41. inbound.connHandler = inbound
  42. return inbound
  43. }
  44. func (h *Mixed) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  45. err := h.newConnection(ctx, conn, metadata, onClose)
  46. N.CloseOnHandshakeFailure(conn, onClose, err)
  47. if err != nil {
  48. h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
  49. }
  50. }
  51. func (h *Mixed) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
  52. reader := std_bufio.NewReader(conn)
  53. headerBytes, err := reader.Peek(1)
  54. if err != nil {
  55. return E.Cause(err, "peek first byte")
  56. }
  57. switch headerBytes[0] {
  58. case socks4.Version, socks5.Version:
  59. return socks.HandleConnectionEx(ctx, conn, reader, h.authenticator, nil, h.upstreamUserHandlerEx(metadata), metadata.Source, metadata.Destination, onClose)
  60. default:
  61. return http.HandleConnectionEx(ctx, conn, reader, h.authenticator, nil, h.upstreamUserHandlerEx(metadata), metadata.Source, onClose)
  62. }
  63. }