Compare commits

...

2 Commits

Author SHA1 Message Date
Lukas Prause a6356c3297 Adds send and receive rate monitoring. 2026-07-16 13:25:58 +02:00
Lukas Prause 97a59b6f20 Removes apt repo. 2026-07-14 09:56:55 +02:00
3 changed files with 52 additions and 25 deletions
+1 -14
View File
@@ -5,26 +5,13 @@ Additionally, it is specially suited for 4G/5G cellular networks.
A peer-reviewed [paper on TCP ROCCET](https://opendl.ifip-tc6.org/db/conf/wons/wons2026/1571217211.pdf) was presented at the WONS 2026 conference. A peer-reviewed [paper on TCP ROCCET](https://opendl.ifip-tc6.org/db/conf/wons/wons2026/1571217211.pdf) was presented at the WONS 2026 conference.
## Install with apt
Add tcp-roccet-dkms to your source lists and install:
```
echo "deb [trusted=yes] https://apt.fury.io/timfuchs/ /" | sudo tee /etc/apt/sources.list.d/tcp-roccet.list
sudo apt update
sudo apt install tcp-roccet-dkms
```
### Loading and using the congestion control
Note: This change is not persistent, the module will not be loaded at boot.
```
sudo modprobe tcp_roccet
sudo sysctl net.ipv4.tcp_congestion_control=roccet
```
### Versions ### Versions
- latest on master branch - latest on master branch
- Improved min RTT probing - Improved min RTT probing
- Packet pacing - Packet pacing
- Code refactor - Code refactor
- Monitoring send and receive rate
- release-2026-06-12-v1 - release-2026-06-12-v1
- Adds minimum RTT probing - Adds minimum RTT probing
+49 -11
View File
@@ -230,11 +230,14 @@ static __always_inline void roccet_congestion_event(struct sock *sk, u32 now)
ca->epoch_start = 0; ca->epoch_start = 0;
ca->roccet_last_event_time_us = now; ca->roccet_last_event_time_us = now;
ca->cnt = 100 * tcp_snd_cwnd(tp); ca->cnt = 100 * tcp_snd_cwnd(tp);
ca->last_max_cwnd = tcp_snd_cwnd(tp); /*Set W_max only if the current cwnd is larger */
tcp_snd_cwnd_set(tp, min(tp->snd_cwnd_clamp, if (tcp_snd_cwnd(tp) > ca->last_max_cwnd)
max((tcp_snd_cwnd(tp) * beta) / ca->last_max_cwnd = tcp_snd_cwnd(tp);
BICTCP_BETA_SCALE, 2U))); tcp_snd_cwnd_set(tp, min(tp->snd_cwnd_clamp,
tp->snd_ssthresh = tcp_snd_cwnd(tp); max((tcp_snd_cwnd(tp) * beta) /
BICTCP_BETA_SCALE, 2U)));
tp->snd_ssthresh = tcp_snd_cwnd(tp);
} }
/* Do minimum RTT probing. /* 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); u32 now = jiffies_to_usecs(tcp_jiffies32);
bool evaluate_srrtt = false; bool evaluate_srrtt = false;
bool send_more_than_acked = false;
u32 roccet_xj; u32 roccet_xj;
u32 jitter; u32 jitter;
u32 send, received;
if(ca->state == LAUNCH){ if(ca->state == LAUNCH){
/* LAUNCH: Detect an exit point for tcp slow start /* LAUNCH: Detect an exit point for tcp slow start
@@ -539,10 +544,11 @@ static void roccettcp_cong_avoid(struct sock *sk, u32 ack,
return; return;
}else if(ca->state == ORBITER){ }else if(ca->state == ORBITER){
/* ORBITER: Increase the cwnd by using the CUBIC /* ORBITER: Increase the cwnd by using the CUBIC
* cwnd growth function, if no roccet congestion * cwnd growth function, if no roccet congestion
* event is detechted. * event is detechted.
*/ */
/* Calculate jitter */ /* Calculate jitter */
if ((s32)(ca->curr_rtt - ca->last_rtt) < 0) if ((s32)(ca->curr_rtt - ca->last_rtt) < 0)
jitter = ca->last_rtt - ca->curr_rtt; 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) if (ca->next_srrtt_check == 0)
ca->next_srrtt_check = now + 5 * ca->curr_rtt; 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 */ /* Check if it's time to evaluate the srRTT */
if ((s32)(ca->next_srrtt_check - now) < 0) { if ((s32)(ca->next_srrtt_check - now) < 0) {
evaluate_srrtt = true; evaluate_srrtt = true;
/* reset struct and set next end of period */ /* reset struct and set next end of period */
ca->next_srrtt_check = now + 5 * ca->curr_rtt; 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 /* 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. /* The srRTT exceeds the upper bound if bufferbloat happens.
* Here, we want to reduce the cwnd and drain the buffer. * 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); roccet_congestion_event(sk, now);
return; 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 * at an excessively high value. The cwnd cannot therefore be fully
* utilized because it is limited by the connection capacity. * 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; return;
bictcp_update(ca, tcp_snd_cwnd(tp), acked); 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_min_rtt(sk);
update_srrtt(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 */ /* Update roccet state */
if(tcp_in_slow_start(tp)){ if(tcp_in_slow_start(tp)){
ca->state = LAUNCH; ca->state = LAUNCH;
+2
View File
@@ -58,6 +58,8 @@ struct roccettcp {
* Used for jitter calculation * Used for jitter calculation
*/ */
enum roccet_state state; /* State in which roccet currently opperates */ enum roccet_state state; /* State in which roccet currently opperates */
u32 interval_snd_seq_start;
u32 interval_una_seq_start;
}; };
#endif /* __TCP_ROCCET_H */ #endif /* __TCP_ROCCET_H */