add support for QUIC v1

This commit is contained in:
Marten Seemann 2021-03-02 16:01:34 +08:00
parent b8f07c728c
commit 6b771df453
8 changed files with 25 additions and 12 deletions

View file

@ -33,6 +33,7 @@ const (
nextProtoH3Draft29 = "h3-29"
nextProtoH3Draft32 = "h3-32"
nextProtoH3Draft34 = "h3-34"
nextProtoH3 = "h3"
)
const (
@ -43,6 +44,9 @@ const (
)
func versionToALPN(v protocol.VersionNumber) string {
if v == protocol.Version1 {
return nextProtoH3
}
if v == protocol.VersionTLS || v == protocol.VersionDraft29 {
return nextProtoH3Draft29
}
@ -155,11 +159,14 @@ func (s *Server) serveImpl(tlsConf *tls.Config, conn net.PacketConn) error {
// determine the ALPN from the QUIC version used
proto := nextProtoH3Draft29
if qconn, ok := ch.Conn.(handshake.ConnWithVersion); ok {
if qconn.GetQUICVersion() == quic.VersionDraft32 {
//nolint:exhaustive
switch qconn.GetQUICVersion() {
case quic.VersionDraft32:
proto = nextProtoH3Draft32
}
if qconn.GetQUICVersion() == protocol.VersionDraft34 {
case protocol.VersionDraft34:
proto = nextProtoH3Draft34
case protocol.Version1:
proto = nextProtoH3
}
}
config := tlsConf

View file

@ -35,6 +35,8 @@ const (
VersionDraft32 = protocol.VersionDraft32
// VersionDraft34 is IETF QUIC draft-34
VersionDraft34 = protocol.VersionDraft34
// Version1 is RFC 9000
Version1 = protocol.Version1
)
// A Token can be used to verify the ownership of the client address.

View file

@ -14,7 +14,7 @@ var (
)
func getSalt(v protocol.VersionNumber) []byte {
if v == protocol.VersionDraft34 {
if v == protocol.VersionDraft34 || v == protocol.Version1 {
return quicSaltDraft34
}
return quicSaltOld

View file

@ -48,7 +48,7 @@ func GetRetryIntegrityTag(retry []byte, origDestConnID protocol.ConnectionID, ve
var tag [16]byte
var sealed []byte
if version != protocol.VersionDraft34 {
if version != protocol.VersionDraft34 && version != protocol.Version1 {
sealed = oldRetryAEAD.Seal(tag[:0], oldRetryNonce[:], nil, retryBuf.Bytes())
} else {
sealed = retryAEAD.Seal(tag[:0], retryNonce[:], nil, retryBuf.Bytes())

View file

@ -24,7 +24,7 @@ var _ tlsExtensionHandler = &extensionHandler{}
// newExtensionHandler creates a new extension handler
func newExtensionHandler(params []byte, pers protocol.Perspective, v protocol.VersionNumber) tlsExtensionHandler {
et := uint16(quicTLSExtensionType)
if v != protocol.VersionDraft34 {
if v != protocol.VersionDraft34 && v != protocol.Version1 {
et = quicTLSExtensionTypeOldDrafts
}
return &extensionHandler{

View file

@ -19,11 +19,12 @@ const (
// The version numbers, making grepping easier
const (
VersionTLS VersionNumber = 0x51474fff
VersionWhatever VersionNumber = 1 // for when the version doesn't matter
VersionWhatever VersionNumber = math.MaxUint32 - 1 // for when the version doesn't matter
VersionUnknown VersionNumber = math.MaxUint32
VersionDraft29 VersionNumber = 0xff00001d
VersionDraft32 VersionNumber = 0xff000020
VersionDraft34 VersionNumber = 0xff000022 // If everything goes according to plan at the IETF, this will one day be QUIC v1.
VersionDraft34 VersionNumber = 0xff000022
Version1 VersionNumber = 0x1
)
// SupportedVersions lists the versions that the server supports
@ -38,7 +39,7 @@ func IsValidVersion(v VersionNumber) bool {
func (vn VersionNumber) String() string {
// For releases, VersionTLS will be set to a draft version.
// A switch statement can't contain duplicate cases.
if vn == VersionTLS && VersionTLS != VersionDraft29 && VersionTLS != VersionDraft32 {
if vn == VersionTLS && VersionTLS != VersionDraft29 && VersionTLS != VersionDraft32 && VersionTLS != Version1 {
return "TLS dev version (WIP)"
}
//nolint:exhaustive
@ -53,6 +54,8 @@ func (vn VersionNumber) String() string {
return "draft-32"
case VersionDraft34:
return "draft-34"
case Version1:
return "v1"
default:
if vn.isGQUIC() {
return fmt.Sprintf("gQUIC %d", vn.toGQUICVersion())

View file

@ -17,6 +17,7 @@ var _ = Describe("Version", func() {
Expect(IsValidVersion(VersionDraft29)).To(BeFalse())
Expect(IsValidVersion(VersionDraft32)).To(BeFalse())
Expect(IsValidVersion(VersionDraft34)).To(BeFalse())
Expect(IsValidVersion(Version1)).To(BeFalse())
Expect(IsValidVersion(1234)).To(BeFalse())
})
@ -25,12 +26,12 @@ var _ = Describe("Version", func() {
})
It("has the right string representation", func() {
Expect(VersionTLS.String()).To(ContainSubstring("TLS"))
Expect(VersionWhatever.String()).To(Equal("whatever"))
Expect(VersionUnknown.String()).To(Equal("unknown"))
Expect(VersionDraft29.String()).To(Equal("draft-29"))
Expect(VersionDraft32.String()).To(Equal("draft-32"))
Expect(VersionDraft34.String()).To(Equal("draft-34"))
Expect(Version1.String()).To(Equal("v1"))
// check with unsupported version numbers from the wiki
Expect(VersionNumber(0x51303039).String()).To(Equal("gQUIC 9"))
Expect(VersionNumber(0x51303133).String()).To(Equal("gQUIC 13"))
@ -46,7 +47,7 @@ var _ = Describe("Version", func() {
})
It("has supported versions in sorted order", func() {
for i := 0; i < len(SupportedVersions)-1; i++ {
for i := 1; i < len(SupportedVersions)-1; i++ {
Expect(SupportedVersions[i]).To(BeNumerically(">", SupportedVersions[i+1]))
}
})

View file

@ -16,7 +16,7 @@ import (
"github.com/lucas-clemente/quic-go"
)
const h09alpn = "hq-29"
const h09alpn = "hq-interop"
type responseWriter struct {
io.Writer