/* This is a very naive Reno implementation, shown as an example on how to develop a new congestion control algorithm with TCP-Linux. */

#include "ns-linux-c.h"
#include "ns-linux-util.h"

/* opencwnd */
void tcp_naive_reno_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt, u32 in_flight, int flag) 
{
	if (tp->snd_cwnd < tp->snd_ssthresh) {
		tp->snd_cwnd++;
	} else {
		if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
			tp->snd_cwnd++;
			tp->snd_cwnd_cnt = 0;
		} else {
			tp->snd_cwnd_cnt++;
		}
	}
}

/* ssthreshold should be half of the congestion window after a loss */
u32 tcp_naive_reno_ssthresh(struct tcp_sock *tp)
{
        return max(tp->snd_cwnd >> 1U, 2U);
}


/* congestion window should be equal to the slow start threshold (after slow start threshold set to half of cwnd before loss). */
u32 tcp_naive_reno_min_cwnd(struct tcp_sock *tp)
{
        return tp->snd_ssthresh;
}

struct tcp_congestion_ops naive_reno = {
        .name           = "naive_reno",
        .ssthresh       = tcp_naive_reno_ssthresh,
        .cong_avoid     = tcp_naive_reno_cong_avoid,
        .min_cwnd       = tcp_naive_reno_min_cwnd
};

