Browse Source

fix(tuic): preserve IP destinations during sniffing (#6753)

Keep sniffed TLS domains available for routing without replacing the destination address requested by the TUIC client. Add a regression assertion for the generated relay sniffing settings.
libmur-dev 16 hours ago
parent
commit
b3f1cced70
2 changed files with 18 additions and 4 deletions
  1. 14 2
      internal/web/service/inbound_tuic_test.go
  2. 4 2
      internal/web/service/xray.go

+ 14 - 2
internal/web/service/inbound_tuic_test.go

@@ -3,6 +3,7 @@ package service
 import (
 	"encoding/json"
 	"fmt"
+	"slices"
 	"strings"
 	"testing"
 
@@ -50,8 +51,19 @@ func TestInjectTuicSocks(t *testing.T) {
 	if string(sc.Listen) != `"127.0.0.1"` {
 		t.Fatalf("expected listen 127.0.0.1, got %s", sc.Listen)
 	}
-	if string(sc.Sniffing) != tuicEgressSniffingSettings {
-		t.Fatalf("expected sniffing settings %s, got %s", tuicEgressSniffingSettings, sc.Sniffing)
+	var parsedSniffing struct {
+		Enabled      bool     `json:"enabled"`
+		DestOverride []string `json:"destOverride"`
+		RouteOnly    bool     `json:"routeOnly"`
+	}
+	if err := json.Unmarshal(sc.Sniffing, &parsedSniffing); err != nil {
+		t.Fatalf("failed to unmarshal sniffing settings: %v", err)
+	}
+	if !parsedSniffing.Enabled || !parsedSniffing.RouteOnly {
+		t.Fatalf("sniffing must be enabled with routeOnly, got %+v", parsedSniffing)
+	}
+	if want := []string{"http", "tls", "quic", "fakedns"}; !slices.Equal(parsedSniffing.DestOverride, want) {
+		t.Fatalf("destOverride = %v, want %v", parsedSniffing.DestOverride, want)
 	}
 
 	var parsedSettings struct {

+ 4 - 2
internal/web/service/xray.go

@@ -796,8 +796,10 @@ func injectAmneziawgnetSocks(cfg *xray.Config, inbounds []*model.Inbound) {
 }
 
 const (
-	tuicEgressSocksSettings    = `{"auth":"noauth","udp":true}`
-	tuicEgressSniffingSettings = `{"enabled":true,"destOverride":["http","tls","quic","fakedns"]}`
+	tuicEgressSocksSettings = `{"auth":"noauth","udp":true}`
+	// TUIC clients can connect to an IP while TLS carries a different or unresolvable SNI.
+	// Keep sniffed domains available for routing without replacing the requested destination.
+	tuicEgressSniffingSettings = `{"enabled":true,"destOverride":["http","tls","quic","fakedns"],"routeOnly":true}`
 )
 
 func injectTuicSocks(cfg *xray.Config, inbounds []*model.Inbound) {