@@ -598,6 +598,10 @@ pub struct Socket<'a> {
598598 /// The congestion control algorithm.
599599 congestion_controller : congestion:: AnyController ,
600600
601+ /// Pacing: next time a packet can be sent (for rate limiting).
602+ /// If None, pacing is not active.
603+ pacing_next_send_at : Option < Instant > ,
604+
601605 /// tsval generator - if some, tcp timestamp is enabled
602606 tsval_generator : Option < TcpTimestampGenerator > ,
603607
@@ -670,6 +674,7 @@ impl<'a> Socket<'a> {
670674 tsval_generator : None ,
671675 last_remote_tsval : 0 ,
672676 congestion_controller : congestion:: AnyController :: new ( ) ,
677+ pacing_next_send_at : None ,
673678
674679 #[ cfg( feature = "async" ) ]
675680 rx_waker : WakerRegistration :: new ( ) ,
@@ -2479,6 +2484,15 @@ impl<'a> Socket<'a> {
24792484 return Ok ( ( ) ) ;
24802485 }
24812486
2487+ // Check if pacing delays transmission
2488+ if let Some ( next_send_at) = self . pacing_next_send_at {
2489+ if cx. now ( ) < next_send_at && self . seq_to_transmit ( cx) {
2490+ // Pacing prevents us from sending data right now
2491+ tcp_trace ! ( "pacing delayed until {:?}" , next_send_at) ;
2492+ return Ok ( ( ) ) ;
2493+ }
2494+ }
2495+
24822496 // Decide whether we're sending a packet.
24832497 if self . seq_to_transmit ( cx) {
24842498 // If we have data to transmit and it fits into partner's window, do it.
@@ -2720,6 +2734,26 @@ impl<'a> Socket<'a> {
27202734 self . congestion_controller
27212735 . inner_mut ( )
27222736 . post_transmit ( cx. now ( ) , repr. segment_len ( ) ) ;
2737+
2738+ // Update pacing: calculate when the next packet can be sent
2739+ let pacing_rate = self . congestion_controller . inner_mut ( ) . pacing_rate ( ) ;
2740+ if pacing_rate > 0 {
2741+ // Calculate delay: (packet_size_bytes * 1_000_000) / pacing_rate_bytes_per_sec
2742+ // This gives us microseconds until the next packet can be sent
2743+ let packet_size = repr. segment_len ( ) as u64 ;
2744+ let delay_micros = ( packet_size * 1_000_000 ) / pacing_rate;
2745+ let delay = crate :: time:: Duration :: from_micros ( delay_micros) ;
2746+ self . pacing_next_send_at = Some ( cx. now ( ) + delay) ;
2747+ tcp_trace ! (
2748+ "pacing: sent {} bytes at rate {} bytes/s, next send at {:?}" ,
2749+ packet_size,
2750+ pacing_rate,
2751+ self . pacing_next_send_at
2752+ ) ;
2753+ } else {
2754+ // No pacing
2755+ self . pacing_next_send_at = None ;
2756+ }
27232757 }
27242758
27252759 if repr. segment_len ( ) > 0 && !self . timer . is_retransmit ( ) {
@@ -2757,7 +2791,11 @@ impl<'a> Socket<'a> {
27572791 PollAt :: Now
27582792 } else if self . seq_to_transmit ( cx) {
27592793 // We have a data or flag packet to transmit.
2760- PollAt :: Now
2794+ // Check if pacing delays it.
2795+ match self . pacing_next_send_at {
2796+ Some ( next_send_at) if cx. now ( ) < next_send_at => PollAt :: Time ( next_send_at) ,
2797+ _ => PollAt :: Now ,
2798+ }
27612799 } else if self . window_to_update ( ) {
27622800 // The receive window has been raised significantly.
27632801 PollAt :: Now
0 commit comments