github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/tun_rules.go (about) 1 package tun 2 3 import ( 4 "context" 5 "net/netip" 6 "os" 7 "runtime" 8 "sort" 9 "strconv" 10 11 "github.com/sagernet/sing/common" 12 E "github.com/sagernet/sing/common/exceptions" 13 "github.com/sagernet/sing/common/ranges" 14 15 "go4.org/netipx" 16 ) 17 18 const ( 19 androidUserRange = 100000 20 userEnd uint32 = 0xFFFFFFFF - 1 21 ) 22 23 func (o *Options) BuildAndroidRules(packageManager PackageManager, errorHandler E.Handler) { 24 var includeUser []uint32 25 if len(o.IncludeAndroidUser) > 0 { 26 o.IncludeAndroidUser = common.Uniq(o.IncludeAndroidUser) 27 sort.Ints(o.IncludeAndroidUser) 28 var userExcludeRange []ranges.Range[uint32] 29 for _, androidUser := range o.IncludeAndroidUser { 30 includeUser = append(includeUser, uint32(androidUser)) 31 userExcludeRange = append(userExcludeRange, ranges.New[uint32](uint32(androidUser)*androidUserRange, uint32(androidUser+1)*androidUserRange-1)) 32 } 33 userExcludeRange = ranges.Revert(0, userEnd, userExcludeRange) 34 o.ExcludeUID = append(o.ExcludeUID, userExcludeRange...) 35 } 36 if len(includeUser) == 0 { 37 userDirs, err := os.ReadDir("/data/user") 38 if err == nil { 39 var userId uint64 40 for _, userDir := range userDirs { 41 userId, err = strconv.ParseUint(userDir.Name(), 10, 32) 42 if err != nil { 43 continue 44 } 45 includeUser = append(includeUser, uint32(userId)) 46 } 47 } 48 } 49 if len(includeUser) == 0 { 50 includeUser = []uint32{0} 51 } 52 if len(o.IncludePackage) > 0 { 53 o.IncludePackage = common.Uniq(o.IncludePackage) 54 for _, packageName := range o.IncludePackage { 55 if sharedId, loaded := packageManager.IDBySharedPackage(packageName); loaded { 56 for _, androidUser := range includeUser { 57 o.IncludeUID = append(o.IncludeUID, ranges.NewSingle(sharedId+androidUser*androidUserRange)) 58 } 59 continue 60 } 61 if userId, loaded := packageManager.IDByPackage(packageName); loaded { 62 for _, androidUser := range includeUser { 63 o.IncludeUID = append(o.IncludeUID, ranges.NewSingle(userId+androidUser*androidUserRange)) 64 } 65 continue 66 } 67 errorHandler.NewError(context.Background(), E.New("package to include not found: ", packageName)) 68 } 69 } 70 if len(o.ExcludePackage) > 0 { 71 o.ExcludePackage = common.Uniq(o.ExcludePackage) 72 for _, packageName := range o.ExcludePackage { 73 if sharedId, loaded := packageManager.IDBySharedPackage(packageName); loaded { 74 for _, androidUser := range includeUser { 75 o.ExcludeUID = append(o.ExcludeUID, ranges.NewSingle(sharedId+androidUser*androidUserRange)) 76 } 77 } 78 if userId, loaded := packageManager.IDByPackage(packageName); loaded { 79 for _, androidUser := range includeUser { 80 o.ExcludeUID = append(o.ExcludeUID, ranges.NewSingle(userId+androidUser*androidUserRange)) 81 } 82 continue 83 } 84 errorHandler.NewError(context.Background(), E.New("package to exclude not found: ", packageName)) 85 } 86 } 87 } 88 89 func (o *Options) ExcludedRanges() (uidRanges []ranges.Range[uint32]) { 90 return buildExcludedRanges(o.IncludeUID, o.ExcludeUID) 91 } 92 93 func buildExcludedRanges(includeRanges []ranges.Range[uint32], excludeRanges []ranges.Range[uint32]) (uidRanges []ranges.Range[uint32]) { 94 uidRanges = includeRanges 95 if len(uidRanges) > 0 { 96 uidRanges = ranges.Exclude(uidRanges, excludeRanges) 97 uidRanges = ranges.Revert(0, userEnd, uidRanges) 98 } else { 99 uidRanges = excludeRanges 100 } 101 return ranges.Merge(uidRanges) 102 } 103 104 const autoRouteUseSubRanges = runtime.GOOS == "darwin" 105 106 func (o *Options) BuildAutoRouteRanges(underNetworkExtension bool) ([]netip.Prefix, error) { 107 var routeRanges []netip.Prefix 108 if o.AutoRoute && len(o.Inet4Address) > 0 { 109 var inet4Ranges []netip.Prefix 110 if len(o.Inet4RouteAddress) > 0 { 111 inet4Ranges = o.Inet4RouteAddress 112 } else if autoRouteUseSubRanges && !underNetworkExtension { 113 inet4Ranges = []netip.Prefix{ 114 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 1}), 8), 115 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 2}), 7), 116 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 4}), 6), 117 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 8}), 5), 118 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 16}), 4), 119 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 32}), 3), 120 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 64}), 2), 121 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 128}), 1), 122 } 123 } else { 124 inet4Ranges = []netip.Prefix{netip.PrefixFrom(netip.IPv4Unspecified(), 0)} 125 } 126 if len(o.Inet4RouteExcludeAddress) == 0 { 127 routeRanges = append(routeRanges, inet4Ranges...) 128 } else { 129 var builder netipx.IPSetBuilder 130 for _, inet4Range := range inet4Ranges { 131 builder.AddPrefix(inet4Range) 132 } 133 for _, prefix := range o.Inet4RouteExcludeAddress { 134 builder.RemovePrefix(prefix) 135 } 136 resultSet, err := builder.IPSet() 137 if err != nil { 138 return nil, E.Cause(err, "build IPv4 route address") 139 } 140 routeRanges = append(routeRanges, resultSet.Prefixes()...) 141 } 142 } 143 if len(o.Inet6Address) > 0 { 144 var inet6Ranges []netip.Prefix 145 if len(o.Inet6RouteAddress) > 0 { 146 inet6Ranges = o.Inet6RouteAddress 147 } else if autoRouteUseSubRanges && !underNetworkExtension { 148 inet6Ranges = []netip.Prefix{ 149 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 1}), 8), 150 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 2}), 7), 151 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 4}), 6), 152 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 8}), 5), 153 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 16}), 4), 154 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 32}), 3), 155 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 64}), 2), 156 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 128}), 1), 157 } 158 } else { 159 inet6Ranges = []netip.Prefix{netip.PrefixFrom(netip.IPv6Unspecified(), 0)} 160 } 161 if len(o.Inet6RouteExcludeAddress) == 0 { 162 routeRanges = append(routeRanges, inet6Ranges...) 163 } else { 164 var builder netipx.IPSetBuilder 165 for _, inet6Range := range inet6Ranges { 166 builder.AddPrefix(inet6Range) 167 } 168 for _, prefix := range o.Inet6RouteExcludeAddress { 169 builder.RemovePrefix(prefix) 170 } 171 resultSet, err := builder.IPSet() 172 if err != nil { 173 return nil, E.Cause(err, "build IPv6 route address") 174 } 175 routeRanges = append(routeRanges, resultSet.Prefixes()...) 176 } 177 } 178 return routeRanges, nil 179 }