forked from quic-go/quic-go
Merge pull request #2289 from lucas-clemente/fix-keep-alive-duration
fix mismatching expectation of the keep alive timer
This commit is contained in:
26
session.go
26
session.go
@@ -524,11 +524,17 @@ runLoop:
|
||||
if s.pacingDeadline.IsZero() { // the timer didn't have a pacing deadline set
|
||||
pacingDeadline = s.sentPacketHandler.TimeUntilSend()
|
||||
}
|
||||
if s.config.KeepAlive && !s.keepAlivePingSent && s.handshakeComplete && s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && time.Since(s.lastPacketReceivedTime) >= s.keepAliveInterval/2 {
|
||||
if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) {
|
||||
// send a PING frame since there is no activity in the session
|
||||
s.logger.Debugf("Sending a keep-alive ping to keep the connection alive.")
|
||||
s.logger.Debugf("Sending a keep-alive PING to keep the connection alive.")
|
||||
s.framer.QueueControlFrame(&wire.PingFrame{})
|
||||
s.keepAlivePingSent = true
|
||||
} else if !s.handshakeComplete && now.Sub(s.sessionCreationTime) >= s.config.HandshakeTimeout {
|
||||
s.destroyImpl(qerr.TimeoutError("Handshake did not complete in time"))
|
||||
continue
|
||||
} else if s.handshakeComplete && now.Sub(s.idleTimeoutStartTime()) >= s.idleTimeout {
|
||||
s.destroyImpl(qerr.TimeoutError("No recent network activity"))
|
||||
continue
|
||||
} else if !pacingDeadline.IsZero() && now.Before(pacingDeadline) {
|
||||
// If we get to this point before the pacing deadline, we should wait until that deadline.
|
||||
// This can happen when scheduleSending is called, or a packet is received.
|
||||
@@ -575,14 +581,22 @@ func (s *session) ConnectionState() tls.ConnectionState {
|
||||
return s.cryptoStreamHandler.ConnectionState()
|
||||
}
|
||||
|
||||
// Time when the next keep-alive packet should be sent.
|
||||
// It returns a zero time if no keep-alive should be sent.
|
||||
func (s *session) nextKeepAliveTime() time.Time {
|
||||
if !s.config.KeepAlive || s.keepAlivePingSent || s.firstAckElicitingPacketAfterIdleSentTime.IsZero() {
|
||||
return time.Time{}
|
||||
}
|
||||
return s.lastPacketReceivedTime.Add(s.keepAliveInterval / 2)
|
||||
}
|
||||
|
||||
func (s *session) maybeResetTimer() {
|
||||
var deadline time.Time
|
||||
if !s.handshakeComplete {
|
||||
handshakeDeadline := s.sessionCreationTime.Add(s.config.HandshakeTimeout)
|
||||
deadline = handshakeDeadline
|
||||
deadline = s.sessionCreationTime.Add(s.config.HandshakeTimeout)
|
||||
} else {
|
||||
if s.config.KeepAlive && !s.keepAlivePingSent {
|
||||
deadline = s.idleTimeoutStartTime().Add(s.keepAliveInterval / 2)
|
||||
if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() {
|
||||
deadline = keepAliveTime
|
||||
} else {
|
||||
deadline = s.idleTimeoutStartTime().Add(s.idleTimeout)
|
||||
}
|
||||
|
||||
@@ -1382,6 +1382,7 @@ var _ = Describe("Session", func() {
|
||||
It("sends a PING as a keep-alive after half the idle timeout", func() {
|
||||
setRemoteIdleTimeout(5 * time.Second)
|
||||
sess.lastPacketReceivedTime = time.Now().Add(-5 * time.Second / 2)
|
||||
sess.firstAckElicitingPacketAfterIdleSentTime = time.Now().Add(-5 * time.Second / 2)
|
||||
sent := make(chan struct{})
|
||||
packer.EXPECT().PackPacket().Do(func() (*packedPacket, error) {
|
||||
close(sent)
|
||||
@@ -1395,6 +1396,7 @@ var _ = Describe("Session", func() {
|
||||
sess.config.MaxIdleTimeout = time.Hour
|
||||
setRemoteIdleTimeout(time.Hour)
|
||||
sess.lastPacketReceivedTime = time.Now().Add(-protocol.MaxKeepAliveInterval).Add(-time.Millisecond)
|
||||
sess.firstAckElicitingPacketAfterIdleSentTime = time.Now().Add(-protocol.MaxKeepAliveInterval).Add(-time.Millisecond)
|
||||
sent := make(chan struct{})
|
||||
packer.EXPECT().PackPacket().Do(func() (*packedPacket, error) {
|
||||
close(sent)
|
||||
|
||||
Reference in New Issue
Block a user