1
0

redirect.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package redirect
  2. import (
  3. "context"
  4. "net"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-box/adapter/inbound"
  7. "github.com/sagernet/sing-box/common/listener"
  8. "github.com/sagernet/sing-box/common/redir"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing-box/log"
  11. "github.com/sagernet/sing-box/option"
  12. M "github.com/sagernet/sing/common/metadata"
  13. N "github.com/sagernet/sing/common/network"
  14. )
  15. func RegisterRedirect(registry *inbound.Registry) {
  16. inbound.Register[option.RedirectInboundOptions](registry, C.TypeRedirect, NewRedirect)
  17. }
  18. type Redirect struct {
  19. inbound.Adapter
  20. router adapter.Router
  21. logger log.ContextLogger
  22. listener *listener.Listener
  23. }
  24. func NewRedirect(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.RedirectInboundOptions) (adapter.Inbound, error) {
  25. redirect := &Redirect{
  26. Adapter: inbound.NewAdapter(C.TypeRedirect, tag),
  27. router: router,
  28. logger: logger,
  29. }
  30. redirect.listener = listener.New(listener.Options{
  31. Context: ctx,
  32. Logger: logger,
  33. Network: []string{N.NetworkTCP},
  34. Listen: options.ListenOptions,
  35. ConnectionHandler: redirect,
  36. })
  37. return redirect, nil
  38. }
  39. func (h *Redirect) Start(stage adapter.StartStage) error {
  40. if stage != adapter.StartStateStart {
  41. return nil
  42. }
  43. return h.listener.Start()
  44. }
  45. func (h *Redirect) Close() error {
  46. return h.listener.Close()
  47. }
  48. func (h *Redirect) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  49. destination, err := redir.GetOriginalDestination(conn)
  50. if err != nil {
  51. conn.Close()
  52. h.logger.ErrorContext(ctx, "process connection from ", conn.RemoteAddr(), ": get redirect destination: ", err)
  53. return
  54. }
  55. metadata.Inbound = h.Tag()
  56. metadata.InboundType = h.Type()
  57. metadata.Destination = M.SocksaddrFromNetIP(destination)
  58. h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  59. h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  60. }