ソースを参照

Fix CloudMounter

SukkaW 1 年間 前
コミット
64552966dd
3 ファイル変更34 行追加5 行削除
  1. 1 1
      Build/build-cloudmounter-rules.ts
  2. 13 0
      Build/lib/clash.ts
  3. 20 4
      Build/lib/singbox.ts

+ 1 - 1
Build/build-cloudmounter-rules.ts

@@ -19,7 +19,7 @@ export const buildCloudMounterRules = task(require.main === module, __filename)(
         '127.0.0.0/8',
         '127.0.0.0/8',
         '172.16.0.0/12',
         '172.16.0.0/12',
         '192.168.0.0/16'
         '192.168.0.0/16'
-      ].map(cidr => `AND,((${domain}),(SRC-IP-CIDR,${cidr}))`)
+      ].map(cidr => `AND,((${domain}),(SRC-IP,${cidr}))`)
     ]);
     ]);
   });
   });
 
 

+ 13 - 0
Build/lib/clash.ts

@@ -1,5 +1,6 @@
 import picocolors from 'picocolors';
 import picocolors from 'picocolors';
 import { domainWildCardToRegex } from './misc';
 import { domainWildCardToRegex } from './misc';
+import { isProbablyIpv4, isProbablyIpv6 } from './is-fast-ip';
 
 
 const identity = <T>(x: T): T => x;
 const identity = <T>(x: T): T => x;
 const unsupported = Symbol('unsupported');
 const unsupported = Symbol('unsupported');
@@ -14,6 +15,18 @@ const PROCESSOR: Record<string, ((raw: string, type: string, value: string) => s
   'IP-CIDR': identity,
   'IP-CIDR': identity,
   'IP-CIDR6': identity,
   'IP-CIDR6': identity,
   'IP-ASN': identity,
   'IP-ASN': identity,
+  'SRC-IP': (_raw, _type, value) => {
+    if (value.includes('/')) {
+      return `SRC-IP-CIDR,${value}`;
+    }
+    if (isProbablyIpv4(value)) {
+      return `SRC-IP-CIDR,${value}/32`;
+    }
+    if (isProbablyIpv6(value)) {
+      return `SRC-IP-CIDR6,${value}/128`;
+    }
+    return '';
+  },
   'SRC-IP-CIDR': identity,
   'SRC-IP-CIDR': identity,
   'SRC-PORT': identity,
   'SRC-PORT': identity,
   'DST-PORT': identity,
   'DST-PORT': identity,

+ 20 - 4
Build/lib/singbox.ts

@@ -1,10 +1,11 @@
 import picocolors from 'picocolors';
 import picocolors from 'picocolors';
 import { domainWildCardToRegex } from './misc';
 import { domainWildCardToRegex } from './misc';
+import { isProbablyIpv4, isProbablyIpv6 } from './is-fast-ip';
 
 
 const unsupported = Symbol('unsupported');
 const unsupported = Symbol('unsupported');
 
 
 // https://sing-box.sagernet.org/configuration/rule-set/source-format/
 // https://sing-box.sagernet.org/configuration/rule-set/source-format/
-const PROCESSOR: Record<string, ((raw: string, type: string, value: string) => [key: keyof SingboxHeadlessRule, value: string]) | typeof unsupported> = {
+const PROCESSOR: Record<string, ((raw: string, type: string, value: string) => [key: keyof SingboxHeadlessRule, value: string] | null) | typeof unsupported> = {
   DOMAIN: (_1, _2, value) => ['domain', value],
   DOMAIN: (_1, _2, value) => ['domain', value],
   'DOMAIN-SUFFIX': (_1, _2, value) => ['domain_suffix', value],
   'DOMAIN-SUFFIX': (_1, _2, value) => ['domain_suffix', value],
   'DOMAIN-KEYWORD': (_1, _2, value) => ['domain_keyword', value],
   'DOMAIN-KEYWORD': (_1, _2, value) => ['domain_keyword', value],
@@ -13,6 +14,18 @@ const PROCESSOR: Record<string, ((raw: string, type: string, value: string) => [
   'IP-CIDR': (_1, _2, value) => ['ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'IP-CIDR': (_1, _2, value) => ['ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'IP-CIDR6': (_1, _2, value) => ['ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'IP-CIDR6': (_1, _2, value) => ['ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'IP-ASN': unsupported,
   'IP-ASN': unsupported,
+  'SRC-IP': (_1, _2, value) => {
+    if (value.includes('/')) {
+      return ['source_ip_cidr', value];
+    }
+    if (isProbablyIpv4(value)) {
+      return ['source_ip_cidr', value + '/32'];
+    }
+    if (isProbablyIpv6(value)) {
+      return ['source_ip_cidr', value + '/128'];
+    }
+    return null;
+  },
   'SRC-IP-CIDR': (_1, _2, value) => ['source_ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'SRC-IP-CIDR': (_1, _2, value) => ['source_ip_cidr', value.endsWith(',no-resolve') ? value.slice(0, -11) : value],
   'SRC-PORT': (_1, _2, value) => ['source_port', value],
   'SRC-PORT': (_1, _2, value) => ['source_port', value],
   'DST-PORT': (_1, _2, value) => ['port', value],
   'DST-PORT': (_1, _2, value) => ['port', value],
@@ -63,9 +76,12 @@ export const surgeRulesetToSingbox = (rules: string[] | Set<string>): SingboxSou
     if (type in PROCESSOR) {
     if (type in PROCESSOR) {
       const proc = PROCESSOR[type];
       const proc = PROCESSOR[type];
       if (proc !== unsupported) {
       if (proc !== unsupported) {
-        const [k, v] = proc(cur, type, value);
-        acc[k] ||= [];
-        acc[k].push(v);
+        const r = proc(cur, type, value);
+        if (r) {
+          const [k, v] = r;
+          acc[k] ||= [];
+          acc[k].push(v);
+        }
       }
       }
     } else {
     } else {
       console.log(picocolors.yellow(`[sing-box] unknown rule type: ${type}`), cur);
       console.log(picocolors.yellow(`[sing-box] unknown rule type: ${type}`), cur);