service.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package libbox
  2. import (
  3. "context"
  4. "net/netip"
  5. "runtime"
  6. "sync"
  7. "syscall"
  8. "github.com/sagernet/sing-box/adapter"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing-box/daemon"
  11. "github.com/sagernet/sing-box/dns"
  12. "github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
  13. "github.com/sagernet/sing-box/log"
  14. "github.com/sagernet/sing-box/option"
  15. tun "github.com/sagernet/sing-tun"
  16. "github.com/sagernet/sing/common"
  17. "github.com/sagernet/sing/common/control"
  18. E "github.com/sagernet/sing/common/exceptions"
  19. "github.com/sagernet/sing/common/logger"
  20. )
  21. var _ daemon.PlatformInterface = (*platformInterfaceWrapper)(nil)
  22. type platformInterfaceWrapper struct {
  23. iif PlatformInterface
  24. useProcFS bool
  25. networkManager adapter.NetworkManager
  26. myTunName string
  27. defaultInterfaceAccess sync.Mutex
  28. defaultInterface *control.Interface
  29. isExpensive bool
  30. isConstrained bool
  31. }
  32. func (w *platformInterfaceWrapper) Initialize(networkManager adapter.NetworkManager) error {
  33. w.networkManager = networkManager
  34. return nil
  35. }
  36. func (w *platformInterfaceWrapper) UsePlatformAutoDetectInterfaceControl() bool {
  37. return w.iif.UsePlatformAutoDetectInterfaceControl()
  38. }
  39. func (w *platformInterfaceWrapper) AutoDetectInterfaceControl(fd int) error {
  40. return w.iif.AutoDetectInterfaceControl(int32(fd))
  41. }
  42. func (w *platformInterfaceWrapper) UsePlatformInterface() bool {
  43. return true
  44. }
  45. func (w *platformInterfaceWrapper) OpenInterface(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) {
  46. if len(options.IncludeUID) > 0 || len(options.ExcludeUID) > 0 {
  47. return nil, E.New("platform: unsupported uid options")
  48. }
  49. if len(options.IncludeAndroidUser) > 0 {
  50. return nil, E.New("platform: unsupported android_user option")
  51. }
  52. routeRanges, err := options.BuildAutoRouteRanges(true)
  53. if err != nil {
  54. return nil, err
  55. }
  56. tunFd, err := w.iif.OpenTun(&tunOptions{options, routeRanges, platformOptions})
  57. if err != nil {
  58. return nil, err
  59. }
  60. options.Name, err = getTunnelName(tunFd)
  61. if err != nil {
  62. return nil, E.Cause(err, "query tun name")
  63. }
  64. options.InterfaceMonitor.RegisterMyInterface(options.Name)
  65. dupFd, err := dup(int(tunFd))
  66. if err != nil {
  67. return nil, E.Cause(err, "dup tun file descriptor")
  68. }
  69. options.FileDescriptor = dupFd
  70. w.myTunName = options.Name
  71. return tun.New(*options)
  72. }
  73. func (w *platformInterfaceWrapper) UsePlatformDefaultInterfaceMonitor() bool {
  74. return true
  75. }
  76. func (w *platformInterfaceWrapper) CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor {
  77. return &platformDefaultInterfaceMonitor{
  78. platformInterfaceWrapper: w,
  79. logger: logger,
  80. }
  81. }
  82. func (w *platformInterfaceWrapper) UsePlatformNetworkInterfaces() bool {
  83. return true
  84. }
  85. func (w *platformInterfaceWrapper) NetworkInterfaces() ([]adapter.NetworkInterface, error) {
  86. interfaceIterator, err := w.iif.GetInterfaces()
  87. if err != nil {
  88. return nil, err
  89. }
  90. var interfaces []adapter.NetworkInterface
  91. for _, netInterface := range iteratorToArray[*NetworkInterface](interfaceIterator) {
  92. if netInterface.Name == w.myTunName {
  93. continue
  94. }
  95. w.defaultInterfaceAccess.Lock()
  96. // (GOOS=windows) SA4006: this value of `isDefault` is never used
  97. // Why not used?
  98. //nolint:staticcheck
  99. isDefault := w.defaultInterface != nil && int(netInterface.Index) == w.defaultInterface.Index
  100. w.defaultInterfaceAccess.Unlock()
  101. interfaces = append(interfaces, adapter.NetworkInterface{
  102. Interface: control.Interface{
  103. Index: int(netInterface.Index),
  104. MTU: int(netInterface.MTU),
  105. Name: netInterface.Name,
  106. Addresses: common.Map(iteratorToArray[string](netInterface.Addresses), netip.MustParsePrefix),
  107. Flags: linkFlags(uint32(netInterface.Flags)),
  108. },
  109. Type: C.InterfaceType(netInterface.Type),
  110. DNSServers: iteratorToArray[string](netInterface.DNSServer),
  111. Expensive: netInterface.Metered || isDefault && w.isExpensive,
  112. Constrained: isDefault && w.isConstrained,
  113. })
  114. }
  115. return interfaces, nil
  116. }
  117. func (w *platformInterfaceWrapper) UnderNetworkExtension() bool {
  118. return w.iif.UnderNetworkExtension()
  119. }
  120. func (w *platformInterfaceWrapper) NetworkExtensionIncludeAllNetworks() bool {
  121. return w.iif.IncludeAllNetworks()
  122. }
  123. func (w *platformInterfaceWrapper) ClearDNSCache() {
  124. w.iif.ClearDNSCache()
  125. }
  126. func (w *platformInterfaceWrapper) RequestPermissionForWIFIState() error {
  127. return nil
  128. }
  129. func (w *platformInterfaceWrapper) UsePlatformWIFIMonitor() bool {
  130. return true
  131. }
  132. func (w *platformInterfaceWrapper) ReadWIFIState() adapter.WIFIState {
  133. wifiState := w.iif.ReadWIFIState()
  134. if wifiState == nil {
  135. return adapter.WIFIState{}
  136. }
  137. return (adapter.WIFIState)(*wifiState)
  138. }
  139. func (w *platformInterfaceWrapper) SystemCertificates() []string {
  140. return iteratorToArray[string](w.iif.SystemCertificates())
  141. }
  142. func (w *platformInterfaceWrapper) UsePlatformConnectionOwnerFinder() bool {
  143. return true
  144. }
  145. func (w *platformInterfaceWrapper) FindConnectionOwner(request *adapter.FindConnectionOwnerRequest) (*adapter.ConnectionOwner, error) {
  146. var uid int32
  147. if w.useProcFS {
  148. var source netip.AddrPort
  149. var destination netip.AddrPort
  150. sourceAddr, _ := netip.ParseAddr(request.SourceAddress)
  151. source = netip.AddrPortFrom(sourceAddr, uint16(request.SourcePort))
  152. destAddr, _ := netip.ParseAddr(request.DestinationAddress)
  153. destination = netip.AddrPortFrom(destAddr, uint16(request.DestinationPort))
  154. var network string
  155. switch request.IpProtocol {
  156. case int32(syscall.IPPROTO_TCP):
  157. network = "tcp"
  158. case int32(syscall.IPPROTO_UDP):
  159. network = "udp"
  160. default:
  161. return nil, E.New("unknown protocol: ", request.IpProtocol)
  162. }
  163. uid = procfs.ResolveSocketByProcSearch(network, source, destination)
  164. if uid == -1 {
  165. return nil, E.New("procfs: not found")
  166. }
  167. } else {
  168. var err error
  169. uid, err = w.iif.FindConnectionOwner(request.IpProtocol, request.SourceAddress, request.SourcePort, request.DestinationAddress, request.DestinationPort)
  170. if err != nil {
  171. return nil, err
  172. }
  173. }
  174. packageName, _ := w.iif.PackageNameByUid(uid)
  175. return &adapter.ConnectionOwner{
  176. UserId: uid,
  177. AndroidPackageName: packageName,
  178. }, nil
  179. }
  180. func (w *platformInterfaceWrapper) DisableColors() bool {
  181. return runtime.GOOS != "android"
  182. }
  183. func (w *platformInterfaceWrapper) UsePlatformNotification() bool {
  184. return true
  185. }
  186. func (w *platformInterfaceWrapper) SendNotification(notification *adapter.Notification) error {
  187. return w.iif.SendNotification((*Notification)(notification))
  188. }
  189. func (w *platformInterfaceWrapper) UsePlatformLocalDNSTransport() bool {
  190. return C.IsAndroid
  191. }
  192. func (w *platformInterfaceWrapper) LocalDNSTransport() dns.TransportConstructorFunc[option.LocalDNSServerOptions] {
  193. localTransport := w.iif.LocalDNSTransport()
  194. if localTransport == nil {
  195. return nil
  196. }
  197. return func(ctx context.Context, logger log.ContextLogger, tag string, options option.LocalDNSServerOptions) (adapter.DNSTransport, error) {
  198. return newPlatformTransport(localTransport, tag, options), nil
  199. }
  200. }