@@ -21,11 +21,22 @@ import (
21
21
)
22
22
23
23
var _ = Describe ("0-RTT" , func () {
24
- const rtt = 50 * time .Millisecond
24
+ rtt := scaleDuration (5 * time .Millisecond )
25
+
25
26
for _ , v := range protocol .SupportedVersions {
26
27
version := v
27
28
28
29
Context (fmt .Sprintf ("with QUIC version %s" , version ), func () {
30
+ runDelayProxy := func (serverPort int ) * quicproxy.QuicProxy {
31
+ proxy , err := quicproxy .NewQuicProxy ("localhost:0" , & quicproxy.Opts {
32
+ RemoteAddr : fmt .Sprintf ("localhost:%d" , serverPort ),
33
+ DelayPacket : func (_ quicproxy.Direction , data []byte ) time.Duration { return rtt / 2 },
34
+ })
35
+ Expect (err ).ToNot (HaveOccurred ())
36
+
37
+ return proxy
38
+ }
39
+
29
40
runCountingProxy := func (serverPort int ) (* quicproxy.QuicProxy , * uint32 ) {
30
41
var num0RTTPackets uint32 // to be used as an atomic
31
42
proxy , err := quicproxy .NewQuicProxy ("localhost:0" , & quicproxy.Opts {
@@ -105,6 +116,34 @@ var _ = Describe("0-RTT", func() {
105
116
Eventually (done ).Should (BeClosed ())
106
117
}
107
118
119
+ check0RTTRejected := func (
120
+ ln quic.EarlyListener ,
121
+ proxyPort int ,
122
+ clientConf * tls.Config ,
123
+ ) {
124
+ sess , err := quic .DialAddrEarly (
125
+ fmt .Sprintf ("localhost:%d" , proxyPort ),
126
+ clientConf ,
127
+ getQuicConfig (& quic.Config {Versions : []protocol.VersionNumber {version }}),
128
+ )
129
+ Expect (err ).ToNot (HaveOccurred ())
130
+ str , err := sess .OpenUniStream ()
131
+ Expect (err ).ToNot (HaveOccurred ())
132
+ _ , err = str .Write (make ([]byte , 3000 ))
133
+ Expect (err ).ToNot (HaveOccurred ())
134
+ Expect (str .Close ()).To (Succeed ())
135
+ Expect (sess .ConnectionState ().TLS .Used0RTT ).To (BeFalse ())
136
+
137
+ // make sure the server doesn't process the data
138
+ ctx , cancel := context .WithTimeout (context .Background (), scaleDuration (50 * time .Millisecond ))
139
+ defer cancel ()
140
+ serverSess , err := ln .Accept (ctx )
141
+ Expect (err ).ToNot (HaveOccurred ())
142
+ Expect (serverSess .ConnectionState ().TLS .Used0RTT ).To (BeFalse ())
143
+ _ , err = serverSess .AcceptUniStream (ctx )
144
+ Expect (err ).To (Equal (context .DeadlineExceeded ))
145
+ }
146
+
108
147
It ("transfers 0-RTT data" , func () {
109
148
ln , err := quic .ListenAddrEarly (
110
149
"localhost:0" ,
@@ -354,7 +393,7 @@ var _ = Describe("0-RTT", func() {
354
393
Expect (err ).ToNot (HaveOccurred ())
355
394
proxy , num0RTTPackets := runCountingProxy (ln .Addr ().(* net.UDPAddr ).Port )
356
395
defer proxy .Close ()
357
- transfer0RTTData (ln , proxy .LocalPort (), clientConf , PRData , false )
396
+ check0RTTRejected (ln , proxy .LocalPort (), clientConf )
358
397
359
398
// The client should send 0-RTT packets, but the server doesn't process them.
360
399
num0RTT := atomic .LoadUint32 (num0RTTPackets )
@@ -374,7 +413,9 @@ var _ = Describe("0-RTT", func() {
374
413
)
375
414
Expect (err ).ToNot (HaveOccurred ())
376
415
377
- clientConf := dialAndReceiveSessionTicket (ln , ln .Addr ().(* net.UDPAddr ).Port )
416
+ delayProxy := runDelayProxy (ln .Addr ().(* net.UDPAddr ).Port )
417
+ defer delayProxy .Close ()
418
+ clientConf := dialAndReceiveSessionTicket (ln , delayProxy .LocalPort ())
378
419
379
420
// now close the listener and dial new connection with a different ALPN
380
421
Expect (ln .Close ()).To (Succeed ())
@@ -391,7 +432,91 @@ var _ = Describe("0-RTT", func() {
391
432
Expect (err ).ToNot (HaveOccurred ())
392
433
proxy , num0RTTPackets := runCountingProxy (ln .Addr ().(* net.UDPAddr ).Port )
393
434
defer proxy .Close ()
394
- transfer0RTTData (ln , proxy .LocalPort (), clientConf , PRData , false )
435
+
436
+ check0RTTRejected (ln , proxy .LocalPort (), clientConf )
437
+
438
+ // The client should send 0-RTT packets, but the server doesn't process them.
439
+ num0RTT := atomic .LoadUint32 (num0RTTPackets )
440
+ fmt .Fprintf (GinkgoWriter , "Sent %d 0-RTT packets." , num0RTT )
441
+ Expect (num0RTT ).ToNot (BeZero ())
442
+ })
443
+
444
+ It ("correctly deals with 0-RTT rejections" , func () {
445
+ tlsConf := getTLSConfig ()
446
+ ln , err := quic .ListenAddrEarly (
447
+ "localhost:0" ,
448
+ tlsConf ,
449
+ getQuicConfig (& quic.Config {
450
+ Versions : []protocol.VersionNumber {version },
451
+ MaxIncomingUniStreams : 2 ,
452
+ AcceptToken : func (_ net.Addr , _ * quic.Token ) bool { return true },
453
+ }),
454
+ )
455
+ Expect (err ).ToNot (HaveOccurred ())
456
+
457
+ delayProxy := runDelayProxy (ln .Addr ().(* net.UDPAddr ).Port )
458
+ defer delayProxy .Close ()
459
+ clientConf := dialAndReceiveSessionTicket (ln , delayProxy .LocalPort ())
460
+ // now close the listener and dial new connection with different transport parameters
461
+ Expect (ln .Close ()).To (Succeed ())
462
+ ln , err = quic .ListenAddrEarly (
463
+ "localhost:0" ,
464
+ tlsConf ,
465
+ getQuicConfig (& quic.Config {
466
+ Versions : []protocol.VersionNumber {version },
467
+ MaxIncomingUniStreams : 1 ,
468
+ }),
469
+ )
470
+ Expect (err ).ToNot (HaveOccurred ())
471
+ proxy , num0RTTPackets := runCountingProxy (ln .Addr ().(* net.UDPAddr ).Port )
472
+ defer proxy .Close ()
473
+
474
+ done := make (chan struct {})
475
+ go func () {
476
+ defer GinkgoRecover ()
477
+ defer close (done )
478
+ sess , err := ln .Accept (context .Background ())
479
+ Expect (err ).ToNot (HaveOccurred ())
480
+ str , err := sess .AcceptUniStream (context .Background ())
481
+ Expect (err ).ToNot (HaveOccurred ())
482
+ data , err := ioutil .ReadAll (str )
483
+ Expect (err ).ToNot (HaveOccurred ())
484
+ Expect (string (data )).To (Equal ("second flight" ))
485
+ }()
486
+
487
+ sess , err := quic .DialAddrEarly (
488
+ fmt .Sprintf ("localhost:%d" , proxy .LocalPort ()),
489
+ clientConf ,
490
+ getQuicConfig (& quic.Config {Versions : []protocol.VersionNumber {version }}),
491
+ )
492
+ Expect (err ).ToNot (HaveOccurred ())
493
+ // The client remembers that it was allowed to open 2 uni-directional streams.
494
+ for i := 0 ; i < 2 ; i ++ {
495
+ str , err := sess .OpenUniStream ()
496
+ Expect (err ).ToNot (HaveOccurred ())
497
+ go func () {
498
+ defer GinkgoRecover ()
499
+ _ , err = str .Write ([]byte ("first flight" ))
500
+ Expect (err ).ToNot (HaveOccurred ())
501
+ }()
502
+ }
503
+
504
+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
505
+ defer cancel ()
506
+ _ , err = sess .AcceptStream (ctx )
507
+ Expect (err ).To (Equal (quic .Err0RTTRejected ))
508
+
509
+ newSess := sess .NextSession ()
510
+ str , err := newSess .OpenUniStream ()
511
+ Expect (err ).ToNot (HaveOccurred ())
512
+ _ , err = newSess .OpenUniStream ()
513
+ Expect (err ).To (HaveOccurred ())
514
+ Expect (err .Error ()).To (ContainSubstring ("too many open streams" ))
515
+ _ , err = str .Write ([]byte ("second flight" ))
516
+ Expect (err ).ToNot (HaveOccurred ())
517
+ Expect (str .Close ()).To (Succeed ())
518
+
519
+ Eventually (done ).Should (BeClosed ())
395
520
396
521
// The client should send 0-RTT packets, but the server doesn't process them.
397
522
num0RTT := atomic .LoadUint32 (num0RTTPackets )
0 commit comments