diff --git a/README.md b/README.md index 6530c10..109c797 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A peer-reviewed [paper on TCP ROCCET](https://opendl.ifip-tc6.org/db/conf/wons/w - Improved min RTT probing - Packet pacing - Code refactor + - Monitoring send and receive rate - release-2026-06-12-v1 - Adds minimum RTT probing diff --git a/tcp_roccet.c b/tcp_roccet.c index 803195f..83ed77c 100644 --- a/tcp_roccet.c +++ b/tcp_roccet.c @@ -230,11 +230,14 @@ static __always_inline void roccet_congestion_event(struct sock *sk, u32 now) ca->epoch_start = 0; ca->roccet_last_event_time_us = now; ca->cnt = 100 * tcp_snd_cwnd(tp); - ca->last_max_cwnd = tcp_snd_cwnd(tp); - tcp_snd_cwnd_set(tp, min(tp->snd_cwnd_clamp, - max((tcp_snd_cwnd(tp) * beta) / - BICTCP_BETA_SCALE, 2U))); - tp->snd_ssthresh = tcp_snd_cwnd(tp); + /*Set W_max only if the current cwnd is larger */ + if (tcp_snd_cwnd(tp) > ca->last_max_cwnd) + ca->last_max_cwnd = tcp_snd_cwnd(tp); + tcp_snd_cwnd_set(tp, min(tp->snd_cwnd_clamp, + max((tcp_snd_cwnd(tp) * beta) / + BICTCP_BETA_SCALE, 2U))); + tp->snd_ssthresh = tcp_snd_cwnd(tp); + } /* Do minimum RTT probing. @@ -497,8 +500,10 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack, u32 now = jiffies_to_usecs(tcp_jiffies32); bool evaluate_srrtt = false; + bool send_more_than_acked = false; u32 roccet_xj; u32 jitter; + u32 send, received; if(ca->state == LAUNCH){ /* LAUNCH: Detect an exit point for tcp slow start @@ -539,10 +544,11 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack, return; }else if(ca->state == ORBITER){ - /* ORBITER: Increase the cwnd by using the CUBIC - * cwnd growth function, if no roccet congestion - * event is detechted. - */ + /* ORBITER: Increase the cwnd by using the CUBIC + * cwnd growth function, if no roccet congestion + * event is detechted. + */ + /* Calculate jitter */ if ((s32)(ca->curr_rtt - ca->last_rtt) < 0) jitter = ca->last_rtt - ca->curr_rtt; @@ -552,12 +558,38 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack, if (ca->next_srrtt_check == 0) ca->next_srrtt_check = now + 5 * ca->curr_rtt; + /* Calculate if more bytes was send than reveived + * in the time interval. + */ + if (tp->snd_nxt < ca->interval_snd_seq_start){ + /* We had a wrap around in seq no counter */ + send = (~0U - ca->interval_snd_seq_start + tp->snd_nxt); + }else{ + send = (tp->snd_nxt - ca->interval_snd_seq_start); + } + if (tp->snd_una < ca->interval_una_seq_start){ + /* We had a wrap around in seq no counter */ + received = (~0U - ca->interval_una_seq_start + tp->snd_una); + }else{ + received = (tp->snd_una - ca->interval_una_seq_start); + } + + /* Here we use a guard space of 1% of the current cwnd. + * We do this to avoid a false positive evaluation due + * to delays caused by jitter or scheduling. + */ + send_more_than_acked = send > received + ((tcp_snd_cwnd(tp) * tp->mss_cache) / 100 ); + /* Check if it's time to evaluate the srRTT */ if ((s32)(ca->next_srrtt_check - now) < 0) { evaluate_srrtt = true; /* reset struct and set next end of period */ ca->next_srrtt_check = now + 5 * ca->curr_rtt; + + /* Reset Rate calculation */ + ca->interval_snd_seq_start = tp->snd_nxt; + ca->interval_una_seq_start = tp->snd_una; } /* Respects the jitter of the connection and add it on top of @@ -571,7 +603,7 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack, /* The srRTT exceeds the upper bound if bufferbloat happens. * Here, we want to reduce the cwnd and drain the buffer. */ - if (ca->curr_srrtt > roccet_xj && evaluate_srrtt) { + if (ca->curr_srrtt > roccet_xj && evaluate_srrtt && send_more_than_acked) { roccet_congestion_event(sk, now); return; } @@ -583,7 +615,7 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack, * at an excessively high value. The cwnd cannot therefore be fully * utilized because it is limited by the connection capacity. */ - if (!tcp_is_cwnd_limited(sk)) + if (!tcp_is_cwnd_limited(sk) || send_more_than_acked) return; bictcp_update(ca, tcp_snd_cwnd(tp), acked); @@ -727,6 +759,12 @@ __bpf_kfunc static void roccet_control(struct sock *sk, u32 ack, int flag, const update_min_rtt(sk); update_srrtt(sk); + /* Set values for send and receive rate */ + if (ca->interval_snd_seq_start == 0){ + ca->interval_snd_seq_start = tp->snd_nxt; + ca->interval_una_seq_start = tp->snd_una; + } + /* Update roccet state */ if(tcp_in_slow_start(tp)){ ca->state = LAUNCH; diff --git a/tcp_roccet.h b/tcp_roccet.h index 1ee4d75..d5784cd 100644 --- a/tcp_roccet.h +++ b/tcp_roccet.h @@ -58,6 +58,8 @@ struct roccettcp { * Used for jitter calculation */ enum roccet_state state; /* State in which roccet currently opperates */ + u32 interval_snd_seq_start; + u32 interval_una_seq_start; }; #endif /* __TCP_ROCCET_H */