service.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package libbox
  2. import (
  3. "context"
  4. "net/netip"
  5. "runtime"
  6. "syscall"
  7. "github.com/sagernet/sing-box"
  8. "github.com/sagernet/sing-box/common/process"
  9. "github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
  10. "github.com/sagernet/sing-box/experimental/libbox/platform"
  11. "github.com/sagernet/sing-box/option"
  12. "github.com/sagernet/sing-tun"
  13. "github.com/sagernet/sing/common/control"
  14. E "github.com/sagernet/sing/common/exceptions"
  15. N "github.com/sagernet/sing/common/network"
  16. )
  17. type BoxService struct {
  18. ctx context.Context
  19. cancel context.CancelFunc
  20. instance *box.Box
  21. }
  22. func NewService(configContent string, platformInterface PlatformInterface) (*BoxService, error) {
  23. options, err := parseConfig(configContent)
  24. if err != nil {
  25. return nil, err
  26. }
  27. platformInterface.WriteLog("Hello " + runtime.GOOS + "/" + runtime.GOARCH)
  28. ctx, cancel := context.WithCancel(context.Background())
  29. instance, err := box.New(ctx, options, &platformInterfaceWrapper{platformInterface, platformInterface.UseProcFS()})
  30. if err != nil {
  31. cancel()
  32. return nil, E.Cause(err, "create service")
  33. }
  34. return &BoxService{
  35. ctx: ctx,
  36. cancel: cancel,
  37. instance: instance,
  38. }, nil
  39. }
  40. func (s *BoxService) Start() error {
  41. return s.instance.Start()
  42. }
  43. func (s *BoxService) Close() error {
  44. s.cancel()
  45. return s.instance.Close()
  46. }
  47. var _ platform.Interface = (*platformInterfaceWrapper)(nil)
  48. type platformInterfaceWrapper struct {
  49. iif PlatformInterface
  50. useProcFS bool
  51. }
  52. func (w *platformInterfaceWrapper) AutoDetectInterfaceControl() control.Func {
  53. return func(network, address string, conn syscall.RawConn) error {
  54. return control.Raw(conn, func(fd uintptr) error {
  55. return w.iif.AutoDetectInterfaceControl(int32(fd))
  56. })
  57. }
  58. }
  59. func (w *platformInterfaceWrapper) OpenTun(options tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) {
  60. if len(options.IncludeUID) > 0 || len(options.ExcludeUID) > 0 {
  61. return nil, E.New("android: unsupported uid options")
  62. }
  63. if len(options.IncludeAndroidUser) > 0 {
  64. return nil, E.New("android: unsupported android_user option")
  65. }
  66. tunFd, err := w.iif.OpenTun(&tunOptions{options, platformOptions})
  67. if err != nil {
  68. return nil, err
  69. }
  70. options.FileDescriptor = int(tunFd)
  71. return tun.New(options)
  72. }
  73. func (w *platformInterfaceWrapper) Write(p []byte) (n int, err error) {
  74. w.iif.WriteLog(string(p))
  75. return len(p), nil
  76. }
  77. func (w *platformInterfaceWrapper) FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*process.Info, error) {
  78. var uid int32
  79. if w.useProcFS {
  80. uid = procfs.ResolveSocketByProcSearch(network, source, destination)
  81. if uid == -1 {
  82. return nil, E.New("procfs: not found")
  83. }
  84. } else {
  85. var ipProtocol int32
  86. switch N.NetworkName(network) {
  87. case N.NetworkTCP:
  88. ipProtocol = syscall.IPPROTO_TCP
  89. case N.NetworkUDP:
  90. ipProtocol = syscall.IPPROTO_UDP
  91. default:
  92. return nil, E.New("unknown network: ", network)
  93. }
  94. var err error
  95. uid, err = w.iif.FindConnectionOwner(ipProtocol, source.Addr().String(), int32(source.Port()), destination.Addr().String(), int32(destination.Port()))
  96. if err != nil {
  97. return nil, err
  98. }
  99. }
  100. packageName, _ := w.iif.PackageNameByUid(uid)
  101. return &process.Info{UserId: uid, PackageName: packageName}, nil
  102. }