Skip to content

Commit 0146a8d

Browse files
TUN-5285: Fallback to HTTP2 immediately if connection times out with no network activity
1 parent 36479ef commit 0146a8d

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

connection/quic.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ func NewQUICConnection(
4949
) (*QUICConnection, error) {
5050
session, err := quic.DialAddr(edgeAddr.String(), tlsConfig, quicConfig)
5151
if err != nil {
52-
return nil, errors.Wrap(err, "failed to dial to edge")
52+
return nil, fmt.Errorf("failed to dial to edge: %w", err)
5353
}
5454

5555
registrationStream, err := session.OpenStream()
5656
if err != nil {
57-
return nil, errors.Wrap(err, "failed to open a registration stream")
57+
return nil, fmt.Errorf("failed to open a registration stream: %w", err)
5858
}
5959

6060
err = controlStreamHandler.ServeControlStream(ctx, registrationStream, connOptions, false)
@@ -82,7 +82,7 @@ func (q *QUICConnection) Serve(ctx context.Context) error {
8282
if errors.Is(err, context.Canceled) {
8383
return nil
8484
}
85-
return errors.Wrap(err, "failed to accept QUIC stream")
85+
return fmt.Errorf("failed to accept QUIC stream: %w", err)
8686
}
8787
go func() {
8888
defer stream.Close()

origin/tunnel.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,13 @@ func ServeTunnelLoop(
190190
case <-gracefulShutdownC:
191191
return nil
192192
case <-protocolFallback.BackoffTimer():
193-
if !selectNextProtocol(&connLog, protocolFallback, config.ProtocolSelector) {
193+
var idleTimeoutError *quic.IdleTimeoutError
194+
if !selectNextProtocol(
195+
&connLog,
196+
protocolFallback,
197+
config.ProtocolSelector,
198+
errors.As(err, &idleTimeoutError),
199+
) {
194200
return err
195201
}
196202
}
@@ -222,8 +228,9 @@ func selectNextProtocol(
222228
connLog *zerolog.Logger,
223229
protocolBackoff *protocolFallback,
224230
selector connection.ProtocolSelector,
231+
isNetworkActivityTimeout bool,
225232
) bool {
226-
if protocolBackoff.ReachedMaxRetries() {
233+
if protocolBackoff.ReachedMaxRetries() || isNetworkActivityTimeout {
227234
fallback, hasFallback := selector.Fallback()
228235
if !hasFallback {
229236
return false

origin/tunnel_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ func TestWaitForBackoffFallback(t *testing.T) {
6262
// Retry #0 and #1. At retry #2, we switch protocol, so the fallback loop has one more retry than this
6363
for i := 0; i < int(maxRetries-1); i++ {
6464
protocolFallback.BackoffTimer() // simulate retry
65-
ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
65+
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
6666
assert.True(t, ok)
6767
assert.Equal(t, initProtocol, protocolFallback.protocol)
6868
}
6969

7070
// Retry fallback protocol
7171
for i := 0; i < int(maxRetries); i++ {
7272
protocolFallback.BackoffTimer() // simulate retry
73-
ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
73+
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
7474
assert.True(t, ok)
7575
fallback, ok := protocolSelector.Fallback()
7676
assert.True(t, ok)
@@ -82,12 +82,19 @@ func TestWaitForBackoffFallback(t *testing.T) {
8282

8383
// No protocol to fallback, return error
8484
protocolFallback.BackoffTimer() // simulate retry
85-
ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
85+
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
8686
assert.False(t, ok)
8787

8888
protocolFallback.reset()
8989
protocolFallback.BackoffTimer() // simulate retry
90-
ok = selectNextProtocol(&log, protocolFallback, protocolSelector)
90+
ok = selectNextProtocol(&log, protocolFallback, protocolSelector, false)
9191
assert.True(t, ok)
9292
assert.Equal(t, initProtocol, protocolFallback.protocol)
93+
94+
protocolFallback.reset()
95+
protocolFallback.BackoffTimer() // simulate retry
96+
ok = selectNextProtocol(&log, protocolFallback, protocolSelector, true)
97+
// Check that we get a true after the first try itself when this flag is true. This allows us to immediately
98+
// switch protocols.
99+
assert.True(t, ok)
93100
}

0 commit comments

Comments
 (0)