Przeglądaj źródła

Add InproxyProxyRelayInactivityTimeout

Rod Hynes 1 rok temu
rodzic
commit
39ccef905c

+ 1 - 0
psiphon/common/inproxy/coordinator.go

@@ -336,4 +336,5 @@ type WebRTCDialCoordinator interface {
 	WebRTCAnswerTimeout() time.Duration
 	WebRTCAnswerTimeout() time.Duration
 	WebRTCAwaitDataChannelTimeout() time.Duration
 	WebRTCAwaitDataChannelTimeout() time.Duration
 	ProxyDestinationDialTimeout() time.Duration
 	ProxyDestinationDialTimeout() time.Duration
+	ProxyRelayInactivityTimeout() time.Duration
 }
 }

+ 7 - 0
psiphon/common/inproxy/coordinator_test.go

@@ -195,6 +195,7 @@ type testWebRTCDialCoordinator struct {
 	webRTCAnswerTimeout             time.Duration
 	webRTCAnswerTimeout             time.Duration
 	webRTCAwaitDataChannelTimeout   time.Duration
 	webRTCAwaitDataChannelTimeout   time.Duration
 	proxyDestinationDialTimeout     time.Duration
 	proxyDestinationDialTimeout     time.Duration
+	proxyRelayInactivityTimeout     time.Duration
 }
 }
 
 
 func (t *testWebRTCDialCoordinator) NetworkID() string {
 func (t *testWebRTCDialCoordinator) NetworkID() string {
@@ -386,6 +387,12 @@ func (t *testWebRTCDialCoordinator) ProxyDestinationDialTimeout() time.Duration
 	return t.proxyDestinationDialTimeout
 	return t.proxyDestinationDialTimeout
 }
 }
 
 
+func (t *testWebRTCDialCoordinator) ProxyRelayInactivityTimeout() time.Duration {
+	t.mutex.Lock()
+	defer t.mutex.Unlock()
+	return t.proxyRelayInactivityTimeout
+}
+
 type testLogger struct {
 type testLogger struct {
 	logLevelDebug int32
 	logLevelDebug int32
 }
 }

+ 17 - 5
psiphon/common/inproxy/proxy.go

@@ -40,6 +40,7 @@ const (
 	proxyAnnounceLogSamplePeriod = 30 * time.Minute
 	proxyAnnounceLogSamplePeriod = 30 * time.Minute
 	proxyWebRTCAnswerTimeout     = 20 * time.Second
 	proxyWebRTCAnswerTimeout     = 20 * time.Second
 	proxyDestinationDialTimeout  = 20 * time.Second
 	proxyDestinationDialTimeout  = 20 * time.Second
+	proxyRelayInactivityTimeout  = 5 * time.Minute
 )
 )
 
 
 // Proxy is the in-proxy proxying component, which relays traffic from a
 // Proxy is the in-proxy proxying component, which relays traffic from a
@@ -794,7 +795,9 @@ func (p *Proxy) proxyOneClient(
 	// dial destination is a Psiphon server.
 	// dial destination is a Psiphon server.
 
 
 	destinationDialContext, destinationDialCancelFunc := context.WithTimeout(
 	destinationDialContext, destinationDialCancelFunc := context.WithTimeout(
-		ctx, common.ValueOrDefault(webRTCCoordinator.ProxyDestinationDialTimeout(), proxyDestinationDialTimeout))
+		ctx,
+		common.ValueOrDefault(
+			webRTCCoordinator.ProxyDestinationDialTimeout(), proxyDestinationDialTimeout))
 	defer destinationDialCancelFunc()
 	defer destinationDialCancelFunc()
 
 
 	// Use the custom resolver when resolving destination hostnames, such as
 	// Use the custom resolver when resolving destination hostnames, such as
@@ -855,12 +858,21 @@ func (p *Proxy) proxyOneClient(
 
 
 	// Hook up bytes transferred counting for activity updates.
 	// Hook up bytes transferred counting for activity updates.
 
 
-	// The ActivityMonitoredConn inactivity timeout is not configured, since
-	// the Psiphon server will close its connection to inactive clients on
-	// its own schedule.
+	// The ActivityMonitoredConn inactivity timeout is configured. For
+	// upstream TCP connections, the destinationConn will close when the TCP
+	// connection to the Psiphon server closes. But for upstream UDP flows,
+	// the relay does not know when the upstream "connection" has closed.
+	// Well-behaved clients will close the WebRTC half of the relay when
+	// those clients know the UDP-based tunnel protocol connection is closed;
+	// the inactivity timeout handles the remaining cases.
+
+	inactivityTimeout :=
+		common.ValueOrDefault(
+			webRTCCoordinator.ProxyRelayInactivityTimeout(),
+			proxyRelayInactivityTimeout)
 
 
 	destinationConn, err = common.NewActivityMonitoredConn(
 	destinationConn, err = common.NewActivityMonitoredConn(
-		destinationConn, 0, false, nil, p.activityUpdateWrapper)
+		destinationConn, inactivityTimeout, false, nil, p.activityUpdateWrapper)
 	if err != nil {
 	if err != nil {
 		return backOff, errors.Trace(err)
 		return backOff, errors.Trace(err)
 	}
 	}

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

@@ -438,6 +438,7 @@ const (
 	InproxyProxyWebRTCAwaitDataChannelTimeout          = "InproxyProxyWebRTCAwaitDataChannelTimeout"
 	InproxyProxyWebRTCAwaitDataChannelTimeout          = "InproxyProxyWebRTCAwaitDataChannelTimeout"
 	InproxyClientWebRTCAwaitDataChannelTimeout         = "InproxyClientWebRTCAwaitDataChannelTimeout"
 	InproxyClientWebRTCAwaitDataChannelTimeout         = "InproxyClientWebRTCAwaitDataChannelTimeout"
 	InproxyProxyDestinationDialTimeout                 = "InproxyProxyDestinationDialTimeout"
 	InproxyProxyDestinationDialTimeout                 = "InproxyProxyDestinationDialTimeout"
+	InproxyProxyRelayInactivityTimeout                 = "InproxyProxyRelayInactivityTimeout"
 	InproxyPsiphonAPIRequestTimeout                    = "InproxyPsiphonAPIRequestTimeout"
 	InproxyPsiphonAPIRequestTimeout                    = "InproxyPsiphonAPIRequestTimeout"
 	InproxyProxyTotalActivityNoticePeriod              = "InproxyProxyTotalActivityNoticePeriod"
 	InproxyProxyTotalActivityNoticePeriod              = "InproxyProxyTotalActivityNoticePeriod"
 	InproxyPersonalPairingConnectionWorkerPoolSize     = "InproxyPersonalPairingConnectionWorkerPoolSize"
 	InproxyPersonalPairingConnectionWorkerPoolSize     = "InproxyPersonalPairingConnectionWorkerPoolSize"
@@ -939,6 +940,7 @@ var defaultParameters = map[string]struct {
 	InproxyProxyWebRTCAwaitDataChannelTimeout:          {value: 30 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyProxyWebRTCAwaitDataChannelTimeout:          {value: 30 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyClientWebRTCAwaitDataChannelTimeout:         {value: 20 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyClientWebRTCAwaitDataChannelTimeout:         {value: 20 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyProxyDestinationDialTimeout:                 {value: 20 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyProxyDestinationDialTimeout:                 {value: 20 * time.Second, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
+	InproxyProxyRelayInactivityTimeout:                 {value: 5 * time.Minute, minimum: time.Duration(0), flags: useNetworkLatencyMultiplier},
 	InproxyPsiphonAPIRequestTimeout:                    {value: 10 * time.Second, minimum: 1 * time.Second, flags: useNetworkLatencyMultiplier},
 	InproxyPsiphonAPIRequestTimeout:                    {value: 10 * time.Second, minimum: 1 * time.Second, flags: useNetworkLatencyMultiplier},
 	InproxyProxyTotalActivityNoticePeriod:              {value: 5 * time.Minute, minimum: 1 * time.Second},
 	InproxyProxyTotalActivityNoticePeriod:              {value: 5 * time.Minute, minimum: 1 * time.Second},
 	InproxyPersonalPairingConnectionWorkerPoolSize:     {value: 2, minimum: 1},
 	InproxyPersonalPairingConnectionWorkerPoolSize:     {value: 2, minimum: 1},

+ 9 - 2
psiphon/inproxy.go

@@ -1453,6 +1453,7 @@ type InproxyWebRTCDialInstance struct {
 	webRTCAnswerTimeout             time.Duration
 	webRTCAnswerTimeout             time.Duration
 	awaitDataChannelTimeout         time.Duration
 	awaitDataChannelTimeout         time.Duration
 	proxyDestinationDialTimeout     time.Duration
 	proxyDestinationDialTimeout     time.Duration
+	proxyRelayInactivityTimeout     time.Duration
 }
 }
 
 
 // NewInproxyWebRTCDialInstance creates a new InproxyWebRTCDialInstance.
 // NewInproxyWebRTCDialInstance creates a new InproxyWebRTCDialInstance.
@@ -1543,8 +1544,8 @@ func NewInproxyWebRTCDialInstance(
 		webRTCDialParameters: webRTCDialParameters,
 		webRTCDialParameters: webRTCDialParameters,
 
 
 		// discoverNAT is ignored by proxies, which always attempt discovery.
 		// discoverNAT is ignored by proxies, which always attempt discovery.
-		// webRTCAnswerTimeout and proxyDestinationDialTimeout are used only
-		// by proxies.
+		// webRTCAnswerTimeout, proxyDestinationDialTimeout, and
+		// proxyRelayInactivityTimeout are used only by proxies.
 
 
 		discoverNAT:                     p.WeightedCoinFlip(parameters.InproxyClientDiscoverNATProbability),
 		discoverNAT:                     p.WeightedCoinFlip(parameters.InproxyClientDiscoverNATProbability),
 		disableSTUN:                     disableSTUN,
 		disableSTUN:                     disableSTUN,
@@ -1555,6 +1556,7 @@ func NewInproxyWebRTCDialInstance(
 		webRTCAnswerTimeout:             p.Duration(parameters.InproxyWebRTCAnswerTimeout),
 		webRTCAnswerTimeout:             p.Duration(parameters.InproxyWebRTCAnswerTimeout),
 		awaitDataChannelTimeout:         awaitDataChannelTimeout,
 		awaitDataChannelTimeout:         awaitDataChannelTimeout,
 		proxyDestinationDialTimeout:     p.Duration(parameters.InproxyProxyDestinationDialTimeout),
 		proxyDestinationDialTimeout:     p.Duration(parameters.InproxyProxyDestinationDialTimeout),
+		proxyRelayInactivityTimeout:     p.Duration(parameters.InproxyProxyRelayInactivityTimeout),
 	}, nil
 	}, nil
 }
 }
 
 
@@ -1853,6 +1855,11 @@ func (w *InproxyWebRTCDialInstance) ProxyDestinationDialTimeout() time.Duration
 	return w.proxyDestinationDialTimeout
 	return w.proxyDestinationDialTimeout
 }
 }
 
 
+// Implements the inproxy.WebRTCDialCoordinator interface.
+func (w *InproxyWebRTCDialInstance) ProxyRelayInactivityTimeout() time.Duration {
+	return w.proxyRelayInactivityTimeout
+}
+
 // InproxySTUNDialParameters is a set of STUN dial parameters.
 // InproxySTUNDialParameters is a set of STUN dial parameters.
 // InproxySTUNDialParameters is compatible with DialParameters JSON
 // InproxySTUNDialParameters is compatible with DialParameters JSON
 // marshaling. For client in-proxy tunnel dials, DialParameters will manage
 // marshaling. For client in-proxy tunnel dials, DialParameters will manage