forked from quic-go/quic-go
add a timeout before crypto handshake completes
This commit is contained in:
40
session.go
40
session.go
@@ -81,6 +81,7 @@ type Session struct {
|
||||
// representation, and sent back in public reset packets
|
||||
largestRcvdPacketNumber protocol.PacketNumber
|
||||
|
||||
sessionCreationTime time.Time
|
||||
lastNetworkActivityTime time.Time
|
||||
|
||||
timer *time.Timer
|
||||
@@ -99,23 +100,29 @@ func newSession(conn connection, v protocol.VersionNumber, connectionID protocol
|
||||
sentPacketHandler = ackhandler.NewSentPacketHandler()
|
||||
receivedPacketHandler = ackhandler.NewReceivedPacketHandler()
|
||||
|
||||
now := time.Now()
|
||||
session := &Session{
|
||||
connectionID: connectionID,
|
||||
version: v,
|
||||
conn: conn,
|
||||
streamCallback: streamCallback,
|
||||
closeCallback: closeCallback,
|
||||
conn: conn,
|
||||
connectionID: connectionID,
|
||||
version: v,
|
||||
|
||||
streamCallback: streamCallback,
|
||||
closeCallback: closeCallback,
|
||||
|
||||
connectionParametersManager: connectionParametersManager,
|
||||
sentPacketHandler: sentPacketHandler,
|
||||
receivedPacketHandler: receivedPacketHandler,
|
||||
flowControlManager: flowControlManager,
|
||||
receivedPackets: make(chan *receivedPacket, protocol.MaxSessionUnprocessedPackets),
|
||||
closeChan: make(chan *qerr.QuicError, 1),
|
||||
sendingScheduled: make(chan struct{}, 1),
|
||||
connectionParametersManager: connectionParametersManager,
|
||||
undecryptablePackets: make([]*receivedPacket, 0, protocol.MaxUndecryptablePackets),
|
||||
aeadChanged: make(chan struct{}, 1),
|
||||
timer: time.NewTimer(0),
|
||||
lastNetworkActivityTime: time.Now(),
|
||||
|
||||
receivedPackets: make(chan *receivedPacket, protocol.MaxSessionUnprocessedPackets),
|
||||
closeChan: make(chan *qerr.QuicError, 1),
|
||||
sendingScheduled: make(chan struct{}, 1),
|
||||
undecryptablePackets: make([]*receivedPacket, 0, protocol.MaxUndecryptablePackets),
|
||||
aeadChanged: make(chan struct{}, 1),
|
||||
|
||||
timer: time.NewTimer(0),
|
||||
lastNetworkActivityTime: now,
|
||||
sessionCreationTime: now,
|
||||
}
|
||||
|
||||
session.streamsMap = newStreamsMap(session.newStream)
|
||||
@@ -196,6 +203,9 @@ func (s *Session) run() {
|
||||
if time.Now().Sub(s.lastNetworkActivityTime) >= s.connectionParametersManager.GetIdleConnectionStateLifetime() {
|
||||
s.Close(qerr.Error(qerr.NetworkIdleTimeout, "No recent network activity."))
|
||||
}
|
||||
if !s.cryptoSetup.HandshakeComplete() && time.Now().Sub(s.sessionCreationTime) >= protocol.MaxTimeForCryptoHandshake {
|
||||
s.Close(qerr.Error(qerr.NetworkIdleTimeout, "Crypto handshake did not complete in time."))
|
||||
}
|
||||
s.garbageCollectStreams()
|
||||
}
|
||||
}
|
||||
@@ -209,6 +219,10 @@ func (s *Session) maybeResetTimer() {
|
||||
if rtoTime := s.sentPacketHandler.TimeOfFirstRTO(); !rtoTime.IsZero() {
|
||||
nextDeadline = utils.MinTime(nextDeadline, rtoTime)
|
||||
}
|
||||
if !s.cryptoSetup.HandshakeComplete() {
|
||||
handshakeDeadline := s.sessionCreationTime.Add(protocol.MaxTimeForCryptoHandshake)
|
||||
nextDeadline = utils.MinTime(nextDeadline, handshakeDeadline)
|
||||
}
|
||||
|
||||
if nextDeadline.Equal(s.currentDeadline) {
|
||||
// No need to reset the timer
|
||||
|
||||
@@ -748,15 +748,21 @@ var _ = Describe("Session", func() {
|
||||
Expect(session.receivedPackets).To(Receive())
|
||||
})
|
||||
|
||||
It("times out", func(done Done) {
|
||||
session.connectionParametersManager.SetFromMap(map[handshake.Tag][]byte{
|
||||
handshake.TagICSL: {0, 0, 0, 0},
|
||||
Context("timeouts", func() {
|
||||
It("times out due to no network activity", func(done Done) {
|
||||
session.lastNetworkActivityTime = time.Now().Add(-time.Hour)
|
||||
session.run() // Would normally not return
|
||||
Expect(conn.written[0]).To(ContainSubstring("No recent network activity."))
|
||||
close(done)
|
||||
})
|
||||
session.packer.connectionParametersManager = session.connectionParametersManager
|
||||
session.run() // Would normally not return
|
||||
Expect(conn.written[0]).To(ContainSubstring("No recent network activity."))
|
||||
close(done)
|
||||
}, 3)
|
||||
|
||||
It("times out due to non-completed crypto handshake", func(done Done) {
|
||||
session.sessionCreationTime = time.Now().Add(-time.Hour)
|
||||
session.run() // Would normally not return
|
||||
Expect(conn.written[0]).To(ContainSubstring("Crypto handshake did not complete in time."))
|
||||
close(done)
|
||||
})
|
||||
})
|
||||
|
||||
It("errors when the SentPacketHandler has too many packets tracked", func() {
|
||||
streamFrame := frames.StreamFrame{StreamID: 5, Data: []byte("foobar")}
|
||||
|
||||
Reference in New Issue
Block a user