version_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package protocol
  2. import (
  3. . "github.com/onsi/ginkgo"
  4. . "github.com/onsi/gomega"
  5. )
  6. var _ = Describe("Version", func() {
  7. isReservedVersion := func(v VersionNumber) bool {
  8. return v&0x0f0f0f0f == 0x0a0a0a0a
  9. }
  10. // version numbers taken from the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
  11. It("has the right gQUIC version number", func() {
  12. Expect(Version39).To(BeEquivalentTo(0x51303339))
  13. Expect(Version43).To(BeEquivalentTo(0x51303433))
  14. Expect(Version44).To(BeEquivalentTo(0x51303434))
  15. })
  16. It("says if a version is valid", func() {
  17. Expect(IsValidVersion(Version39)).To(BeTrue())
  18. Expect(IsValidVersion(Version43)).To(BeTrue())
  19. Expect(IsValidVersion(Version44)).To(BeTrue())
  20. Expect(IsValidVersion(VersionTLS)).To(BeTrue())
  21. Expect(IsValidVersion(VersionWhatever)).To(BeFalse())
  22. Expect(IsValidVersion(VersionUnknown)).To(BeFalse())
  23. Expect(IsValidVersion(1234)).To(BeFalse())
  24. })
  25. It("says if a version supports TLS", func() {
  26. Expect(Version39.UsesTLS()).To(BeFalse())
  27. Expect(Version43.UsesTLS()).To(BeFalse())
  28. Expect(Version44.UsesTLS()).To(BeFalse())
  29. Expect(VersionTLS.UsesTLS()).To(BeTrue())
  30. })
  31. It("versions don't have reserved version numbers", func() {
  32. Expect(isReservedVersion(Version39)).To(BeFalse())
  33. Expect(isReservedVersion(Version43)).To(BeFalse())
  34. Expect(isReservedVersion(Version44)).To(BeFalse())
  35. Expect(isReservedVersion(VersionTLS)).To(BeFalse())
  36. })
  37. It("has the right string representation", func() {
  38. Expect(Version39.String()).To(Equal("gQUIC 39"))
  39. Expect(VersionTLS.String()).To(ContainSubstring("TLS"))
  40. Expect(VersionWhatever.String()).To(Equal("whatever"))
  41. Expect(VersionUnknown.String()).To(Equal("unknown"))
  42. // check with unsupported version numbers from the wiki
  43. Expect(VersionNumber(0x51303039).String()).To(Equal("gQUIC 9"))
  44. Expect(VersionNumber(0x51303133).String()).To(Equal("gQUIC 13"))
  45. Expect(VersionNumber(0x51303235).String()).To(Equal("gQUIC 25"))
  46. Expect(VersionNumber(0x51303438).String()).To(Equal("gQUIC 48"))
  47. Expect(VersionNumber(0x01234567).String()).To(Equal("0x1234567"))
  48. })
  49. It("has the right representation for the H2 Alt-Svc tag", func() {
  50. Expect(Version39.ToAltSvc()).To(Equal("39"))
  51. Expect(Version43.ToAltSvc()).To(Equal("43"))
  52. Expect(Version44.ToAltSvc()).To(Equal("44"))
  53. Expect(VersionTLS.ToAltSvc()).To(Equal("101"))
  54. // check with unsupported version numbers from the wiki
  55. Expect(VersionNumber(0x51303133).ToAltSvc()).To(Equal("13"))
  56. Expect(VersionNumber(0x51303235).ToAltSvc()).To(Equal("25"))
  57. Expect(VersionNumber(0x51303438).ToAltSvc()).To(Equal("48"))
  58. })
  59. It("tells the Stream ID of the crypto stream", func() {
  60. Expect(Version39.CryptoStreamID()).To(Equal(StreamID(1)))
  61. Expect(Version43.CryptoStreamID()).To(Equal(StreamID(1)))
  62. Expect(Version44.CryptoStreamID()).To(Equal(StreamID(1)))
  63. Expect(VersionTLS.CryptoStreamID()).To(Equal(StreamID(0)))
  64. })
  65. It("tells if a version uses the IETF frame types", func() {
  66. Expect(Version39.UsesIETFFrameFormat()).To(BeFalse())
  67. Expect(Version43.UsesIETFFrameFormat()).To(BeFalse())
  68. Expect(Version44.UsesIETFFrameFormat()).To(BeFalse())
  69. Expect(VersionTLS.UsesIETFFrameFormat()).To(BeTrue())
  70. })
  71. It("tells if a version uses the IETF header format", func() {
  72. Expect(Version39.UsesIETFHeaderFormat()).To(BeFalse())
  73. Expect(Version43.UsesIETFHeaderFormat()).To(BeFalse())
  74. Expect(Version44.UsesIETFHeaderFormat()).To(BeTrue())
  75. Expect(VersionTLS.UsesIETFHeaderFormat()).To(BeTrue())
  76. })
  77. It("tells if a version uses varint packet numbers", func() {
  78. Expect(Version39.UsesVarintPacketNumbers()).To(BeFalse())
  79. Expect(Version43.UsesVarintPacketNumbers()).To(BeFalse())
  80. Expect(Version44.UsesVarintPacketNumbers()).To(BeFalse())
  81. Expect(VersionTLS.UsesVarintPacketNumbers()).To(BeTrue())
  82. })
  83. It("tells if a version uses the Length field in the IETF header", func() {
  84. Expect(Version44.UsesLengthInHeader()).To(BeFalse())
  85. Expect(VersionTLS.UsesLengthInHeader()).To(BeTrue())
  86. })
  87. It("tells if a version uses the Token field in the IETF header", func() {
  88. Expect(Version44.UsesTokenInHeader()).To(BeFalse())
  89. Expect(VersionTLS.UsesTokenInHeader()).To(BeTrue())
  90. })
  91. It("tells if a version uses STOP_WAITING frames", func() {
  92. Expect(Version39.UsesStopWaitingFrames()).To(BeTrue())
  93. Expect(Version43.UsesStopWaitingFrames()).To(BeTrue())
  94. Expect(Version44.UsesStopWaitingFrames()).To(BeFalse())
  95. Expect(VersionTLS.UsesStopWaitingFrames()).To(BeFalse())
  96. })
  97. It("says if a stream contributes to connection-level flowcontrol, for gQUIC", func() {
  98. for _, v := range []VersionNumber{Version39, Version43, Version44} {
  99. version := v
  100. Expect(version.StreamContributesToConnectionFlowControl(1)).To(BeFalse())
  101. Expect(version.StreamContributesToConnectionFlowControl(2)).To(BeTrue())
  102. Expect(version.StreamContributesToConnectionFlowControl(3)).To(BeFalse())
  103. Expect(version.StreamContributesToConnectionFlowControl(4)).To(BeTrue())
  104. Expect(version.StreamContributesToConnectionFlowControl(5)).To(BeTrue())
  105. }
  106. })
  107. It("says if a stream contributes to connection-level flowcontrol, for TLS", func() {
  108. Expect(VersionTLS.StreamContributesToConnectionFlowControl(0)).To(BeFalse())
  109. Expect(VersionTLS.StreamContributesToConnectionFlowControl(1)).To(BeTrue())
  110. Expect(VersionTLS.StreamContributesToConnectionFlowControl(2)).To(BeTrue())
  111. Expect(VersionTLS.StreamContributesToConnectionFlowControl(3)).To(BeTrue())
  112. })
  113. It("recognizes supported versions", func() {
  114. Expect(IsSupportedVersion(SupportedVersions, 0)).To(BeFalse())
  115. Expect(IsSupportedVersion(SupportedVersions, SupportedVersions[0])).To(BeTrue())
  116. Expect(IsSupportedVersion(SupportedVersions, SupportedVersions[len(SupportedVersions)-1])).To(BeTrue())
  117. })
  118. It("has supported versions in sorted order", func() {
  119. for i := 0; i < len(SupportedVersions)-1; i++ {
  120. Expect(SupportedVersions[i]).To(BeNumerically(">", SupportedVersions[i+1]))
  121. }
  122. })
  123. Context("highest supported version", func() {
  124. It("finds the supported version", func() {
  125. supportedVersions := []VersionNumber{1, 2, 3}
  126. other := []VersionNumber{6, 5, 4, 3}
  127. ver, ok := ChooseSupportedVersion(supportedVersions, other)
  128. Expect(ok).To(BeTrue())
  129. Expect(ver).To(Equal(VersionNumber(3)))
  130. })
  131. It("picks the preferred version", func() {
  132. supportedVersions := []VersionNumber{2, 1, 3}
  133. other := []VersionNumber{3, 6, 1, 8, 2, 10}
  134. ver, ok := ChooseSupportedVersion(supportedVersions, other)
  135. Expect(ok).To(BeTrue())
  136. Expect(ver).To(Equal(VersionNumber(2)))
  137. })
  138. It("says when no matching version was found", func() {
  139. _, ok := ChooseSupportedVersion([]VersionNumber{1}, []VersionNumber{2})
  140. Expect(ok).To(BeFalse())
  141. })
  142. It("handles empty inputs", func() {
  143. _, ok := ChooseSupportedVersion([]VersionNumber{102, 101}, []VersionNumber{})
  144. Expect(ok).To(BeFalse())
  145. _, ok = ChooseSupportedVersion([]VersionNumber{}, []VersionNumber{1, 2})
  146. Expect(ok).To(BeFalse())
  147. _, ok = ChooseSupportedVersion([]VersionNumber{}, []VersionNumber{})
  148. Expect(ok).To(BeFalse())
  149. })
  150. })
  151. Context("reserved versions", func() {
  152. It("adds a greased version if passed an empty slice", func() {
  153. greased := GetGreasedVersions([]VersionNumber{})
  154. Expect(greased).To(HaveLen(1))
  155. Expect(isReservedVersion(greased[0])).To(BeTrue())
  156. })
  157. It("strips greased versions", func() {
  158. v := SupportedVersions[0]
  159. greased := GetGreasedVersions([]VersionNumber{v})
  160. Expect(greased).To(HaveLen(2))
  161. stripped := StripGreasedVersions(greased)
  162. Expect(stripped).To(HaveLen(1))
  163. Expect(stripped[0]).To(Equal(v))
  164. })
  165. It("creates greased lists of version numbers", func() {
  166. supported := []VersionNumber{10, 18, 29}
  167. for _, v := range supported {
  168. Expect(isReservedVersion(v)).To(BeFalse())
  169. }
  170. var greasedVersionFirst, greasedVersionLast, greasedVersionMiddle int
  171. // check that
  172. // 1. the greased version sometimes appears first
  173. // 2. the greased version sometimes appears in the middle
  174. // 3. the greased version sometimes appears last
  175. // 4. the supported versions are kept in order
  176. for i := 0; i < 100; i++ {
  177. greased := GetGreasedVersions(supported)
  178. Expect(greased).To(HaveLen(4))
  179. var j int
  180. for i, v := range greased {
  181. if isReservedVersion(v) {
  182. if i == 0 {
  183. greasedVersionFirst++
  184. }
  185. if i == len(greased)-1 {
  186. greasedVersionLast++
  187. }
  188. greasedVersionMiddle++
  189. continue
  190. }
  191. Expect(supported[j]).To(Equal(v))
  192. j++
  193. }
  194. }
  195. Expect(greasedVersionFirst).ToNot(BeZero())
  196. Expect(greasedVersionLast).ToNot(BeZero())
  197. Expect(greasedVersionMiddle).ToNot(BeZero())
  198. })
  199. })
  200. })