14
14
15
15
mod cleanup;
16
16
mod closing;
17
+ mod rtt;
17
18
mod stream;
18
19
19
20
use crate :: tagged_stream:: TaggedStream ;
@@ -287,8 +288,15 @@ struct Active<T> {
287
288
288
289
pending_frames : VecDeque < Frame < ( ) > > ,
289
290
new_outbound_stream_waker : Option < Waker > ,
290
- }
291
291
292
+ rtt : rtt:: Rtt ,
293
+
294
+ /// A stream's `max_stream_receive_window` can grow beyond [`DEFAULT_CREDIT`], see
295
+ /// [`Stream::next_window_update`]. This field is the sum of the bytes by which all streams'
296
+ /// `max_stream_receive_window` have each exceeded [`DEFAULT_CREDIT`]. Used to enforce
297
+ /// [`Config::max_connection_receive_window`].
298
+ accumulated_max_stream_windows : Arc < Mutex < usize > > ,
299
+ }
292
300
/// `Stream` to `Connection` commands.
293
301
#[ derive( Debug ) ]
294
302
pub ( crate ) enum StreamCommand {
@@ -300,15 +308,13 @@ pub(crate) enum StreamCommand {
300
308
301
309
/// Possible actions as a result of incoming frame handling.
302
310
#[ derive( Debug ) ]
303
- enum Action {
311
+ pub ( crate ) enum Action {
304
312
/// Nothing to be done.
305
313
None ,
306
314
/// A new stream has been opened by the remote.
307
315
New ( Stream ) ,
308
316
/// A ping should be answered.
309
317
Ping ( Frame < Ping > ) ,
310
- /// A stream should be reset.
311
- Reset ( Frame < Data > ) ,
312
318
/// The connection should be terminated.
313
319
Terminate ( Frame < GoAway > ) ,
314
320
}
@@ -341,7 +347,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
341
347
fn new ( socket : T , cfg : Config , mode : Mode ) -> Self {
342
348
let id = Id :: random ( ) ;
343
349
log:: debug!( "new connection: {} ({:?})" , id, mode) ;
344
- let socket = frame:: Io :: new ( id, socket, cfg . max_buffer_size ) . fuse ( ) ;
350
+ let socket = frame:: Io :: new ( id, socket) . fuse ( ) ;
345
351
Active {
346
352
id,
347
353
mode,
@@ -356,6 +362,8 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
356
362
} ,
357
363
pending_frames : VecDeque :: default ( ) ,
358
364
new_outbound_stream_waker : None ,
365
+ rtt : rtt:: Rtt :: new ( ) ,
366
+ accumulated_max_stream_windows : Default :: default ( ) ,
359
367
}
360
368
}
361
369
@@ -376,6 +384,14 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
376
384
fn poll ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < Stream > > {
377
385
loop {
378
386
if self . socket . poll_ready_unpin ( cx) . is_ready ( ) {
387
+ // Note `next_ping` does not register a waker and thus if not called regularly (idle
388
+ // connection) no ping is sent. This is deliberate as an idle connection does not
389
+ // need RTT measurements to increase its stream receive window.
390
+ if let Some ( frame) = self . rtt . next_ping ( ) {
391
+ self . socket . start_send_unpin ( frame. into ( ) ) ?;
392
+ continue ;
393
+ }
394
+
379
395
if let Some ( frame) = self . pending_frames . pop_front ( ) {
380
396
self . socket . start_send_unpin ( frame) ?;
381
397
continue ;
@@ -439,20 +455,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
439
455
log:: trace!( "{}: creating new outbound stream" , self . id) ;
440
456
441
457
let id = self . next_stream_id ( ) ?;
442
- let extra_credit = self . config . receive_window - DEFAULT_CREDIT ;
443
-
444
- if extra_credit > 0 {
445
- let mut frame = Frame :: window_update ( id, extra_credit) ;
446
- frame. header_mut ( ) . syn ( ) ;
447
- log:: trace!( "{}/{}: sending initial {}" , self . id, id, frame. header( ) ) ;
448
- self . pending_frames . push_back ( frame. into ( ) ) ;
449
- }
450
-
451
- let mut stream = self . make_new_outbound_stream ( id, self . config . receive_window ) ;
452
-
453
- if extra_credit == 0 {
454
- stream. set_flag ( stream:: Flag :: Syn )
455
- }
458
+ let stream = self . make_new_outbound_stream ( id) ;
456
459
457
460
log:: debug!( "{}: new outbound {} of {}" , self . id, stream, self ) ;
458
461
self . streams . insert ( id, stream. clone_shared ( ) ) ;
@@ -537,7 +540,9 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
537
540
fn on_frame ( & mut self , frame : Frame < ( ) > ) -> Result < Option < Stream > > {
538
541
log:: trace!( "{}: received: {}" , self . id, frame. header( ) ) ;
539
542
540
- if frame. header ( ) . flags ( ) . contains ( header:: ACK ) {
543
+ if frame. header ( ) . flags ( ) . contains ( header:: ACK )
544
+ && matches ! ( frame. header( ) . tag( ) , Tag :: Data | Tag :: WindowUpdate )
545
+ {
541
546
let id = frame. header ( ) . stream_id ( ) ;
542
547
if let Some ( stream) = self . streams . get ( & id) {
543
548
stream
@@ -565,10 +570,6 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
565
570
log:: trace!( "{}/{}: pong" , self . id, f. header( ) . stream_id( ) ) ;
566
571
self . pending_frames . push_back ( f. into ( ) ) ;
567
572
}
568
- Action :: Reset ( f) => {
569
- log:: trace!( "{}/{}: sending reset" , self . id, f. header( ) . stream_id( ) ) ;
570
- self . pending_frames . push_back ( f. into ( ) ) ;
571
- }
572
573
Action :: Terminate ( f) => {
573
574
log:: trace!( "{}: sending term" , self . id) ;
574
575
self . pending_frames . push_back ( f. into ( ) ) ;
@@ -620,23 +621,22 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
620
621
log:: error!( "{}: maximum number of streams reached" , self . id) ;
621
622
return Action :: Terminate ( Frame :: internal_error ( ) ) ;
622
623
}
623
- let mut stream = self . make_new_inbound_stream ( stream_id, DEFAULT_CREDIT ) ;
624
+ let stream = self . make_new_inbound_stream ( stream_id, DEFAULT_CREDIT ) ;
624
625
{
625
626
let mut shared = stream. shared ( ) ;
626
627
if is_finish {
627
628
shared. update_state ( self . id , stream_id, State :: RecvClosed ) ;
628
629
}
629
- shared. window = shared . window . saturating_sub ( frame. body_len ( ) ) ;
630
+ shared. consume_receive_window ( frame. body_len ( ) ) ;
630
631
shared. buffer . push ( frame. into_body ( ) ) ;
631
632
}
632
- stream. set_flag ( stream:: Flag :: Ack ) ;
633
633
self . streams . insert ( stream_id, stream. clone_shared ( ) ) ;
634
634
return Action :: New ( stream) ;
635
635
}
636
636
637
637
if let Some ( s) = self . streams . get_mut ( & stream_id) {
638
638
let mut shared = s. lock ( ) ;
639
- if frame. body ( ) . len ( ) > shared. window as usize {
639
+ if frame. body_len ( ) > shared. receive_window ( ) {
640
640
log:: error!(
641
641
"{}/{}: frame body larger than window of stream" ,
642
642
self . id,
@@ -647,18 +647,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
647
647
if is_finish {
648
648
shared. update_state ( self . id , stream_id, State :: RecvClosed ) ;
649
649
}
650
- let max_buffer_size = self . config . max_buffer_size ;
651
- if shared. buffer . len ( ) >= max_buffer_size {
652
- log:: error!(
653
- "{}/{}: buffer of stream grows beyond limit" ,
654
- self . id,
655
- stream_id
656
- ) ;
657
- let mut header = Header :: data ( stream_id, 0 ) ;
658
- header. rst ( ) ;
659
- return Action :: Reset ( Frame :: new ( header) ) ;
660
- }
661
- shared. window = shared. window . saturating_sub ( frame. body_len ( ) ) ;
650
+ shared. consume_receive_window ( frame. body_len ( ) ) ;
662
651
shared. buffer . push ( frame. into_body ( ) ) ;
663
652
if let Some ( w) = shared. reader . take ( ) {
664
653
w. wake ( )
@@ -718,8 +707,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
718
707
}
719
708
720
709
let credit = frame. header ( ) . credit ( ) + DEFAULT_CREDIT ;
721
- let mut stream = self . make_new_inbound_stream ( stream_id, credit) ;
722
- stream. set_flag ( stream:: Flag :: Ack ) ;
710
+ let stream = self . make_new_inbound_stream ( stream_id, credit) ;
723
711
724
712
if is_finish {
725
713
stream
@@ -732,7 +720,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
732
720
733
721
if let Some ( s) = self . streams . get_mut ( & stream_id) {
734
722
let mut shared = s. lock ( ) ;
735
- shared. credit += frame. header ( ) . credit ( ) ;
723
+ shared. increase_send_window_by ( frame. header ( ) . credit ( ) ) ;
736
724
if is_finish {
737
725
shared. update_state ( self . id , stream_id, State :: RecvClosed ) ;
738
726
}
@@ -761,15 +749,14 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
761
749
fn on_ping ( & mut self , frame : & Frame < Ping > ) -> Action {
762
750
let stream_id = frame. header ( ) . stream_id ( ) ;
763
751
if frame. header ( ) . flags ( ) . contains ( header:: ACK ) {
764
- // pong
765
- return Action :: None ;
752
+ return self . rtt . handle_pong ( frame. nonce ( ) ) ;
766
753
}
767
754
if stream_id == CONNECTION_ID || self . streams . contains_key ( & stream_id) {
768
755
let mut hdr = Header :: ping ( frame. header ( ) . nonce ( ) ) ;
769
756
hdr. ack ( ) ;
770
757
return Action :: Ping ( Frame :: new ( hdr) ) ;
771
758
}
772
- log:: trace !(
759
+ log:: debug !(
773
760
"{}/{}: ping for unknown stream, possibly dropped earlier: {:?}" ,
774
761
self . id,
775
762
stream_id,
@@ -794,10 +781,18 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
794
781
waker. wake ( ) ;
795
782
}
796
783
797
- Stream :: new_inbound ( id, self . id , config, credit, sender)
784
+ Stream :: new_inbound (
785
+ id,
786
+ self . id ,
787
+ config,
788
+ credit,
789
+ sender,
790
+ self . rtt . clone ( ) ,
791
+ self . accumulated_max_stream_windows . clone ( ) ,
792
+ )
798
793
}
799
794
800
- fn make_new_outbound_stream ( & mut self , id : StreamId , window : u32 ) -> Stream {
795
+ fn make_new_outbound_stream ( & mut self , id : StreamId ) -> Stream {
801
796
let config = self . config . clone ( ) ;
802
797
803
798
let ( sender, receiver) = mpsc:: channel ( 10 ) ; // 10 is an arbitrary number.
@@ -806,7 +801,14 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
806
801
waker. wake ( ) ;
807
802
}
808
803
809
- Stream :: new_outbound ( id, self . id , config, window, sender)
804
+ Stream :: new_outbound (
805
+ id,
806
+ self . id ,
807
+ config,
808
+ sender,
809
+ self . rtt . clone ( ) ,
810
+ self . accumulated_max_stream_windows . clone ( ) ,
811
+ )
810
812
}
811
813
812
814
fn next_stream_id ( & mut self ) -> Result < StreamId > {
0 commit comments