diff options
Diffstat (limited to 'src/vnet/tcp')
-rwxr-xr-x | src/vnet/tcp/tcp_input.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index de79e3e19ab..e4bd156391f 100755 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -1509,6 +1509,24 @@ tcp_cc_handle_event (tcp_connection_t * tc, tcp_rate_sample_t * rs, tcp_cc_rcv_cong_ack (tc, TCP_CC_PARTIALACK, rs); } +static void +tcp_handle_old_ack (tcp_connection_t * tc, vlib_buffer_t * b, + tcp_rate_sample_t * rs) +{ + if (!tcp_in_cong_recovery (tc)) + return; + + if (tcp_opts_sack_permitted (&tc->rcv_opts)) + tcp_rcv_sacks (tc, vnet_buffer (b)->tcp.ack_number); + + tc->bytes_acked = 0; + + if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE) + tcp_bt_sample_delivery_rate (tc, rs); + + tcp_cc_handle_event (tc, rs, 1); +} + /** * Check if duplicate ack as per RFC5681 Sec. 2 */ @@ -1574,8 +1592,12 @@ tcp_rcv_ack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc, vlib_buffer_t * b, tc->errors.below_ack_wnd += 1; *error = TCP_ERROR_ACK_OLD; TCP_EVT (TCP_EVT_ACK_RCV_ERR, tc, 1, vnet_buffer (b)->tcp.ack_number); - if (tcp_in_fastrecovery (tc) && tc->rcv_dupacks == TCP_DUPACK_THRESHOLD) - tcp_cc_handle_event (tc, 0, 1); + + if (seq_lt (vnet_buffer (b)->tcp.ack_number, tc->snd_una - tc->rcv_wnd)) + return -1; + + tcp_handle_old_ack (tc, b, &rs); + /* Don't drop yet */ return 0; } |