Эх сурвалжийг харах

Enable QUIC obfuscated PSK with a probability

Amir Khan 1 жил өмнө
parent
commit
f98862c844

+ 2 - 2
psiphon/common/parameters/parameters.go

@@ -113,7 +113,7 @@ const (
 	LimitQUICVersions                                  = "LimitQUICVersions"
 	DisableFrontingProviderQUICVersions                = "DisableFrontingProviderQUICVersions"
 	QUICDialEarlyProbability                           = "QUICDialEarlyProbability"
-	QUICDisableObfuscatedPSK                           = "QUICDisableObfuscatedPSK"
+	QUICObfuscatedPSKProbability                       = "QUICObfuscatedPSKProbability"
 	QUICDisableClientPathMTUDiscoveryProbability       = "QUICDisableClientPathMTUDiscoveryProbability"
 	FragmentorProbability                              = "FragmentorProbability"
 	FragmentorLimitProtocols                           = "FragmentorLimitProtocols"
@@ -522,7 +522,7 @@ var defaultParameters = map[string]struct {
 	LimitQUICVersions:                            {value: protocol.QUICVersions{}},
 	DisableFrontingProviderQUICVersions:          {value: protocol.LabeledQUICVersions{}},
 	QUICDialEarlyProbability:                     {value: 1.0, minimum: 0.0},
-	QUICDisableObfuscatedPSK:                     {value: false},
+	QUICObfuscatedPSKProbability:                 {value: 0.5, minimum: 0.0},
 	QUICDisableClientPathMTUDiscoveryProbability: {value: 0.0, minimum: 0.0},
 
 	FragmentorProbability:              {value: 0.5, minimum: 0.0},

+ 2 - 1
psiphon/common/protocol/packed.go

@@ -797,8 +797,9 @@ func init() {
 		{145, "quic_sent_ticket", intConverter},
 		{146, "quic_did_resume", intConverter},
 		{147, "quic_dial_early", intConverter},
+		{148, "quic_obfuscated_psk", intConverter},
 
-		// Last key value = 147
+		// Last key value = 148
 	}
 
 	for _, spec := range packedAPIParameterSpecs {

+ 1 - 1
psiphon/common/quic/obfuscator_test.go

@@ -133,7 +133,7 @@ func runNonceTransformer(t *testing.T, quicVersion string) {
 			},
 			false,
 			false,
-			true, // Disable obfuscated PSK
+			false, // Disable obfuscated PSK
 			nil,
 		)
 

+ 17 - 9
psiphon/common/quic/quic.go

@@ -404,7 +404,7 @@ func Dial(
 	obfuscationNonceTransformerParameters *transforms.ObfuscatorSeedTransformerParameters,
 	disablePathMTUDiscovery bool,
 	dialEarly bool,
-	disableObfuscatedPSK bool,
+	useObfuscatedPSK bool,
 	tlsClientSessionCache *common.TLSClientSessionCacheWrapper) (net.Conn, error) {
 
 	if quicVersion == "" {
@@ -513,9 +513,9 @@ func Dial(
 		}
 	}
 
-	obfuscatedSessionTicketKey := obfuscationKey
-	if disableObfuscatedPSK {
-		obfuscatedSessionTicketKey = ""
+	obfuscatedPSKKey := ""
+	if useObfuscatedPSK {
+		obfuscatedPSKKey = obfuscationKey
 	}
 
 	connection, err := dialQUIC(
@@ -530,7 +530,7 @@ func Dial(
 		maxPacketSizeAdjustment,
 		disablePathMTUDiscovery,
 		dialEarly,
-		obfuscatedSessionTicketKey,
+		obfuscatedPSKKey,
 		tlsClientSessionCache)
 
 	if err != nil {
@@ -762,6 +762,12 @@ func (conn *Conn) GetMetrics() common.LogFields {
 	}
 	logFields["quic_did_resume"] = quicDidResume
 
+	obfuscatedPSK := "0"
+	if metrics.obfuscatedPSK {
+		obfuscatedPSK = "1"
+	}
+	logFields["quic_obfuscated_psk"] = obfuscatedPSK
+
 	return logFields
 }
 
@@ -1010,6 +1016,7 @@ type quicConnectionMetrics struct {
 	dialEarly           bool
 	tlsClientSentTicket bool
 	tlsDidResume        bool
+	obfuscatedPSK       bool
 }
 
 type quicConnection interface {
@@ -1121,7 +1128,7 @@ func dialQUIC(
 	clientMaxPacketSizeAdjustment int,
 	disablePathMTUDiscovery bool,
 	dialEarly bool,
-	obfuscatedSessionTicketKey string,
+	obfuscatedPSKKey string,
 	tlsClientSessionCache *common.TLSClientSessionCacheWrapper) (quicConnection, error) {
 
 	if tlsClientSessionCache == nil {
@@ -1165,11 +1172,11 @@ func dialQUIC(
 
 		// Creating a session state and storing it in the TLS cache to be used
 		// for PSK (Pre-Shared Key) resumption.
-		if obfuscatedSessionTicketKey != "" {
+		if obfuscatedPSKKey != "" {
 			var sharedSecret [32]byte
-			key, err := hex.DecodeString(obfuscatedSessionTicketKey)
+			key, err := hex.DecodeString(obfuscatedPSKKey)
 			if err == nil && len(key) != 32 {
-				err = std_errors.New("invalid obfuscated session key length")
+				err = std_errors.New("invalid obfuscated PSK key length")
 			}
 			if err != nil {
 				return nil, errors.Trace(err)
@@ -1218,6 +1225,7 @@ func dialQUIC(
 			dialEarly:           dialEarly,
 			tlsClientSentTicket: dialConnection.ConnectionState().TLS.DidResume,
 			tlsDidResume:        dialConnection.TLSConnectionMetrics().ClientSentTicket,
+			obfuscatedPSK:       obfuscatedPSKKey != "",
 		}
 
 		return &ietfQUICConnection{

+ 9 - 9
psiphon/common/quic/quic_test.go

@@ -44,23 +44,23 @@ import (
 func TestQUIC(t *testing.T) {
 	for quicVersion := range supportedVersionNumbers {
 
-		for _, disableObfuscatedPSK := range []bool{true, false} {
-			t.Run(fmt.Sprintf("%s|PSK disabled=%v", quicVersion, disableObfuscatedPSK), func(t *testing.T) {
+		for _, useObfuscatedPSK := range []bool{false, true} {
+			t.Run(fmt.Sprintf("%s|PSK=%v", quicVersion, useObfuscatedPSK), func(t *testing.T) {
 				if isGQUIC(quicVersion) && !GQUICEnabled() {
 					t.Skipf("gQUIC is not enabled")
 				}
-				runQUIC(t, quicVersion, GQUICEnabled(), disableObfuscatedPSK, false)
+				runQUIC(t, quicVersion, GQUICEnabled(), useObfuscatedPSK, false)
 			})
 			if isIETF(quicVersion) {
-				t.Run(fmt.Sprintf("%s (invoke anti-probing)|PSK disabled=%v", quicVersion, disableObfuscatedPSK), func(t *testing.T) {
+				t.Run(fmt.Sprintf("%s (invoke anti-probing)|PSK=%v", quicVersion, useObfuscatedPSK), func(t *testing.T) {
 					fmt.Printf("quic version: %s\n", quicVersion)
-					runQUIC(t, quicVersion, GQUICEnabled(), true, disableObfuscatedPSK)
+					runQUIC(t, quicVersion, GQUICEnabled(), true, useObfuscatedPSK)
 				})
 			}
 			if isIETF(quicVersion) {
-				t.Run(fmt.Sprintf("%s (disable gQUIC)|PSK disabled=%v", quicVersion, disableObfuscatedPSK), func(t *testing.T) {
+				t.Run(fmt.Sprintf("%s (disable gQUIC)|PSK=%v", quicVersion, useObfuscatedPSK), func(t *testing.T) {
 					fmt.Printf("quic version: %s\n", quicVersion)
-					runQUIC(t, quicVersion, false, false, disableObfuscatedPSK)
+					runQUIC(t, quicVersion, false, false, useObfuscatedPSK)
 				})
 			}
 		}
@@ -72,7 +72,7 @@ func runQUIC(
 	quicVersion string,
 	enableGQUIC bool,
 	invokeAntiProbing bool,
-	disableObfuscatedPSK bool) {
+	useObfuscatedPSK bool) {
 
 	initGoroutines := getGoroutines()
 
@@ -215,7 +215,7 @@ func runQUIC(
 				nil,
 				disablePathMTUDiscovery,
 				true,
-				disableObfuscatedPSK,
+				useObfuscatedPSK,
 				clientSessionCache)
 
 			if invokeAntiProbing {

+ 7 - 7
psiphon/config.go

@@ -939,8 +939,8 @@ type Config struct {
 	// QUICDialEarlyProbability is for testing purposes.
 	QUICDialEarlyProbability *float64
 
-	// QUICDisableObfuscatedPSK is for testing purposes.
-	QUICDisableObfuscatedPSK *bool
+	// QUICObfuscatedPSKProbability is for testing purposes.
+	QUICObfuscatedPSKProbability *float64
 
 	// QUICDisablePathMTUDiscoveryProbability is for testing purposes.
 	QUICDisablePathMTUDiscoveryProbability *float64
@@ -2218,8 +2218,8 @@ func (config *Config) makeConfigParameters() map[string]interface{} {
 		applyParameters[parameters.QUICDialEarlyProbability] = *config.QUICDialEarlyProbability
 	}
 
-	if config.QUICDisableObfuscatedPSK != nil {
-		applyParameters[parameters.QUICDisableObfuscatedPSK] = *config.QUICDisableObfuscatedPSK
+	if config.QUICObfuscatedPSKProbability != nil {
+		applyParameters[parameters.QUICObfuscatedPSKProbability] = *config.QUICObfuscatedPSKProbability
 	}
 
 	if config.QUICDisablePathMTUDiscoveryProbability != nil {
@@ -2983,9 +2983,9 @@ func (config *Config) setDialParametersHash() {
 		binary.Write(hash, binary.LittleEndian, *config.QUICDialEarlyProbability)
 	}
 
-	if config.QUICDisableObfuscatedPSK != nil {
-		hash.Write([]byte("QUICDisableObfuscatedPSK"))
-		binary.Write(hash, binary.LittleEndian, *config.QUICDisableObfuscatedPSK)
+	if config.QUICObfuscatedPSKProbability != nil {
+		hash.Write([]byte("QUICObfuscatedPSKProbability"))
+		binary.Write(hash, binary.LittleEndian, *config.QUICObfuscatedPSKProbability)
 	}
 
 	if config.QUICDisablePathMTUDiscoveryProbability != nil {

+ 4 - 5
psiphon/dialParameters.go

@@ -133,7 +133,7 @@ type DialParameters struct {
 	ObfuscatedQUICPaddingSeed                *prng.Seed
 	ObfuscatedQUICNonceTransformerParameters *transforms.ObfuscatorSeedTransformerParameters
 	QUICDialEarly                            bool
-	QUICDisableObfuscatedPSK                 bool
+	QUICUseObfuscatedPSK                     bool
 	QUICDisablePathMTUDiscovery              bool
 
 	ConjureCachedRegistrationTTL        time.Duration
@@ -867,10 +867,9 @@ func MakeDialParameters(
 			}
 		}
 
-		if isFronted {
-			dialParams.QUICDisableObfuscatedPSK = true
-		} else {
-			dialParams.QUICDisableObfuscatedPSK = p.Bool(parameters.QUICDisableObfuscatedPSK)
+		// Coin-flip for obfuscated PSK use for non-fronted QUIC.
+		if !isFronted {
+			dialParams.QUICUseObfuscatedPSK = p.WeightedCoinFlip(parameters.QUICObfuscatedPSKProbability)
 		}
 
 		dialParams.QUICDialEarly = p.WeightedCoinFlip(parameters.QUICDialEarlyProbability)

+ 1 - 1
psiphon/tunnel.go

@@ -935,7 +935,7 @@ func dialTunnel(
 			dialParams.ObfuscatedQUICNonceTransformerParameters,
 			dialParams.QUICDisablePathMTUDiscovery,
 			dialParams.QUICDialEarly,
-			dialParams.QUICDisableObfuscatedPSK,
+			dialParams.QUICUseObfuscatedPSK,
 			dialParams.quicTLSClientSessionCache)
 		if err != nil {
 			return nil, errors.Trace(err)