hysteria2.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //go:build with_quic
  2. package inbound
  3. import (
  4. "context"
  5. "net"
  6. "net/http"
  7. "net/http/httputil"
  8. "net/url"
  9. "github.com/sagernet/sing-box/adapter"
  10. "github.com/sagernet/sing-box/common/tls"
  11. C "github.com/sagernet/sing-box/constant"
  12. "github.com/sagernet/sing-box/log"
  13. "github.com/sagernet/sing-box/option"
  14. "github.com/sagernet/sing-box/transport/hysteria2"
  15. "github.com/sagernet/sing/common"
  16. "github.com/sagernet/sing/common/auth"
  17. E "github.com/sagernet/sing/common/exceptions"
  18. N "github.com/sagernet/sing/common/network"
  19. )
  20. var _ adapter.Inbound = (*Hysteria2)(nil)
  21. type Hysteria2 struct {
  22. myInboundAdapter
  23. tlsConfig tls.ServerConfig
  24. server *hysteria2.Server
  25. }
  26. func NewHysteria2(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.Hysteria2InboundOptions) (*Hysteria2, error) {
  27. if options.TLS == nil || !options.TLS.Enabled {
  28. return nil, C.ErrTLSRequired
  29. }
  30. tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
  31. if err != nil {
  32. return nil, err
  33. }
  34. var salamanderPassword string
  35. if options.Obfs != nil {
  36. if options.Obfs.Password == "" {
  37. return nil, E.New("missing obfs password")
  38. }
  39. switch options.Obfs.Type {
  40. case hysteria2.ObfsTypeSalamander:
  41. salamanderPassword = options.Obfs.Password
  42. default:
  43. return nil, E.New("unknown obfs type: ", options.Obfs.Type)
  44. }
  45. }
  46. var masqueradeHandler http.Handler
  47. if options.Masquerade != "" {
  48. masqueradeURL, err := url.Parse(options.Masquerade)
  49. if err != nil {
  50. return nil, E.Cause(err, "parse masquerade URL")
  51. }
  52. switch masqueradeURL.Scheme {
  53. case "file":
  54. masqueradeHandler = http.FileServer(http.Dir(masqueradeURL.Path))
  55. case "http", "https":
  56. masqueradeHandler = &httputil.ReverseProxy{
  57. Rewrite: func(r *httputil.ProxyRequest) {
  58. r.SetURL(masqueradeURL)
  59. r.Out.Host = r.In.Host
  60. },
  61. ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
  62. w.WriteHeader(http.StatusBadGateway)
  63. },
  64. }
  65. default:
  66. return nil, E.New("unknown masquerade URL scheme: ", masqueradeURL.Scheme)
  67. }
  68. }
  69. inbound := &Hysteria2{
  70. myInboundAdapter: myInboundAdapter{
  71. protocol: C.TypeHysteria2,
  72. network: []string{N.NetworkUDP},
  73. ctx: ctx,
  74. router: router,
  75. logger: logger,
  76. tag: tag,
  77. listenOptions: options.ListenOptions,
  78. },
  79. tlsConfig: tlsConfig,
  80. }
  81. server, err := hysteria2.NewServer(hysteria2.ServerOptions{
  82. Context: ctx,
  83. Logger: logger,
  84. SendBPS: uint64(options.UpMbps * 1024 * 1024),
  85. ReceiveBPS: uint64(options.DownMbps * 1024 * 1024),
  86. SalamanderPassword: salamanderPassword,
  87. TLSConfig: tlsConfig,
  88. Users: common.Map(options.Users, func(it option.Hysteria2User) hysteria2.User {
  89. return hysteria2.User(it)
  90. }),
  91. IgnoreClientBandwidth: options.IgnoreClientBandwidth,
  92. Handler: adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, nil),
  93. MasqueradeHandler: masqueradeHandler,
  94. })
  95. if err != nil {
  96. return nil, err
  97. }
  98. inbound.server = server
  99. return inbound, nil
  100. }
  101. func (h *Hysteria2) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  102. ctx = log.ContextWithNewID(ctx)
  103. h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  104. metadata = h.createMetadata(conn, metadata)
  105. metadata.User, _ = auth.UserFromContext[string](ctx)
  106. return h.router.RouteConnection(ctx, conn, metadata)
  107. }
  108. func (h *Hysteria2) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  109. ctx = log.ContextWithNewID(ctx)
  110. metadata = h.createPacketMetadata(conn, metadata)
  111. metadata.User, _ = auth.UserFromContext[string](ctx)
  112. h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  113. return h.router.RoutePacketConnection(ctx, conn, metadata)
  114. }
  115. func (h *Hysteria2) Start() error {
  116. if h.tlsConfig != nil {
  117. err := h.tlsConfig.Start()
  118. if err != nil {
  119. return err
  120. }
  121. }
  122. packetConn, err := h.myInboundAdapter.ListenUDP()
  123. if err != nil {
  124. return err
  125. }
  126. return h.server.Start(packetConn)
  127. }
  128. func (h *Hysteria2) Close() error {
  129. return common.Close(
  130. &h.myInboundAdapter,
  131. h.tlsConfig,
  132. common.PtrOrNil(h.server),
  133. )
  134. }