forked from quic-go/quic-go
@@ -323,3 +323,8 @@ func (h *CryptoSetup) LockForSealing() {
|
|||||||
func (h *CryptoSetup) UnlockForSealing() {
|
func (h *CryptoSetup) UnlockForSealing() {
|
||||||
h.mutex.RUnlock()
|
h.mutex.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandshakeComplete returns true after the first forward secure packet was received form the client.
|
||||||
|
func (h *CryptoSetup) HandshakeComplete() bool {
|
||||||
|
return h.receivedForwardSecurePacket
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const MaxNewStreamIDDelta = 4 * MaxStreamsPerConnection
|
|||||||
const MaxIdleConnectionStateLifetime = 60 * time.Second
|
const MaxIdleConnectionStateLifetime = 60 * time.Second
|
||||||
|
|
||||||
// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed.
|
// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed.
|
||||||
const MaxSessionUnprocessedPackets = 128
|
const MaxSessionUnprocessedPackets = 2000
|
||||||
|
|
||||||
// RetransmissionThreshold + 1 is the number of times a packet has to be NACKed so that it gets retransmitted
|
// RetransmissionThreshold + 1 is the number of times a packet has to be NACKed so that it gets retransmitted
|
||||||
const RetransmissionThreshold = 3
|
const RetransmissionThreshold = 3
|
||||||
|
|||||||
@@ -629,6 +629,9 @@ func (s *Session) scheduleSending() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) tryQueueingUndecryptablePacket(p receivedPacket) {
|
func (s *Session) tryQueueingUndecryptablePacket(p receivedPacket) {
|
||||||
|
if s.cryptoSetup.HandshakeComplete() {
|
||||||
|
return
|
||||||
|
}
|
||||||
utils.Infof("Queueing packet 0x%x for later decryption", p.publicHeader.PacketNumber)
|
utils.Infof("Queueing packet 0x%x for later decryption", p.publicHeader.PacketNumber)
|
||||||
if len(s.undecryptablePackets)+1 >= protocol.MaxUndecryptablePackets {
|
if len(s.undecryptablePackets)+1 >= protocol.MaxUndecryptablePackets {
|
||||||
s.Close(qerr.Error(qerr.DecryptionFailure, "too many undecryptable packets received"))
|
s.Close(qerr.Error(qerr.DecryptionFailure, "too many undecryptable packets received"))
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -739,6 +741,19 @@ var _ = Describe("Session", func() {
|
|||||||
Expect(conn.written[0]).To(ContainSubstring(string([]byte("PRST"))))
|
Expect(conn.written[0]).To(ContainSubstring(string([]byte("PRST"))))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("ignores undecryptable packets after the handshake is complete", func() {
|
||||||
|
*(*bool)(unsafe.Pointer(reflect.ValueOf(session.cryptoSetup).Elem().FieldByName("receivedForwardSecurePacket").UnsafeAddr())) = true
|
||||||
|
for i := 0; i < protocol.MaxUndecryptablePackets; i++ {
|
||||||
|
hdr := &PublicHeader{
|
||||||
|
PacketNumber: protocol.PacketNumber(i + 1),
|
||||||
|
}
|
||||||
|
session.handlePacket(nil, hdr, []byte("foobar"))
|
||||||
|
}
|
||||||
|
go session.run()
|
||||||
|
Consistently(session.undecryptablePackets).Should(HaveLen(0))
|
||||||
|
session.closeImpl(nil, true)
|
||||||
|
})
|
||||||
|
|
||||||
It("unqueues undecryptable packets for later decryption", func() {
|
It("unqueues undecryptable packets for later decryption", func() {
|
||||||
session.undecryptablePackets = []receivedPacket{{
|
session.undecryptablePackets = []receivedPacket{{
|
||||||
nil,
|
nil,
|
||||||
|
|||||||
Reference in New Issue
Block a user