Просмотр исходного кода

Add distinct URL tactic parameter for Conjure APIRegistrarBidirectional

The legacy non-bidirectional endpoint may not always work with
APIRegistrarBidirectional. Older clients will continue to exist and use the
legacy endpoint. Introducing a distinct bidirectional URL allows for both
legacy and new clients to receive working Conjure API registration URLs.
Rod Hynes 4 лет назад
Родитель
Сommit
0793aeed05

+ 13 - 9
psiphon/common/parameters/parameters.go

@@ -278,6 +278,7 @@ const (
 	ClientBurstDownstreamTargetBytes                 = "ClientBurstDownstreamTargetBytes"
 	ConjureCachedRegistrationTTL                     = "ConjureCachedRegistrationTTL"
 	ConjureAPIRegistrarURL                           = "ConjureAPIRegistrarURL"
+	ConjureAPIRegistrarBidirectionalURL              = "ConjureAPIRegistrarBidirectionalURL"
 	ConjureAPIRegistrarFrontingSpecs                 = "ConjureAPIRegistrarFrontingSpecs"
 	ConjureAPIRegistrarMinDelay                      = "ConjureAPIRegistrarMinDelay"
 	ConjureAPIRegistrarMaxDelay                      = "ConjureAPIRegistrarMaxDelay"
@@ -601,15 +602,18 @@ var defaultParameters = map[string]struct {
 	ClientBurstDownstreamTargetBytes: {value: 0, minimum: 0},
 	ClientBurstDownstreamDeadline:    {value: time.Duration(0), minimum: time.Duration(0)},
 
-	ConjureCachedRegistrationTTL:     {value: time.Duration(0), minimum: time.Duration(0)},
-	ConjureAPIRegistrarURL:           {value: ""},
-	ConjureAPIRegistrarFrontingSpecs: {value: FrontingSpecs{}},
-	ConjureAPIRegistrarMinDelay:      {value: time.Duration(0), minimum: time.Duration(0)},
-	ConjureAPIRegistrarMaxDelay:      {value: time.Duration(0), minimum: time.Duration(0)},
-	ConjureDecoyRegistrarProbability: {value: 0.0, minimum: 0.0},
-	ConjureDecoyRegistrarWidth:       {value: 5, minimum: 0},
-	ConjureDecoyRegistrarMinDelay:    {value: time.Duration(0), minimum: time.Duration(0)},
-	ConjureDecoyRegistrarMaxDelay:    {value: time.Duration(0), minimum: time.Duration(0)},
+	ConjureCachedRegistrationTTL: {value: time.Duration(0), minimum: time.Duration(0)},
+	// ConjureAPIRegistrarURL parameter is obsoleted by ConjureAPIRegistrarBidirectionalURL.
+	// TODO: remove once no longer required for older clients.
+	ConjureAPIRegistrarURL:              {value: ""},
+	ConjureAPIRegistrarBidirectionalURL: {value: ""},
+	ConjureAPIRegistrarFrontingSpecs:    {value: FrontingSpecs{}},
+	ConjureAPIRegistrarMinDelay:         {value: time.Duration(0), minimum: time.Duration(0)},
+	ConjureAPIRegistrarMaxDelay:         {value: time.Duration(0), minimum: time.Duration(0)},
+	ConjureDecoyRegistrarProbability:    {value: 0.0, minimum: 0.0},
+	ConjureDecoyRegistrarWidth:          {value: 5, minimum: 0},
+	ConjureDecoyRegistrarMinDelay:       {value: time.Duration(0), minimum: time.Duration(0)},
+	ConjureDecoyRegistrarMaxDelay:       {value: time.Duration(0), minimum: time.Duration(0)},
 
 	ConjureTransportObfs4Probability: {value: 0.0, minimum: 0.0},
 

+ 8 - 7
psiphon/common/refraction/config.go

@@ -46,13 +46,14 @@ type ConjureConfig struct {
 	// the client reverts back to its original public IP).
 	RegistrationCacheKey string
 
-	// APIRegistrarURL specifies the API registration endpoint. Setting
-	// APIRegistrarURL enables API registration. The domain fronting
-	// configuration provided by APIRegistrarHTTPClient may ignore the host
-	// portion of this URL, implicitly providing another value; the path portion
-	// is always used in the request. Only one of API registration or decoy
-	// registration can be enabled for a single dial.
-	APIRegistrarURL string
+	// APIRegistrarBidirectionalURL specifies the bidirectional API
+	// registration endpoint. Setting APIRegistrarBidirectionalURL enables
+	// API registration. The domain fronting configuration provided by
+	// APIRegistrarHTTPClient may ignore the host portion of this URL,
+	// implicitly providing another value; the path portion is always used in
+	// the request. Only one of API registration or decoy registration can be
+	// enabled for a single dial.
+	APIRegistrarBidirectionalURL string
 
 	// APIRegistrarHTTPClient specifies a custom HTTP client (and underlying
 	// dialers) to be used for Conjure API registration. The

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

@@ -317,7 +317,7 @@ func dial(
 			conjureCached = true
 			conjureDelay = 0 // report no delay
 
-		} else if conjureConfig.APIRegistrarURL != "" {
+		} else if conjureConfig.APIRegistrarBidirectionalURL != "" {
 
 			if conjureConfig.APIRegistrarHTTPClient == nil {
 				// While not a guaranteed check, if the APIRegistrarHTTPClient isn't set
@@ -327,7 +327,7 @@ func dial(
 			}
 
 			refractionDialer.DarkDecoyRegistrar = &refraction_networking_client.APIRegistrarBidirectional{
-				Endpoint:        conjureConfig.APIRegistrarURL,
+				Endpoint:        conjureConfig.APIRegistrarBidirectionalURL,
 				ConnectionDelay: conjureConfig.APIRegistrarDelay,
 				MaxRetries:      0,
 				Client:          conjureConfig.APIRegistrarHTTPClient,

+ 6 - 6
psiphon/config.go

@@ -733,7 +733,7 @@ type Config struct {
 	// ConjureCachedRegistrationTTLSeconds and other Conjure fields are for
 	// testing purposes.
 	ConjureCachedRegistrationTTLSeconds       *int
-	ConjureAPIRegistrarURL                    string
+	ConjureAPIRegistrarBidirectionalURL       string
 	ConjureAPIRegistrarFrontingSpecs          parameters.FrontingSpecs
 	ConjureAPIRegistrarMinDelayMilliseconds   *int
 	ConjureAPIRegistrarMaxDelayMilliseconds   *int
@@ -1672,8 +1672,8 @@ func (config *Config) makeConfigParameters() map[string]interface{} {
 		applyParameters[parameters.ConjureCachedRegistrationTTL] = fmt.Sprintf("%ds", *config.ConjureCachedRegistrationTTLSeconds)
 	}
 
-	if config.ConjureAPIRegistrarURL != "" {
-		applyParameters[parameters.ConjureAPIRegistrarURL] = config.ConjureAPIRegistrarURL
+	if config.ConjureAPIRegistrarBidirectionalURL != "" {
+		applyParameters[parameters.ConjureAPIRegistrarBidirectionalURL] = config.ConjureAPIRegistrarBidirectionalURL
 	}
 
 	if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {
@@ -1980,9 +1980,9 @@ func (config *Config) setDialParametersHash() {
 		binary.Write(hash, binary.LittleEndian, int64(*config.ConjureCachedRegistrationTTLSeconds))
 	}
 
-	if config.ConjureAPIRegistrarURL != "" {
-		hash.Write([]byte("ConjureAPIRegistrarURL"))
-		hash.Write([]byte(config.ConjureAPIRegistrarURL))
+	if config.ConjureAPIRegistrarBidirectionalURL != "" {
+		hash.Write([]byte("ConjureAPIRegistrarBidirectionalURL"))
+		hash.Write([]byte(config.ConjureAPIRegistrarBidirectionalURL))
 	}
 
 	if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {

+ 22 - 11
psiphon/dialParameters.go

@@ -117,14 +117,14 @@ type DialParameters struct {
 	QUICClientHelloSeed       *prng.Seed
 	ObfuscatedQUICPaddingSeed *prng.Seed
 
-	ConjureCachedRegistrationTTL time.Duration
-	ConjureAPIRegistration       bool
-	ConjureAPIRegistrarURL       string
-	ConjureAPIRegistrarDelay     time.Duration
-	ConjureDecoyRegistration     bool
-	ConjureDecoyRegistrarDelay   time.Duration
-	ConjureDecoyRegistrarWidth   int
-	ConjureTransport             string
+	ConjureCachedRegistrationTTL        time.Duration
+	ConjureAPIRegistration              bool
+	ConjureAPIRegistrarBidirectionalURL string
+	ConjureAPIRegistrarDelay            time.Duration
+	ConjureDecoyRegistration            bool
+	ConjureDecoyRegistrarDelay          time.Duration
+	ConjureDecoyRegistrarWidth          int
+	ConjureTransport                    string
 
 	LivenessTestSeed *prng.Seed
 
@@ -208,6 +208,7 @@ func MakeDialParameters(
 	// - The protocol selection constraints must permit replay, as indicated
 	//   by canReplay.
 	// - Must not be using an obsolete TLS profile that is no longer supported.
+	// - Must be using the latest Conjure API URL.
 	//
 	// When existing dial parameters don't meet these conditions, dialParams
 	// is reset to nil and new dial parameters will be generated.
@@ -230,7 +231,17 @@ func MakeDialParameters(
 			(dialParams.TLSProfile != "" &&
 				!common.Contains(protocol.SupportedTLSProfiles, dialParams.TLSProfile)) ||
 			(dialParams.QUICVersion != "" &&
-				!common.Contains(protocol.SupportedQUICVersions, dialParams.QUICVersion))) {
+				!common.Contains(protocol.SupportedQUICVersions, dialParams.QUICVersion)) ||
+
+			// Legacy clients use ConjureAPIRegistrarURL with
+			// gotapdance.tapdance.APIRegistrar and new clients use
+			// ConjureAPIRegistrarBidirectionalURL with
+			// gotapdance.tapdance.APIRegistrarBidirectional. Updated clients
+			// may have replay dial parameters with the old
+			// ConjureAPIRegistrarURL field, which is now ignored. In this
+			// case, ConjureAPIRegistrarBidirectionalURL will be blank. Reset
+			// this replay.
+			(dialParams.ConjureAPIRegistration && dialParams.ConjureAPIRegistrarBidirectionalURL == "")) {
 
 		// In these cases, existing dial parameters are expired or no longer
 		// match the config state and so are cleared to avoid rechecking them.
@@ -464,7 +475,7 @@ func MakeDialParameters(
 
 		dialParams.ConjureCachedRegistrationTTL = p.Duration(parameters.ConjureCachedRegistrationTTL)
 
-		apiURL := p.String(parameters.ConjureAPIRegistrarURL)
+		apiURL := p.String(parameters.ConjureAPIRegistrarBidirectionalURL)
 		decoyWidth := p.Int(parameters.ConjureDecoyRegistrarWidth)
 
 		dialParams.ConjureAPIRegistration = apiURL != ""
@@ -496,7 +507,7 @@ func MakeDialParameters(
 			// Accordingly, replayFronting/replayHostname have no effect on Conjure API
 			// registration replay.
 
-			dialParams.ConjureAPIRegistrarURL = apiURL
+			dialParams.ConjureAPIRegistrarBidirectionalURL = apiURL
 
 			frontingSpecs := p.FrontingSpecs(parameters.ConjureAPIRegistrarFrontingSpecs)
 			dialParams.FrontingProviderID,

+ 2 - 1
psiphon/tunnel.go

@@ -897,7 +897,8 @@ func dialTunnel(
 				Transport: common.NewHTTPRoundTripper(roundTrip),
 			}
 
-			conjureConfig.APIRegistrarURL = dialParams.ConjureAPIRegistrarURL
+			conjureConfig.APIRegistrarBidirectionalURL =
+				dialParams.ConjureAPIRegistrarBidirectionalURL
 			conjureConfig.APIRegistrarDelay = dialParams.ConjureAPIRegistrarDelay
 
 		} else if dialParams.ConjureDecoyRegistration {