diff --git a/protocol/version.go b/protocol/version.go index 9b73f6128..ac284a7e2 100644 --- a/protocol/version.go +++ b/protocol/version.go @@ -1,8 +1,23 @@ package protocol +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/utils" +) + // VersionNumber is a version number as int type VersionNumber int +// SupportedVersions lists the versions that the server supports +var SupportedVersions = []VersionNumber{ + 30, + 32, +} + +// SupportedVersionsAsTags is needed for the SHLO crypto message +var SupportedVersionsAsTags []byte + // VersionNumberToTag maps version numbers ('32') to tags ('Q032') func VersionNumberToTag(vn VersionNumber) uint32 { v := uint32(vn) @@ -13,3 +28,21 @@ func VersionNumberToTag(vn VersionNumber) uint32 { func VersionTagToNumber(v uint32) VersionNumber { return VersionNumber(((v>>8)&0xff-'0')*100 + ((v>>16)&0xff-'0')*10 + ((v>>24)&0xff - '0')) } + +// IsSupportedVersion returns true if the server supports this version +func IsSupportedVersion(v VersionNumber) bool { + for _, t := range SupportedVersions { + if t == v { + return true + } + } + return false +} + +func init() { + var b bytes.Buffer + for _, v := range SupportedVersions { + utils.WriteUint32(&b, VersionNumberToTag(v)) + } + SupportedVersionsAsTags = b.Bytes() +} diff --git a/protocol/version_test.go b/protocol/version_test.go index 439dbb06e..6b2e71b7e 100644 --- a/protocol/version_test.go +++ b/protocol/version_test.go @@ -17,4 +17,8 @@ var _ = Describe("Version", func() { Expect(protocol.VersionNumberToTag(protocol.VersionNumber(123))).To(Equal(uint32('Q' + '1'<<8 + '2'<<16 + '3'<<24))) Expect(protocol.VersionNumberToTag(protocol.VersionNumber(30))).To(Equal(uint32('Q' + '0'<<8 + '3'<<16 + '0'<<24))) }) + + It("has proper tag list", func() { + Expect(protocol.SupportedVersionsAsTags).To(Equal([]byte("Q030Q032"))) + }) }) diff --git a/server.go b/server.go index ad4ff004a..ac283864f 100644 --- a/server.go +++ b/server.go @@ -9,14 +9,8 @@ import ( "github.com/lucas-clemente/quic-go/crypto" "github.com/lucas-clemente/quic-go/handshake" "github.com/lucas-clemente/quic-go/protocol" - "github.com/lucas-clemente/quic-go/utils" ) -var supportedVersions = map[protocol.VersionNumber]bool{ - 30: true, - 32: true, -} - // A Server of QUIC type Server struct { keyData *crypto.KeyData @@ -77,7 +71,7 @@ func (s *Server) ListenAndServe(address string) error { fmt.Printf("Got packet # %d\n", publicHeader.PacketNumber) // Send Version Negotiation Packet if the client is speaking a different protocol version - if publicHeader.VersionFlag && !supportedVersions[publicHeader.VersionNumber] { + if publicHeader.VersionFlag && !protocol.IsSupportedVersion(publicHeader.VersionNumber) { if err := sendVersionNegotiation(conn, remoteAddr, publicHeader); err != nil { fmt.Printf("Error sending version negotiation: %s", err.Error()) } @@ -104,9 +98,7 @@ func sendVersionNegotiation(conn *net.UDPConn, remoteAddr *net.UDPAddr, publicHe if err != nil { return err } - for v := range supportedVersions { - utils.WriteUint32(fullReply, protocol.VersionNumberToTag(v)) - } + fullReply.Write(protocol.SupportedVersionsAsTags) _, err = conn.WriteToUDP(fullReply.Bytes(), remoteAddr) if err != nil { return err