github.com/sagernet/sing-tun@v0.3.0-beta.5/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 for _, address := range o.Inet4Address { 113 if address.Bits() < 32 { 114 inet4Ranges = append(inet4Ranges, netipx.RangeOfPrefix(address).Prefixes()...) 115 } 116 } 117 } else if autoRouteUseSubRanges && !underNetworkExtension { 118 inet4Ranges = []netip.Prefix{ 119 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 1}), 8), 120 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 2}), 7), 121 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 4}), 6), 122 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 8}), 5), 123 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 16}), 4), 124 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 32}), 3), 125 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 64}), 2), 126 netip.PrefixFrom(netip.AddrFrom4([4]byte{0: 128}), 1), 127 } 128 } else { 129 inet4Ranges = []netip.Prefix{netip.PrefixFrom(netip.IPv4Unspecified(), 0)} 130 } 131 if len(o.Inet4RouteExcludeAddress) == 0 { 132 routeRanges = append(routeRanges, inet4Ranges...) 133 } else { 134 var builder netipx.IPSetBuilder 135 for _, inet4Range := range inet4Ranges { 136 builder.AddPrefix(inet4Range) 137 } 138 for _, prefix := range o.Inet4RouteExcludeAddress { 139 builder.RemovePrefix(prefix) 140 } 141 resultSet, err := builder.IPSet() 142 if err != nil { 143 return nil, E.Cause(err, "build IPv4 route address") 144 } 145 routeRanges = append(routeRanges, resultSet.Prefixes()...) 146 } 147 } 148 if len(o.Inet6Address) > 0 { 149 var inet6Ranges []netip.Prefix 150 if len(o.Inet6RouteAddress) > 0 { 151 inet6Ranges = o.Inet6RouteAddress 152 for _, address := range o.Inet6Address { 153 if address.Bits() < 32 { 154 inet6Ranges = append(inet6Ranges, netipx.RangeOfPrefix(address).Prefixes()...) 155 } 156 } 157 } else if autoRouteUseSubRanges && !underNetworkExtension { 158 inet6Ranges = []netip.Prefix{ 159 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 1}), 8), 160 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 2}), 7), 161 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 4}), 6), 162 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 8}), 5), 163 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 16}), 4), 164 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 32}), 3), 165 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 64}), 2), 166 netip.PrefixFrom(netip.AddrFrom16([16]byte{0: 128}), 1), 167 } 168 } else { 169 inet6Ranges = []netip.Prefix{netip.PrefixFrom(netip.IPv6Unspecified(), 0)} 170 } 171 if len(o.Inet6RouteExcludeAddress) == 0 { 172 routeRanges = append(routeRanges, inet6Ranges...) 173 } else { 174 var builder netipx.IPSetBuilder 175 for _, inet6Range := range inet6Ranges { 176 builder.AddPrefix(inet6Range) 177 } 178 for _, prefix := range o.Inet6RouteExcludeAddress { 179 builder.RemovePrefix(prefix) 180 } 181 resultSet, err := builder.IPSet() 182 if err != nil { 183 return nil, E.Cause(err, "build IPv6 route address") 184 } 185 routeRanges = append(routeRanges, resultSet.Prefixes()...) 186 } 187 } 188 return routeRanges, nil 189 }