/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vnet/tcp/tcp.h>

void
newreno_congestion (tcp_connection_t * tc)
{
  tc->ssthresh = clib_max (tcp_flight_size (tc) / 2, 2 * tc->snd_mss);
}

void
newreno_recovered (tcp_connection_t * tc)
{
  tc->cwnd = tc->ssthresh;
}

void
newreno_rcv_ack (tcp_connection_t * tc)
{
  if (tcp_in_slowstart (tc))
    {
      tc->cwnd += clib_min (tc->snd_mss, tc->bytes_acked);
    }
  else
    {
      /* tc->cwnd += clib_max ((tc->snd_mss * tc->snd_mss) / tc->cwnd, 1); */
      tcp_cwnd_accumulate (tc, tc->cwnd, tc->bytes_acked);
    }
}

void
newreno_rcv_cong_ack (tcp_connection_t * tc, tcp_cc_ack_t ack_type)
{
  if (ack_type == TCP_CC_DUPACK)
    {
      if (!tcp_opts_sack_permitted (tc))
	tc->cwnd += tc->snd_mss;
    }
  else if (ack_type == TCP_CC_PARTIALACK)
    {
      /* RFC 6582 Sec. 3.2 */
      if (!tcp_opts_sack_permitted (&tc->rcv_opts))
	{
	  /* Deflate the congestion window by the amount of new data
	   * acknowledged by the Cumulative Acknowledgment field.
	   * If the partial ACK acknowledges at least one SMSS of new data,
	   * then add back SMSS bytes to the congestion window. This
	   * artificially inflates the congestion window in order to reflect
	   * the additional segment that has left the network. This "partial
	   * window deflation" attempts to ensure that, when fast recovery
	   * eventually ends, approximately ssthresh amount of data will be
	   * outstanding in the network.*/
	  tc->cwnd = (tc->cwnd > tc->bytes_acked + tc->snd_mss) ?
	    tc->cwnd - tc->bytes_acked : tc->snd_mss;
	  if (tc->bytes_acked > tc->snd_mss)
	    tc->cwnd += tc->snd_mss;
	}
    }
}

void
newreno_conn_init (tcp_connection_t * tc)
{
  tc->ssthresh = tc->snd_wnd;
  tc->cwnd = tcp_initial_cwnd (tc);
}

const static tcp_cc_algorithm_t tcp_newreno = {
  .name = "newreno",
  .congestion = newreno_congestion,
  .recovered = newreno_recovered,
  .rcv_ack = newreno_rcv_ack,
  .rcv_cong_ack = newreno_rcv_cong_ack,
  .init = newreno_conn_init
};

clib_error_t *
newreno_init (vlib_main_t * vm)
{
  clib_error_t *error = 0;

  tcp_cc_algo_register (TCP_CC_NEWRENO, &tcp_newreno);

  return error;
}

VLIB_INIT_FUNCTION (newreno_init);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
