Skip to content

Commit 5e16121

Browse files
gbn+mailbox: force connection status change on FIN
When the client receives+processes a FIN packet, we force the connection to status ClientStatusSessionNotFound, as in rare occasions the corresponding server may have time to close the connection before we've already processed the sent FIN packet by the server. In that case, if we didn't force a new status, the client would never mark the connection as status ClientStatusSessionNotFound. This solves a bug for the testServerReconnect itest, as that test would sometimes fail due to the FIN packet being processed but without changing the connection status, leading to a test predicate never being satisfied.
1 parent 77d0bd5 commit 5e16121

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

gbn/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ type config struct {
3838
// packet.
3939
sendToStream sendBytesFunc
4040

41+
// onFIN is a callback that if set, will be called once a FIN packet has
42+
// been received and processed.
43+
onFIN func()
44+
4145
// handshakeTimeout is the time after which the server or client
4246
// will abort and restart the handshake if the expected response is
4347
// not received from the peer.

gbn/gbn_conn.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,10 @@ func (g *GoBackNConn) receivePacketsForever() error { // nolint:gocyclo
649649

650650
close(g.remoteClosed)
651651

652+
if g.cfg.onFIN != nil {
653+
g.cfg.onFIN()
654+
}
655+
652656
return errTransportClosing
653657

654658
default:

gbn/options.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,11 @@ func WithKeepalivePing(ping, pong time.Duration) Option {
4343
conn.pongTime = pong
4444
}
4545
}
46+
47+
// WithOnFIN is used to set the onFIN callback that will be called once a FIN
48+
// packet has been received and processed.
49+
func WithOnFIN(fn func()) Option {
50+
return func(conn *config) {
51+
conn.onFIN = fn
52+
}
53+
}

mailbox/client_conn.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,32 @@ func NewClientConn(ctx context.Context, sid [64]byte, serverHost string,
157157
}
158158

159159
c := &ClientConn{
160-
transport: transport,
161-
gbnOptions: []gbn.Option{
162-
gbn.WithTimeout(gbnTimeout),
163-
gbn.WithHandshakeTimeout(gbnHandshakeTimeout),
164-
gbn.WithKeepalivePing(
165-
gbnClientPingTimeout, gbnPongTimeout,
166-
),
167-
},
160+
transport: transport,
168161
status: ClientStatusNotConnected,
169162
onNewStatus: onNewStatus,
170163
quit: make(chan struct{}),
171164
cancel: cancel,
172165
log: logger,
173166
}
167+
168+
c.gbnOptions = []gbn.Option{
169+
gbn.WithTimeout(gbnTimeout),
170+
gbn.WithHandshakeTimeout(gbnHandshakeTimeout),
171+
gbn.WithKeepalivePing(
172+
gbnClientPingTimeout, gbnPongTimeout,
173+
),
174+
gbn.WithOnFIN(func() {
175+
// We force the connection to set a new status after
176+
// processing a FIN packet, as in rare occasions the
177+
// corresponding server may have time to close the
178+
// connection before we've already processed the sent
179+
// FIN packet by the server. In that case, if we didn't
180+
// force a new status, the client would never mark the
181+
// connection as status ClientStatusSessionNotFound.
182+
c.setStatus(ClientStatusSessionNotFound)
183+
}),
184+
}
185+
174186
c.connKit = &connKit{
175187
ctx: ctxc,
176188
impl: c,

0 commit comments

Comments
 (0)