Browse Source

Protocol/Network rule support

SukkaW 10 months ago
parent
commit
76f56fa0e0

+ 7 - 0
Build/lib/rules/base.ts

@@ -34,6 +34,7 @@ export class FileOutput {
   protected sourceIpOrCidr = new Set<string>();
   protected sourcePort = new Set<string>();
   protected destPort = new Set<string>();
+  protected protocol = new Set<string>();
 
   protected otherRules: string[] = [];
 
@@ -199,6 +200,9 @@ export class FileOutput {
         case 'DEST-PORT':
           this.destPort.add(value);
           break;
+        case 'PROTOCOL':
+          this.protocol.add(value.toUpperCase());
+          break;
         default:
           this.otherRules.push(line);
           break;
@@ -327,6 +331,9 @@ export class FileOutput {
       if (this.domainWildcard.size) {
         strategy.writeDomainWildcards(this.domainWildcard);
       }
+      if (this.protocol.size) {
+        strategy.writeProtocols(this.protocol);
+      }
       if (this.userAgent.size) {
         strategy.writeUserAgents(this.userAgent);
       }

+ 1 - 0
Build/lib/writing-strategy/adguardhome.ts

@@ -105,5 +105,6 @@ export class AdGuardHome extends BaseWriteStrategy {
   writeSourceIpCidrs = notSupported('writeSourceIpCidrs');
   writeSourcePorts = notSupported('writeSourcePorts');
   writeDestinationPorts = noop;
+  writeProtocols = noop;
   writeOtherRules = noop;
 }

+ 1 - 0
Build/lib/writing-strategy/base.ts

@@ -42,6 +42,7 @@ export abstract class BaseWriteStrategy {
   abstract writeSourceIpCidrs(sourceIpCidr: string[]): void;
   abstract writeSourcePorts(port: Set<string>): void;
   abstract writeDestinationPorts(port: Set<string>): void;
+  abstract writeProtocols(protocol: Set<string>): void;
   abstract writeOtherRules(rule: string[]): void;
 
   protected abstract withPadding(title: string, description: string[] | readonly string[], date: Date, content: string[]): string[];

+ 14 - 0
Build/lib/writing-strategy/clash.ts

@@ -41,6 +41,7 @@ export class ClashDomainSet extends BaseWriteStrategy {
   writeSourceIpCidrs = noop;
   writeSourcePorts = noop;
   writeDestinationPorts = noop;
+  writeProtocols = noop;
   writeOtherRules = noop;
 }
 
@@ -80,6 +81,7 @@ export class ClashIPSet extends BaseWriteStrategy {
   writeSourceIpCidrs = notSupported('writeSourceIpCidrs');
   writeSourcePorts = notSupported('writeSourcePorts');
   writeDestinationPorts = noop;
+  writeProtocols = noop;
   writeOtherRules = noop;
 }
 
@@ -171,5 +173,17 @@ export class ClashClassicRuleSet extends BaseWriteStrategy {
     appendSetElementsToArray(this.result, port, i => `DST-PORT,${i}`);
   }
 
+  writeProtocols(protocol: Set<string>): void {
+    // Mihomo only matches UDP/TCP: https://wiki.metacubex.one/en/config/rules/#network
+
+    // protocol has already be normalized and will only contain upppercase
+    if (protocol.has('UDP')) {
+      this.result.push('NETWORK,UDP');
+    }
+    if (protocol.has('TCP')) {
+      this.result.push('NETWORK,TCP');
+    }
+  }
+
   writeOtherRules = noop;
 }

+ 13 - 1
Build/lib/writing-strategy/singbox.ts

@@ -17,7 +17,8 @@ interface SingboxHeadlessRule {
   port?: number[],
   port_range?: string[],
   process_name?: string[],
-  process_path?: string[]
+  process_path?: string[],
+  network?: string[]
 }
 
 export interface SingboxSourceFormat {
@@ -154,5 +155,16 @@ export class SingboxSource extends BaseWriteStrategy {
     }
   }
 
+  writeProtocols(protocol: Set<string>): void {
+    this.singbox.network ??= [];
+    // protocol has already be normalized and will only be uppercase
+    if (protocol.has('UDP')) {
+      this.singbox.network.push('udp');
+    }
+    if (protocol.has('TCP')) {
+      this.singbox.network.push('tcp');
+    }
+  }
+
   writeOtherRules = noop;
 }

+ 6 - 0
Build/lib/writing-strategy/surge.ts

@@ -44,6 +44,7 @@ export class SurgeDomainSet extends BaseWriteStrategy {
   writeSourceIpCidrs = noop;
   writeSourcePorts = noop;
   writeDestinationPorts = noop;
+  writeProtocols = noop;
   writeOtherRules = noop;
 }
 
@@ -130,6 +131,10 @@ export class SurgeRuleSet extends BaseWriteStrategy {
     appendSetElementsToArray(this.result, port, i => `DEST-PORT,${i}`);
   }
 
+  writeProtocols(protocol: Set<string>): void {
+    appendSetElementsToArray(this.result, protocol, i => `PROTOCOL,${i}`);
+  }
+
   writeOtherRules(rule: string[]): void {
     appendArrayInPlace(this.result, rule);
   }
@@ -268,5 +273,6 @@ export class SurgeMitmSgmodule extends BaseWriteStrategy {
   writeSourceIpCidrs = noop;
   writeSourcePorts = noop;
   writeDestinationPorts = noop;
+  writeProtocols = noop;
   writeOtherRules = noop;
 }