1
1
// Heads up! Before working on this file you should read, at least, RFC 793 and
2
- // the parts of RFC 1122 that discuss TCP. Consult RFC 7414 when implementing
3
- // a new feature.
2
+ // the parts of RFC 1122 that discuss TCP, as well as RFC 7323 for some of the TCP options.
3
+ // Consult RFC 7414 when implementing a new feature.
4
4
5
5
use core:: fmt:: Display ;
6
6
#[ cfg( feature = "async" ) ]
@@ -14,7 +14,7 @@ use crate::storage::{Assembler, RingBuffer};
14
14
use crate :: time:: { Duration , Instant } ;
15
15
use crate :: wire:: {
16
16
IpAddress , IpEndpoint , IpListenEndpoint , IpProtocol , IpRepr , TcpControl , TcpRepr , TcpSeqNumber ,
17
- TCP_HEADER_LEN ,
17
+ TcpTimestampGenerator , TcpTimestampRepr , TCP_HEADER_LEN ,
18
18
} ;
19
19
20
20
mod congestion;
@@ -482,6 +482,12 @@ pub struct Socket<'a> {
482
482
/// The congestion control algorithm.
483
483
congestion_controller : congestion:: AnyController ,
484
484
485
+ /// tsval generator - if some, tcp timestamp is enabled
486
+ tsval_generator : Option < TcpTimestampGenerator > ,
487
+
488
+ /// 0 if not seen or timestamp not enabled
489
+ last_remote_tsval : u32 ,
490
+
485
491
#[ cfg( feature = "async" ) ]
486
492
rx_waker : WakerRegistration ,
487
493
#[ cfg( feature = "async" ) ]
@@ -540,6 +546,8 @@ impl<'a> Socket<'a> {
540
546
ack_delay_timer : AckDelayTimer :: Idle ,
541
547
challenge_ack_timer : Instant :: from_secs ( 0 ) ,
542
548
nagle : true ,
549
+ tsval_generator : None ,
550
+ last_remote_tsval : 0 ,
543
551
congestion_controller : congestion:: AnyController :: new ( ) ,
544
552
545
553
#[ cfg( feature = "async" ) ]
@@ -549,6 +557,16 @@ impl<'a> Socket<'a> {
549
557
}
550
558
}
551
559
560
+ /// Enable or disable TCP Timestamp.
561
+ pub fn set_tsval_generator ( & mut self , generator : Option < TcpTimestampGenerator > ) {
562
+ self . tsval_generator = generator;
563
+ }
564
+
565
+ /// Return whether TCP Timestamp is enabled.
566
+ pub fn timestamp_enabled ( & self ) -> bool {
567
+ self . tsval_generator . is_some ( )
568
+ }
569
+
552
570
/// Set an algorithm for congestion control.
553
571
///
554
572
/// `CongestionControl::None` indicates that no congestion control is applied.
@@ -1300,6 +1318,7 @@ impl<'a> Socket<'a> {
1300
1318
max_seg_size : None ,
1301
1319
sack_permitted : false ,
1302
1320
sack_ranges : [ None , None , None ] ,
1321
+ timestamp : None ,
1303
1322
payload : & [ ] ,
1304
1323
} ;
1305
1324
let ip_reply_repr = IpRepr :: new (
@@ -1330,6 +1349,9 @@ impl<'a> Socket<'a> {
1330
1349
1331
1350
fn ack_reply ( & mut self , ip_repr : & IpRepr , repr : & TcpRepr ) -> ( IpRepr , TcpRepr < ' static > ) {
1332
1351
let ( mut ip_reply_repr, mut reply_repr) = Self :: reply ( ip_repr, repr) ;
1352
+ reply_repr. timestamp = repr
1353
+ . timestamp
1354
+ . and_then ( |tcp_ts| tcp_ts. generate_reply ( self . tsval_generator ) ) ;
1333
1355
1334
1356
// From RFC 793:
1335
1357
// [...] an empty acknowledgment segment containing the current send-sequence number
@@ -1725,6 +1747,10 @@ impl<'a> Socket<'a> {
1725
1747
if self . remote_win_scale . is_none ( ) {
1726
1748
self . remote_win_shift = 0 ;
1727
1749
}
1750
+ // Remote doesn't support timestamping, don't do it.
1751
+ if repr. timestamp . is_none ( ) {
1752
+ self . tsval_generator = None ;
1753
+ }
1728
1754
self . set_state ( State :: SynReceived ) ;
1729
1755
self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
1730
1756
}
@@ -1767,6 +1793,10 @@ impl<'a> Socket<'a> {
1767
1793
if self . remote_win_scale . is_none ( ) {
1768
1794
self . remote_win_shift = 0 ;
1769
1795
}
1796
+ // Remote doesn't support timestamping, don't do it.
1797
+ if repr. timestamp . is_none ( ) {
1798
+ self . tsval_generator = None ;
1799
+ }
1770
1800
1771
1801
self . set_state ( State :: Established ) ;
1772
1802
self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
@@ -1954,6 +1984,11 @@ impl<'a> Socket<'a> {
1954
1984
}
1955
1985
}
1956
1986
1987
+ // update last remote tsval
1988
+ if let Some ( timestamp) = repr. timestamp {
1989
+ self . last_remote_tsval = timestamp. tsval ;
1990
+ }
1991
+
1957
1992
let payload_len = payload. len ( ) ;
1958
1993
if payload_len == 0 {
1959
1994
return None ;
@@ -2246,6 +2281,10 @@ impl<'a> Socket<'a> {
2246
2281
max_seg_size : None ,
2247
2282
sack_permitted : false ,
2248
2283
sack_ranges : [ None , None , None ] ,
2284
+ timestamp : TcpTimestampRepr :: generate_reply_with_tsval (
2285
+ self . tsval_generator ,
2286
+ self . last_remote_tsval ,
2287
+ ) ,
2249
2288
payload : & [ ] ,
2250
2289
} ;
2251
2290
@@ -2574,6 +2613,7 @@ mod test {
2574
2613
max_seg_size : None ,
2575
2614
sack_permitted : false ,
2576
2615
sack_ranges : [ None , None , None ] ,
2616
+ timestamp : None ,
2577
2617
payload : & [ ] ,
2578
2618
} ;
2579
2619
const _RECV_IP_TEMPL: IpRepr = IpReprIpvX ( IpvXRepr {
@@ -2594,6 +2634,7 @@ mod test {
2594
2634
max_seg_size : None ,
2595
2635
sack_permitted : false ,
2596
2636
sack_ranges : [ None , None , None ] ,
2637
+ timestamp : None ,
2597
2638
payload : & [ ] ,
2598
2639
} ;
2599
2640
@@ -7429,4 +7470,239 @@ mod test {
7429
7470
s. set_congestion_control ( CongestionControl :: None ) ;
7430
7471
assert_eq ! ( s. congestion_control( ) , CongestionControl :: None ) ;
7431
7472
}
7473
+
7474
+ // =========================================================================================//
7475
+ // Timestamp tests
7476
+ // =========================================================================================//
7477
+
7478
+ #[ test]
7479
+ fn test_tsval_established_connection ( ) {
7480
+ let mut s = socket_established ( ) ;
7481
+ s. set_tsval_generator ( Some ( || 1 ) ) ;
7482
+
7483
+ assert ! ( s. timestamp_enabled( ) ) ;
7484
+
7485
+ // First roundtrip after establishing.
7486
+ s. send_slice ( b"abcdef" ) . unwrap ( ) ;
7487
+ recv ! (
7488
+ s,
7489
+ [ TcpRepr {
7490
+ seq_number: LOCAL_SEQ + 1 ,
7491
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7492
+ payload: & b"abcdef" [ ..] ,
7493
+ timestamp: Some ( TcpTimestampRepr :: new( 1 , 0 ) ) ,
7494
+ ..RECV_TEMPL
7495
+ } ]
7496
+ ) ;
7497
+ assert_eq ! ( s. tx_buffer. len( ) , 6 ) ;
7498
+ send ! (
7499
+ s,
7500
+ TcpRepr {
7501
+ seq_number: REMOTE_SEQ + 1 ,
7502
+ ack_number: Some ( LOCAL_SEQ + 1 + 6 ) ,
7503
+ timestamp: Some ( TcpTimestampRepr :: new( 500 , 1 ) ) ,
7504
+ ..SEND_TEMPL
7505
+ }
7506
+ ) ;
7507
+ assert_eq ! ( s. tx_buffer. len( ) , 0 ) ;
7508
+ // Second roundtrip.
7509
+ s. send_slice ( b"foobar" ) . unwrap ( ) ;
7510
+ recv ! (
7511
+ s,
7512
+ [ TcpRepr {
7513
+ seq_number: LOCAL_SEQ + 1 + 6 ,
7514
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7515
+ payload: & b"foobar" [ ..] ,
7516
+ timestamp: Some ( TcpTimestampRepr :: new( 1 , 500 ) ) ,
7517
+ ..RECV_TEMPL
7518
+ } ]
7519
+ ) ;
7520
+ send ! (
7521
+ s,
7522
+ TcpRepr {
7523
+ seq_number: REMOTE_SEQ + 1 ,
7524
+ ack_number: Some ( LOCAL_SEQ + 1 + 6 + 6 ) ,
7525
+ ..SEND_TEMPL
7526
+ }
7527
+ ) ;
7528
+ assert_eq ! ( s. tx_buffer. len( ) , 0 ) ;
7529
+ }
7530
+
7531
+ #[ test]
7532
+ fn test_tsval_disabled_in_remote_client ( ) {
7533
+ let mut s = socket_listen ( ) ;
7534
+ s. set_tsval_generator ( Some ( || 1 ) ) ;
7535
+ assert ! ( s. timestamp_enabled( ) ) ;
7536
+ send ! (
7537
+ s,
7538
+ TcpRepr {
7539
+ control: TcpControl :: Syn ,
7540
+ seq_number: REMOTE_SEQ ,
7541
+ ack_number: None ,
7542
+ ..SEND_TEMPL
7543
+ }
7544
+ ) ;
7545
+ assert_eq ! ( s. state( ) , State :: SynReceived ) ;
7546
+ assert_eq ! ( s. tuple, Some ( TUPLE ) ) ;
7547
+ assert ! ( !s. timestamp_enabled( ) ) ;
7548
+ recv ! (
7549
+ s,
7550
+ [ TcpRepr {
7551
+ control: TcpControl :: Syn ,
7552
+ seq_number: LOCAL_SEQ ,
7553
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7554
+ max_seg_size: Some ( BASE_MSS ) ,
7555
+ ..RECV_TEMPL
7556
+ } ]
7557
+ ) ;
7558
+ send ! (
7559
+ s,
7560
+ TcpRepr {
7561
+ seq_number: REMOTE_SEQ + 1 ,
7562
+ ack_number: Some ( LOCAL_SEQ + 1 ) ,
7563
+ ..SEND_TEMPL
7564
+ }
7565
+ ) ;
7566
+ assert_eq ! ( s. state( ) , State :: Established ) ;
7567
+ assert_eq ! ( s. local_seq_no, LOCAL_SEQ + 1 ) ;
7568
+ assert_eq ! ( s. remote_seq_no, REMOTE_SEQ + 1 ) ;
7569
+ }
7570
+
7571
+ #[ test]
7572
+ fn test_tsval_disabled_in_local_server ( ) {
7573
+ let mut s = socket_listen ( ) ;
7574
+ // s.set_timestamp(false); // commented to alert if the default state changes
7575
+ assert ! ( !s. timestamp_enabled( ) ) ;
7576
+ send ! (
7577
+ s,
7578
+ TcpRepr {
7579
+ control: TcpControl :: Syn ,
7580
+ seq_number: REMOTE_SEQ ,
7581
+ ack_number: None ,
7582
+ timestamp: Some ( TcpTimestampRepr :: new( 500 , 0 ) ) ,
7583
+ ..SEND_TEMPL
7584
+ }
7585
+ ) ;
7586
+ assert_eq ! ( s. state( ) , State :: SynReceived ) ;
7587
+ assert_eq ! ( s. tuple, Some ( TUPLE ) ) ;
7588
+ assert ! ( !s. timestamp_enabled( ) ) ;
7589
+ recv ! (
7590
+ s,
7591
+ [ TcpRepr {
7592
+ control: TcpControl :: Syn ,
7593
+ seq_number: LOCAL_SEQ ,
7594
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7595
+ max_seg_size: Some ( BASE_MSS ) ,
7596
+ ..RECV_TEMPL
7597
+ } ]
7598
+ ) ;
7599
+ send ! (
7600
+ s,
7601
+ TcpRepr {
7602
+ seq_number: REMOTE_SEQ + 1 ,
7603
+ ack_number: Some ( LOCAL_SEQ + 1 ) ,
7604
+ ..SEND_TEMPL
7605
+ }
7606
+ ) ;
7607
+ assert_eq ! ( s. state( ) , State :: Established ) ;
7608
+ assert_eq ! ( s. local_seq_no, LOCAL_SEQ + 1 ) ;
7609
+ assert_eq ! ( s. remote_seq_no, REMOTE_SEQ + 1 ) ;
7610
+ }
7611
+
7612
+ #[ test]
7613
+ fn test_tsval_disabled_in_remote_server ( ) {
7614
+ let mut s = socket ( ) ;
7615
+ s. set_tsval_generator ( Some ( || 1 ) ) ;
7616
+ assert ! ( s. timestamp_enabled( ) ) ;
7617
+ s. local_seq_no = LOCAL_SEQ ;
7618
+ s. socket
7619
+ . connect ( & mut s. cx , REMOTE_END , LOCAL_END . port )
7620
+ . unwrap ( ) ;
7621
+ assert_eq ! ( s. tuple, Some ( TUPLE ) ) ;
7622
+ recv ! (
7623
+ s,
7624
+ [ TcpRepr {
7625
+ control: TcpControl :: Syn ,
7626
+ seq_number: LOCAL_SEQ ,
7627
+ ack_number: None ,
7628
+ max_seg_size: Some ( BASE_MSS ) ,
7629
+ window_scale: Some ( 0 ) ,
7630
+ sack_permitted: true ,
7631
+ timestamp: Some ( TcpTimestampRepr :: new( 1 , 0 ) ) ,
7632
+ ..RECV_TEMPL
7633
+ } ]
7634
+ ) ;
7635
+ send ! (
7636
+ s,
7637
+ TcpRepr {
7638
+ control: TcpControl :: Syn ,
7639
+ seq_number: REMOTE_SEQ ,
7640
+ ack_number: Some ( LOCAL_SEQ + 1 ) ,
7641
+ max_seg_size: Some ( BASE_MSS - 80 ) ,
7642
+ window_scale: Some ( 0 ) ,
7643
+ timestamp: None ,
7644
+ ..SEND_TEMPL
7645
+ }
7646
+ ) ;
7647
+ assert ! ( !s. timestamp_enabled( ) ) ;
7648
+ s. send_slice ( b"abcdef" ) . unwrap ( ) ;
7649
+ recv ! (
7650
+ s,
7651
+ [ TcpRepr {
7652
+ seq_number: LOCAL_SEQ + 1 ,
7653
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7654
+ payload: & b"abcdef" [ ..] ,
7655
+ timestamp: None ,
7656
+ ..RECV_TEMPL
7657
+ } ]
7658
+ ) ;
7659
+ }
7660
+
7661
+ #[ test]
7662
+ fn test_tsval_disabled_in_local_client ( ) {
7663
+ let mut s = socket ( ) ;
7664
+ // s.set_timestamp(false); // commented to alert if the default state changes
7665
+ assert ! ( !s. timestamp_enabled( ) ) ;
7666
+ s. local_seq_no = LOCAL_SEQ ;
7667
+ s. socket
7668
+ . connect ( & mut s. cx , REMOTE_END , LOCAL_END . port )
7669
+ . unwrap ( ) ;
7670
+ assert_eq ! ( s. tuple, Some ( TUPLE ) ) ;
7671
+ recv ! (
7672
+ s,
7673
+ [ TcpRepr {
7674
+ control: TcpControl :: Syn ,
7675
+ seq_number: LOCAL_SEQ ,
7676
+ ack_number: None ,
7677
+ max_seg_size: Some ( BASE_MSS ) ,
7678
+ window_scale: Some ( 0 ) ,
7679
+ sack_permitted: true ,
7680
+ ..RECV_TEMPL
7681
+ } ]
7682
+ ) ;
7683
+ send ! (
7684
+ s,
7685
+ TcpRepr {
7686
+ control: TcpControl :: Syn ,
7687
+ seq_number: REMOTE_SEQ ,
7688
+ ack_number: Some ( LOCAL_SEQ + 1 ) ,
7689
+ max_seg_size: Some ( BASE_MSS - 80 ) ,
7690
+ window_scale: Some ( 0 ) ,
7691
+ timestamp: Some ( TcpTimestampRepr :: new( 500 , 0 ) ) ,
7692
+ ..SEND_TEMPL
7693
+ }
7694
+ ) ;
7695
+ assert ! ( !s. timestamp_enabled( ) ) ;
7696
+ s. send_slice ( b"abcdef" ) . unwrap ( ) ;
7697
+ recv ! (
7698
+ s,
7699
+ [ TcpRepr {
7700
+ seq_number: LOCAL_SEQ + 1 ,
7701
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7702
+ payload: & b"abcdef" [ ..] ,
7703
+ timestamp: None ,
7704
+ ..RECV_TEMPL
7705
+ } ]
7706
+ ) ;
7707
+ }
7432
7708
}
0 commit comments