send a Public Reset when receiving the NSTP tag in the CHLO

We currently don't support the no STOP_WAITING experiment.
This commit is contained in:
Marten Seemann
2017-08-10 09:50:21 +07:00
parent f6e8ce5c67
commit be338c8389
5 changed files with 33 additions and 3 deletions

View File

@@ -54,11 +54,15 @@ type cryptoSetupServer struct {
var _ CryptoSetup = &cryptoSetupServer{}
// ErrHOLExperiment is returned when the client sends the FHL2 tag in the CHLO
// this is an expiremnt implemented by Chrome in QUIC 36, which we don't support
// ErrHOLExperiment is returned when the client sends the FHL2 tag in the CHLO.
// This is an experiment implemented by Chrome in QUIC 36, which we don't support.
// TODO: remove this when dropping support for QUIC 36
var ErrHOLExperiment = qerr.Error(qerr.InvalidCryptoMessageParameter, "HOL experiment. Unsupported")
// ErrNSTPExperiment is returned when the client sends the NSTP tag in the CHLO.
// This is an experiment implemented by Chrome in QUIC 38, which we don't support at this point.
var ErrNSTPExperiment = qerr.Error(qerr.InvalidCryptoMessageParameter, "NSTP experiment. Unsupported")
// NewCryptoSetup creates a new CryptoSetup instance for a server
func NewCryptoSetup(
connID protocol.ConnectionID,
@@ -120,6 +124,9 @@ func (h *cryptoSetupServer) handleMessage(chloData []byte, cryptoData map[Tag][]
if _, isHOLExperiment := cryptoData[TagFHL2]; isHOLExperiment {
return false, ErrHOLExperiment
}
if _, isNSTPExperiment := cryptoData[TagNSTP]; isNSTPExperiment {
return false, ErrNSTPExperiment
}
sniSlice, ok := cryptoData[TagSNI]
if !ok {

View File

@@ -264,6 +264,17 @@ var _ = Describe("Server Crypto Setup", func() {
Expect(err).To(MatchError(ErrHOLExperiment))
})
It("doesn't support Chrome's no STOP_WAITING experiment", func() {
HandshakeMessage{
Tag: TagCHLO,
Data: map[Tag][]byte{
TagNSTP: []byte("foobar"),
},
}.Write(&stream.dataToRead)
err := cs.HandleCryptoStream()
Expect(err).To(MatchError(ErrNSTPExperiment))
})
It("generates REJ messages", func() {
sourceAddrValid = false
response, err := cs.handleInchoateCHLO("", bytes.Repeat([]byte{'a'}, protocol.ClientHelloMinimumSize), nil)

View File

@@ -54,6 +54,9 @@ const (
// Chrome experiment (see https://codereview.chromium.org/2115033002)
// unsupported by quic-go
TagFHL2 Tag = 'F' + 'H'<<8 + 'L'<<16 + '2'<<24
// TagNSTP is the no STOP_WAITING experiment
// currently unsupported by quic-go
TagNSTP Tag = 'N' + 'S'<<8 + 'T'<<16 + 'P'<<24
// TagSTK is the source-address token
TagSTK Tag = 'S' + 'T'<<8 + 'K'<<16

View File

@@ -578,7 +578,9 @@ func (s *session) handleCloseError(closeErr closeError) error {
return nil
}
if quicErr.ErrorCode == qerr.DecryptionFailure || quicErr == handshake.ErrHOLExperiment {
if quicErr.ErrorCode == qerr.DecryptionFailure ||
quicErr == handshake.ErrHOLExperiment ||
quicErr == handshake.ErrNSTPExperiment {
return s.sendPublicReset(s.lastRcvdPacketNumber)
}
return s.sendConnectionClose(quicErr)

View File

@@ -804,6 +804,13 @@ var _ = Describe("Session", func() {
Expect(sess.Context().Done()).To(BeClosed())
})
It("sends a Public Reset if the client is initiating the no STOP_WAITING experiment", func() {
sess.Close(handshake.ErrHOLExperiment)
Expect(mconn.written).To(HaveLen(1))
Expect(mconn.written[0][0] & 0x02).ToNot(BeZero()) // Public Reset
Expect(sess.Context().Done()).To(BeClosed())
})
It("cancels the context when the run loop exists", func() {
returned := make(chan struct{})
go func() {