@@ -1261,6 +1261,10 @@ pub mod options {
12611261 ) ;
12621262 }
12631263 _ => {
1264+ // NB: Subtract 2 since we've already advanced beyond
1265+ // the kind and length fields
1266+ let len = len - 2 ;
1267+
12641268 // Ignore unknown options, but move `bytes` ahead to
12651269 // allow subsequent options to be parsed.
12661270 let _: B = bytes. take_front ( len) . ok_or ( ParseError :: Format ) ?;
@@ -1725,15 +1729,15 @@ mod tests {
17251729 builder. syn ( true ) ;
17261730
17271731 let mut buf = builder
1728- . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
1732+ . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
17291733 . serialize_vec_outer ( )
17301734 . unwrap ( ) ;
17311735 // assert that we get the literal bytes we expected
17321736 assert_eq ! (
17331737 buf. as_ref( ) ,
17341738 [
1735- 0 , 1 , 0 , 2 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 4 , 80 , 23 , 0 , 5 , 141 , 137 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 4 ,
1736- 5 , 7 , 8 , 9
1739+ 0 , 1 , 0 , 2 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 4 , 80 , 23 , 0 , 5 , 137 , 145 , 0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 ,
1740+ 7 , 8 , 9
17371741 ]
17381742 ) ;
17391743 let segment = buf
@@ -1746,7 +1750,7 @@ mod tests {
17461750 assert_eq ! ( segment. seq_num( ) , 3 ) ;
17471751 assert_eq ! ( segment. ack_num( ) , Some ( 4 ) ) ;
17481752 assert_eq ! ( segment. window_size( ) , 5 ) ;
1749- assert_eq ! ( segment. body( ) , [ 0 , 1 , 2 , 3 , 3 , 4 , 5 , 7 , 8 , 9 ] ) ;
1753+ assert_eq ! ( segment. body( ) , [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 ] ) ;
17501754 }
17511755
17521756 #[ test]
@@ -1962,7 +1966,7 @@ mod tests {
19621966
19631967 // Serialize and Parse the segment.
19641968 let mut buf = builder
1965- . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
1969+ . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
19661970 . serialize_vec_outer ( )
19671971 . unwrap ( ) ;
19681972 let segment = buf
@@ -1987,7 +1991,7 @@ mod tests {
19871991
19881992 // Serialize the segment.
19891993 let buf = builder
1990- . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
1994+ . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
19911995 . serialize_vec_outer ( )
19921996 . unwrap ( ) ;
19931997
@@ -2003,4 +2007,49 @@ mod tests {
20032007 & expected_options[ ..]
20042008 )
20052009 }
2010+
2011+ #[ derive( Debug ) ]
2012+ struct TcpSegmentBuilderWithUnknownOption < A : IpAddress > ( TcpSegmentBuilder < A > ) ;
2013+
2014+ impl < A : IpAddress > TcpSegmentBuilderWithUnknownOption < A > {
2015+ const UNKNOWN_KIND : u8 = 255 ;
2016+ const OPTION_LEN : u8 = 4 ;
2017+ const OPTION_BYTES : [ u8 ; 4 ] = [ Self :: UNKNOWN_KIND , Self :: OPTION_LEN , 0 , 0 ] ;
2018+ }
2019+
2020+ impl < A : IpAddress > PacketBuilder for TcpSegmentBuilderWithUnknownOption < A > {
2021+ fn constraints ( & self ) -> PacketConstraints {
2022+ let header_len = HDR_PREFIX_LEN + usize:: from ( Self :: OPTION_LEN ) ;
2023+ PacketConstraints :: new ( header_len, 0 , 0 , usize:: MAX )
2024+ }
2025+
2026+ fn serialize ( & self , target : & mut SerializeTarget < ' _ > , body : FragmentedBytesMut < ' _ , ' _ > ) {
2027+ let Self ( prefix_builder) = self ;
2028+ let mut header = & mut & mut target. header [ ..] ;
2029+ header. write_obj_back ( & Self :: OPTION_BYTES ) . unwrap ( ) ;
2030+ prefix_builder. serialize ( target, body) ;
2031+ }
2032+ }
2033+
2034+ #[ test]
2035+ fn test_parse_unknown_option ( ) {
2036+ let builder = TcpSegmentBuilderWithUnknownOption ( new_builder ( TEST_SRC_IPV4 , TEST_DST_IPV4 ) ) ;
2037+
2038+ // Serialize and Parse the segment. Parsing should ignore the unknown
2039+ // option.
2040+ let mut buf = builder
2041+ . wrap_body ( ( & [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 ] ) . into_serializer ( ) )
2042+ . serialize_vec_outer ( )
2043+ . unwrap ( ) ;
2044+ let segment = buf
2045+ . parse_with :: < _ , TcpSegment < _ > > ( TcpParseArgs :: new ( TEST_SRC_IPV4 , TEST_DST_IPV4 ) )
2046+ . unwrap ( ) ;
2047+
2048+ // Verify no options are set.
2049+ assert_eq ! ( segment. options( ) . mss( ) , None ) ;
2050+ assert_eq ! ( segment. options( ) . window_scale( ) , None ) ;
2051+ assert_eq ! ( segment. options( ) . sack_permitted( ) , false ) ;
2052+ assert_eq ! ( segment. options( ) . sack_blocks( ) , None ) ;
2053+ assert_eq ! ( segment. options( ) . timestamp( ) , None ) ;
2054+ }
20062055}
0 commit comments