skipped 1 lines 2 2 3 3 import ( 4 4 "context" 5 - "io" 6 5 "net" 7 - "net/http" 8 6 "net/netip" 9 7 "net/url" 10 8 "os" 11 9 "os/user" 12 - "path/filepath" 13 10 "strings" 14 11 "time" 15 12 skipped 21 lines 37 34 F "github.com/sagernet/sing/common/format" 38 35 M "github.com/sagernet/sing/common/metadata" 39 36 N "github.com/sagernet/sing/common/network" 40 - "github.com/sagernet/sing/common/rw" 41 37 "github.com/sagernet/sing/common/uot" 42 38 ) 43 39 skipped 28 lines 72 68 outbounds []adapter.Outbound 73 69 outboundByTag map[string]adapter.Outbound 74 70 rules []adapter.Rule 71 + ipRules []adapter.IPRule 75 72 defaultDetour string 76 73 defaultOutboundForConnection adapter.Outbound 77 74 defaultOutboundForPacketConnection adapter.Outbound skipped 51 lines 129 126 dnsLogger: logFactory.NewLogger("dns"), 130 127 outboundByTag: make(map[string]adapter.Outbound), 131 128 rules: make([]adapter.Rule, 0, len(options.Rules)), 129 + ipRules: make([]adapter.IPRule, 0, len(options.IPRules)), 132 130 dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)), 133 131 needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule), 134 132 needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule), skipped 15 lines 150 148 } 151 149 router.rules = append(router.rules, routeRule) 152 150 } 151 + for i, ipRuleOptions := range options.IPRules { 152 + ipRule, err := NewIPRule(router, router.logger, ipRuleOptions) 153 + if err != nil { 154 + return nil, E.Cause(err, "parse ip rule[", i, "]") 155 + } 156 + router.ipRules = append(router.ipRules, ipRule) 157 + } 153 158 for i, dnsRuleOptions := range dnsOptions.Rules { 154 159 dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions) 155 160 if err != nil { skipped 1 lines 157 162 } 158 163 router.dnsRules = append(router.dnsRules, dnsRule) 159 164 } 165 + 160 166 transports := make([]dns.Transport, len(dnsOptions.Servers)) 161 167 dummyTransportMap := make(map[string]dns.Transport) 162 168 transportMap := make(map[string]dns.Transport) skipped 356 lines 519 525 r.packageManager, 520 526 r.timeService, 521 527 ) 522 - } 523 - 524 - func (r *Router) GeoIPReader() *geoip.Reader { 525 - return r.geoIPReader 526 - } 527 - 528 - func (r *Router) LoadGeosite(code string) (adapter.Rule, error) { 529 - rule, cached := r.geositeCache[code] 530 - if cached { 531 - return rule, nil 532 - } 533 - items, err := r.geositeReader.Read(code) 534 - if err != nil { 535 - return nil, err 536 - } 537 - rule, err = NewDefaultRule(r, nil, geosite.Compile(items)) 538 - if err != nil { 539 - return nil, err 540 - } 541 - r.geositeCache[code] = rule 542 - return rule, nil 543 528 } 544 529 545 530 func (r *Router) Outbound(tag string) (adapter.Outbound, bool) { skipped 173 lines 719 704 } 720 705 conn = bufio.NewCachedPacketConn(conn, buffer, destination) 721 706 } 707 + if r.dnsReverseMapping != nil && metadata.Domain == "" { 708 + domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr) 709 + if loaded { 710 + metadata.Domain = domain 711 + r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain) 712 + } 713 + } 722 714 if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS { 723 715 addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)) 724 716 if err != nil { skipped 100 lines 825 817 return r.rules 826 818 } 827 819 820 + func (r *Router) IPRules() []adapter.IPRule { 821 + return r.ipRules 822 + } 823 + 828 824 func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor { 829 825 return r.networkMonitor 830 826 } skipped 27 lines 858 854 859 855 func (r *Router) SetV2RayServer(server adapter.V2RayServer) { 860 856 r.v2rayServer = server 861 - } 862 - 863 - func hasRule(rules []option.Rule, cond func(rule option.DefaultRule) bool) bool { 864 - for _, rule := range rules { 865 - switch rule.Type { 866 - case C.RuleTypeDefault: 867 - if cond(rule.DefaultOptions) { 868 - return true 869 - } 870 - case C.RuleTypeLogical: 871 - for _, subRule := range rule.LogicalOptions.Rules { 872 - if cond(subRule) { 873 - return true 874 - } 875 - } 876 - } 877 - } 878 - return false 879 - } 880 - 881 - func hasDNSRule(rules []option.DNSRule, cond func(rule option.DefaultDNSRule) bool) bool { 882 - for _, rule := range rules { 883 - switch rule.Type { 884 - case C.RuleTypeDefault: 885 - if cond(rule.DefaultOptions) { 886 - return true 887 - } 888 - case C.RuleTypeLogical: 889 - for _, subRule := range rule.LogicalOptions.Rules { 890 - if cond(subRule) { 891 - return true 892 - } 893 - } 894 - } 895 - } 896 - return false 897 - } 898 - 899 - func isGeoIPRule(rule option.DefaultRule) bool { 900 - return len(rule.SourceGeoIP) > 0 && common.Any(rule.SourceGeoIP, notPrivateNode) || len(rule.GeoIP) > 0 && common.Any(rule.GeoIP, notPrivateNode) 901 - } 902 - 903 - func isGeoIPDNSRule(rule option.DefaultDNSRule) bool { 904 - return len(rule.SourceGeoIP) > 0 && common.Any(rule.SourceGeoIP, notPrivateNode) 905 - } 906 - 907 - func isGeositeRule(rule option.DefaultRule) bool { 908 - return len(rule.Geosite) > 0 909 - } 910 - 911 - func isGeositeDNSRule(rule option.DefaultDNSRule) bool { 912 - return len(rule.Geosite) > 0 913 - } 914 - 915 - func isProcessRule(rule option.DefaultRule) bool { 916 - return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0 917 - } 918 - 919 - func isProcessDNSRule(rule option.DefaultDNSRule) bool { 920 - return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0 921 - } 922 - 923 - func notPrivateNode(code string) bool { 924 - return code != "private" 925 - } 926 - 927 - func (r *Router) prepareGeoIPDatabase() error { 928 - var geoPath string 929 - if r.geoIPOptions.Path != "" { 930 - geoPath = r.geoIPOptions.Path 931 - } else { 932 - geoPath = "geoip.db" 933 - if foundPath, loaded := C.FindPath(geoPath); loaded { 934 - geoPath = foundPath 935 - } 936 - } 937 - geoPath = C.BasePath(geoPath) 938 - if !rw.FileExists(geoPath) { 939 - r.logger.Warn("geoip database not exists: ", geoPath) 940 - var err error 941 - for attempts := 0; attempts < 3; attempts++ { 942 - err = r.downloadGeoIPDatabase(geoPath) 943 - if err == nil { 944 - break 945 - } 946 - r.logger.Error("download geoip database: ", err) 947 - os.Remove(geoPath) 948 - // time.Sleep(10 * time.Second) 949 - } 950 - if err != nil { 951 - return err 952 - } 953 - } 954 - geoReader, codes, err := geoip.Open(geoPath) 955 - if err != nil { 956 - return E.Cause(err, "open geoip database") 957 - } 958 - r.logger.Info("loaded geoip database: ", len(codes), " codes") 959 - r.geoIPReader = geoReader 960 - return nil 961 - } 962 - 963 - func (r *Router) prepareGeositeDatabase() error { 964 - var geoPath string 965 - if r.geositeOptions.Path != "" { 966 - geoPath = r.geositeOptions.Path 967 - } else { 968 - geoPath = "geosite.db" 969 - if foundPath, loaded := C.FindPath(geoPath); loaded { 970 - geoPath = foundPath 971 - } 972 - } 973 - geoPath = C.BasePath(geoPath) 974 - if !rw.FileExists(geoPath) { 975 - r.logger.Warn("geosite database not exists: ", geoPath) 976 - var err error 977 - for attempts := 0; attempts < 3; attempts++ { 978 - err = r.downloadGeositeDatabase(geoPath) 979 - if err == nil { 980 - break 981 - } 982 - r.logger.Error("download geosite database: ", err) 983 - os.Remove(geoPath) 984 - // time.Sleep(10 * time.Second) 985 - } 986 - if err != nil { 987 - return err 988 - } 989 - } 990 - geoReader, codes, err := geosite.Open(geoPath) 991 - if err == nil { 992 - r.logger.Info("loaded geosite database: ", len(codes), " codes") 993 - r.geositeReader = geoReader 994 - } else { 995 - return E.Cause(err, "open geosite database") 996 - } 997 - return nil 998 - } 999 - 1000 - func (r *Router) downloadGeoIPDatabase(savePath string) error { 1001 - var downloadURL string 1002 - if r.geoIPOptions.DownloadURL != "" { 1003 - downloadURL = r.geoIPOptions.DownloadURL 1004 - } else { 1005 - downloadURL = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db" 1006 - } 1007 - r.logger.Info("downloading geoip database") 1008 - var detour adapter.Outbound 1009 - if r.geoIPOptions.DownloadDetour != "" { 1010 - outbound, loaded := r.Outbound(r.geoIPOptions.DownloadDetour) 1011 - if !loaded { 1012 - return E.New("detour outbound not found: ", r.geoIPOptions.DownloadDetour) 1013 - } 1014 - detour = outbound 1015 - } else { 1016 - detour = r.defaultOutboundForConnection 1017 - } 1018 - 1019 - if parentDir := filepath.Dir(savePath); parentDir != "" { 1020 - os.MkdirAll(parentDir, 0o755) 1021 - } 1022 - 1023 - saveFile, err := os.OpenFile(savePath, os.O_CREATE|os.O_WRONLY, 0o644) 1024 - if err != nil { 1025 - return E.Cause(err, "open output file: ", downloadURL) 1026 - } 1027 - defer saveFile.Close() 1028 - 1029 - httpClient := &http.Client{ 1030 - Transport: &http.Transport{ 1031 - ForceAttemptHTTP2: true, 1032 - TLSHandshakeTimeout: 5 * time.Second, 1033 - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { 1034 - return detour.DialContext(ctx, network, M.ParseSocksaddr(addr)) 1035 - }, 1036 - }, 1037 - } 1038 - defer httpClient.CloseIdleConnections() 1039 - response, err := httpClient.Get(downloadURL) 1040 - if err != nil { 1041 - return err 1042 - } 1043 - defer response.Body.Close() 1044 - _, err = io.Copy(saveFile, response.Body) 1045 - return err 1046 - } 1047 - 1048 - func (r *Router) downloadGeositeDatabase(savePath string) error { 1049 - var downloadURL string 1050 - if r.geositeOptions.DownloadURL != "" { 1051 - downloadURL = r.geositeOptions.DownloadURL 1052 - } else { 1053 - downloadURL = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db" 1054 - } 1055 - r.logger.Info("downloading geosite database") 1056 - var detour adapter.Outbound 1057 - if r.geositeOptions.DownloadDetour != "" { 1058 - outbound, loaded := r.Outbound(r.geositeOptions.DownloadDetour) 1059 - if !loaded { 1060 - return E.New("detour outbound not found: ", r.geositeOptions.DownloadDetour) 1061 - } 1062 - detour = outbound 1063 - } else { 1064 - detour = r.defaultOutboundForConnection 1065 - } 1066 - 1067 - if parentDir := filepath.Dir(savePath); parentDir != "" { 1068 - os.MkdirAll(parentDir, 0o755) 1069 - } 1070 - 1071 - saveFile, err := os.OpenFile(savePath, os.O_CREATE|os.O_WRONLY, 0o644) 1072 - if err != nil { 1073 - return E.Cause(err, "open output file: ", downloadURL) 1074 - } 1075 - defer saveFile.Close() 1076 - 1077 - httpClient := &http.Client{ 1078 - Transport: &http.Transport{ 1079 - ForceAttemptHTTP2: true, 1080 - TLSHandshakeTimeout: 5 * time.Second, 1081 - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { 1082 - return detour.DialContext(ctx, network, M.ParseSocksaddr(addr)) 1083 - }, 1084 - }, 1085 - } 1086 - defer httpClient.CloseIdleConnections() 1087 - response, err := httpClient.Get(downloadURL) 1088 - if err != nil { 1089 - return err 1090 - } 1091 - defer response.Body.Close() 1092 - _, err = io.Copy(saveFile, response.Body) 1093 - return err 1094 857 } 1095 858 1096 859 func (r *Router) OnPackagesUpdated(packages int, sharedUsers int) { skipped 37 lines