@@ -1070,18 +1070,40 @@ async fn auto_mtu_detection(
1070
1070
/// points.
1071
1071
#[ cfg( target_os = "linux" ) ]
1072
1072
fn mtu_spacing ( mtu_min : u16 , mtu_max : u16 , step_size : u16 ) -> Vec < u16 > {
1073
- if mtu_min > mtu_max {
1074
- panic ! ( "Invalid MTU detection range: `mtu_min`={mtu_min}, `mtu_max`={mtu_max}." ) ;
1075
- }
1076
- let second_mtu = mtu_min. next_multiple_of ( step_size) ;
1073
+ assert ! ( mtu_min < mtu_max) ;
1074
+ assert ! ( step_size < mtu_max) ;
1075
+ assert_ne ! ( step_size, 0 ) ;
1076
+
1077
+ let second_mtu = ( mtu_min + 1 ) . next_multiple_of ( step_size) ;
1077
1078
let in_between = ( second_mtu..mtu_max) . step_by ( step_size as usize ) ;
1078
- let mut ret = Vec :: with_capacity ( ( ( mtu_max - second_mtu) . div_ceil ( step_size) + 2 ) as usize ) ;
1079
+
1080
+ let mut ret = Vec :: with_capacity ( in_between. clone ( ) . count ( ) + 2 ) ;
1079
1081
ret. push ( mtu_min) ;
1080
1082
ret. extend ( in_between) ;
1081
1083
ret. push ( mtu_max) ;
1082
1084
ret
1083
1085
}
1084
1086
1087
+ #[ cfg( all( test, target_os = "linux" ) ) ]
1088
+ mod tests {
1089
+ use crate :: mtu_spacing;
1090
+ use proptest:: prelude:: * ;
1091
+
1092
+ proptest ! {
1093
+ #[ test]
1094
+ fn test_mtu_spacing( mtu_min in 0 ..800u16 , mtu_max in 800 ..2000u16 , step_size in 1 ..800u16 ) {
1095
+ let mtu_spacing = mtu_spacing( mtu_min, mtu_max, step_size) ;
1096
+
1097
+ prop_assert_eq!( mtu_spacing. iter( ) . filter( |mtu| mtu == &&mtu_min) . count( ) , 1 ) ;
1098
+ prop_assert_eq!( mtu_spacing. iter( ) . filter( |mtu| mtu == &&mtu_max) . count( ) , 1 ) ;
1099
+ prop_assert_eq!( mtu_spacing. capacity( ) , mtu_spacing. len( ) ) ;
1100
+ let mut diffs = mtu_spacing. windows( 2 ) . map( |win| win[ 1 ] -win[ 0 ] ) ;
1101
+ prop_assert!( diffs. all( |diff| diff <= step_size) ) ;
1102
+
1103
+ }
1104
+ }
1105
+ }
1106
+
1085
1107
#[ derive( Debug ) ]
1086
1108
enum CloseMsg {
1087
1109
Stop ,
0 commit comments