/*
 * Copyright (c) 2017 SUSE LLC.
 * 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.
 */
#ifndef included_vnet_sctp_h
#define included_vnet_sctp_h

#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/sctp/sctp_timer.h>
#include <vnet/sctp/sctp_packet.h>
#include <vnet/session/transport.h>
#include <vnet/session/session.h>

/* SCTP timers */
#define foreach_sctp_timer              	\
  _(T1_INIT, "T1_INIT")           			\
  _(T1_COOKIE, "T1_COOKIE")        			\
  _(T2_SHUTDOWN, "T2_SHUTDOWN")         	\
  _(T3_RXTX, "T3_RXTX")   					\
  _(T4_HEARTBEAT, "T4_HB")					\
  _(T5_SHUTDOWN_GUARD, "T5_SHUTDOWN_GUARD")

typedef enum _sctp_timers
{
#define _(sym, str) SCTP_TIMER_##sym,
  foreach_sctp_timer
#undef _
  SCTP_N_TIMERS
} sctp_timers_e;

#define SCTP_TIMER_HANDLE_INVALID ((u32) ~0)

always_inline char *
sctp_timer_to_string (u8 timer_id)
{
  switch (timer_id)
    {
    case SCTP_TIMER_T1_INIT:
      return "SCTP_TIMER_T1_INIT";
    case SCTP_TIMER_T1_COOKIE:
      return "SCTP_TIMER_T1_COOKIE";
    case SCTP_TIMER_T2_SHUTDOWN:
      return "SCTP_TIMER_T2_SHUTDOWN";
    case SCTP_TIMER_T3_RXTX:
      return "SCTP_TIMER_T3_RXTX";
    case SCTP_TIMER_T4_HEARTBEAT:
      return "SCTP_TIMER_T4_HEARTBEAT";
    case SCTP_TIMER_T5_SHUTDOWN_GUARD:
      return "SCTP_TIMER_T5_SHUTDOWN_GUARD";
    }
  return NULL;
}

typedef enum _sctp_error
{
#define sctp_error(n,s) SCTP_ERROR_##n,
#include <vnet/sctp/sctp_error.def>
#undef sctp_error
  SCTP_N_ERROR,
} sctp_error_t;

#define NO_FLAG 0

#define IS_T_BIT_SET(var) ((var) & (1))
#define IS_E_BIT_SET(var) ((var) & (1))
#define IS_B_BIT_SET(var) ((var) & (1<<1))
#define IS_U_BIT_SET(var) ((var) & (1<<2))

#define MAX_SCTP_CONNECTIONS 8
#define MAIN_SCTP_SUB_CONN_IDX 0

#if (VLIB_BUFFER_TRACE_TRAJECTORY)
#define sctp_trajectory_add_start(b, start)			\
{								\
    (*vlib_buffer_trace_trajectory_cb) (b, start);		\
}
#else
#define sctp_trajectory_add_start(b, start)
#endif

enum _sctp_subconn_state
{
  SCTP_SUBCONN_STATE_DOWN = 0,
  SCTP_SUBCONN_STATE_UP,
  SCTP_SUBCONN_STATE_ALLOW_HB
};

#define SCTP_INITIAL_SSHTRESH 65535
typedef struct _sctp_sub_connection
{
  transport_connection_t connection;	      /**< Common transport data. First! */

  u8 subconn_idx; /**< This indicates the position of this sub-connection in the super-set container of connections pool */
  u32 error_count; /**< The current error count for this destination. */
  u32 error_threshold; /**< Current error threshold for this destination,
				i.e. what value marks the destination down if error count reaches this value. */
  u32 cwnd; /**< Congestion control window (cwnd, in bytes), which is adjusted by
      the sender based on observed network conditions. */
  u32 ssthresh;	/**< Slow-start threshold (in bytes), which is used by the
      sender to distinguish slow-start and congestion avoidance phases. */

  u32 rtt_ts;	/**< USED to hold the timestamp of when the packet has been sent */

  u32 RTO; /**< The current retransmission timeout value. */
  u32 SRTT; /**< The current smoothed round-trip time. */
  f32 RTTVAR; /**< The current RTT variation. */

  u32 partially_acked_bytes; /**< The tracking method for increase of cwnd when in
  	  	  	  	  congestion avoidance mode (see Section 7.2.2).*/

  u8 state; /**< The current state of this destination, i.e., DOWN, UP, ALLOW-HB, NO-HEARTBEAT, etc. */

  u16 PMTU; /**< The current known path MTU. */

  u32 timers[SCTP_N_TIMERS]; /**< A timer used by each destination. */

  u8 RTO_pending; /**< A flag used to track if one of the DATA chunks sent to
  	  	  	  	  this address is currently being used to compute an RTT.
  	  	  	  	  If this flag is 0, the next DATA chunk sent to this destination
  	  	  	  	  should be used to compute an RTT and this flag should be set.
  	  	  	  	  Every time the RTT calculation completes (i.e., the DATA chunk is SACK'd),
  	  	  	  	  clear this flag. */

  u32 last_seen; /**< The time to which this destination was last sent a packet to.
  	  	  	  	  This can be used to determine if a HEARTBEAT is needed. */

  u32 last_data_ts; /**< Used to hold the timestamp value of last time we sent a DATA chunk */

  u8 unacknowledged_hb;	/**< Used to track how many unacknowledged heartbeats we had;
  	  	  	  	  If more than SCTP_PATH_MAX_RETRANS then connection is considered unreachable. */

  u8 is_retransmitting;	/**< A flag (0 = no, 1 = yes) indicating whether the connection is retransmitting a previous packet */

  u8 enqueue_state; /**< if set to 1 indicates that DATA is still being handled hence cannot shutdown this connection yet */

} sctp_sub_connection_t;

typedef struct
{
  u32 a_rwnd; /**< Maximum segment size advertised */

} sctp_options_t;

/* Useful macros to deal with the out_of_order_map (array of bit) */
#define SET_BIT(A,k)     ( A[(k/32)] |= (1 << (k%32)) )
#define CLEAR_BIT(A,k)   ( A[(k/32)] &= ~(1 << (k%32)) )
#define TEST_BIT(A,k)    ( A[(k/32)] & (1 << (k%32)) )

always_inline void
_bytes_swap (void *pv, size_t n)
{
  char *p = pv;
  size_t lo, hi;
  for (lo = 0, hi = n - 1; hi > lo; lo++, hi--)
    {
      char tmp = p[lo];
      p[lo] = p[hi];
      p[hi] = tmp;
    }
}

#define ENDIANESS_SWAP(x) _bytes_swap(&x, sizeof(x));

#define MAX_INFLIGHT_PACKETS	128
#define MAX_ENQUEABLE_SACKS 2

/* This parameter indicates to the receiver how much increment in
 * milliseconds the sender wishes the receiver to add to its default
 * cookie life-span.
 */
#define SUGGESTED_COOKIE_LIFE_SPAN_INCREMENT 1000

typedef struct _sctp_connection
{
  sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS];	/**< Common transport data. First! */

  u8 state;			/**< SCTP state as per sctp_state_t */
  u16 flags;		/**< Chunk flag (see sctp_chunks_common_hdr_t) */

  u32 local_tag;	/**< INIT_TAG generated locally */
  u32 remote_tag;	/**< INIT_TAG generated by the remote peer */

  u32 local_initial_tsn; /**< Initial TSN generated locally */
  u32 remote_initial_tsn; /**< Initial TSN generated by the remote-peer */

  u32 peer_cookie_life_span_increment;

  u32 overall_err_count; /**< The overall association error count. */
  u32 overall_err_treshold; /**< The threshold for this association that if the Overall Error Count
  	  	  	  	  reaches will cause this association to be torn down. */

  u32 peer_rwnd; /**< Current calculated value of the peer's rwnd. */

  u32 next_tsn;	/**< The next TSN number to be assigned to a new DATA chunk.
                 This is sent in the INIT or INIT ACK chunk to the peer
                 and incremented each time a DATA chunk is assigned a
                 TSN (normally just prior to transmit or during
                 fragmentation). */

  u32 last_unacked_tsn;	/** < Last TSN number still unacked */
  u32 next_tsn_expected; /**< The next TSN number expected to be received. */

  u32 last_rcvd_tsn; /**< This is the last TSN received in sequence. This value
     	 	 	 is set initially by taking the peer's initial TSN,
                 received in the INIT or INIT ACK chunk, and
                 subtracting one from it. */

  u32 out_of_order_map[MAX_INFLIGHT_PACKETS]; /**< An array of bits or bytes indicating which out-of-order
				TSNs have been received (relative to the Last Rcvd TSN).
				If no gaps exist, i.e., no out-of-order packets have been received,
				this array will be set to all zero. */

  u8 ack_state;	/**< This flag indicates if the next received packet is set to be responded to with a SACK.
  	  	  	  	This is initialized to 0. When a packet is received it is incremented.
  	  	  	  	If this value reaches 2 or more, a SACK is sent and the value is reset to 0.
  	  	  	  	Note: This is used only when no DATA chunks are received out-of-order.
  	  	  	  	When DATA chunks are out-of-order, SACKs are not delayed (see Section 6). */

  u8 smallest_PMTU_idx;	/** The index of the sub-connection with the smallest PMTU discovered across all peer's transport addresses. */

  u8 overall_sending_status; /**< 0 indicates first fragment of a user message
  	  	  	  	  	  	  	  	  1 indicates normal stream
  	  	  	  	  	  	  	  	  2 indicates last fragment of a user message */

  sctp_options_t snd_opts;

  u8 forming_association_changed; /**< This is a flag indicating whether the original association has been modified during
  	  	  	  	  the life-span of the association itself. For instance, a new sub-connection might have been added. */

} sctp_connection_t;

typedef void (sctp_timer_expiration_handler) (u32 conn_index, u32 timer_id);

sctp_connection_t *sctp_connection_new (u8 thread_index);

u8
sctp_sub_connection_add_ip4 (vlib_main_t * vm,
			     ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr);

u8
sctp_sub_connection_add_ip6 (vlib_main_t * vm,
			     ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr);

u8
sctp_sub_connection_del_ip4 (ip4_address_t * lcl_addr,
			     ip4_address_t * rmt_addr);

u8
sctp_sub_connection_del_ip6 (ip6_address_t * lcl_addr,
			     ip6_address_t * rmt_addr);

void sctp_connection_close (sctp_connection_t * sctp_conn);
void sctp_connection_cleanup (sctp_connection_t * sctp_conn);
void sctp_connection_del (sctp_connection_t * sctp_conn);

u32 sctp_push_header (transport_connection_t * tconn, vlib_buffer_t * b);
void sctp_send_init (sctp_connection_t * sctp_conn);
void sctp_send_shutdown (sctp_connection_t * sctp_conn);
void sctp_send_shutdown_ack (sctp_connection_t * sctp_conn, u8 idx,
			     vlib_buffer_t * b);
void sctp_send_shutdown_complete (sctp_connection_t * sctp_conn, u8 idx,
				  vlib_buffer_t * b0);
void sctp_send_heartbeat (sctp_connection_t * sctp_conn);
void sctp_flush_frame_to_output (vlib_main_t * vm, u8 thread_index,
				 u8 is_ip4);
void sctp_flush_frames_to_output (u8 thread_index);
void sctp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add);

format_function_t format_sctp_state;

u8 *format_sctp_connection_id (u8 * s, va_list * args);
u8 *format_sctp_connection (u8 * s, va_list * args);
u8 *format_sctp_scoreboard (u8 * s, va_list * args);
u8 *format_sctp_header (u8 * s, va_list * args);
u8 *format_sctp_tx_trace (u8 * s, va_list * args);

clib_error_t *sctp_init (vlib_main_t * vm);
void sctp_connection_timers_init (sctp_connection_t * sctp_conn);
void sctp_connection_timers_reset (sctp_connection_t * sctp_conn);
void sctp_init_snd_vars (sctp_connection_t * sctp_conn);
void sctp_init_mss (sctp_connection_t * sctp_conn);

void sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				 vlib_buffer_t * b, ip4_address_t * ip4_addr,
				 ip6_address_t * ip6_addr);
void
sctp_prepare_initack_chunk_for_collision (sctp_connection_t * sctp_conn,
					  u8 idx, vlib_buffer_t * b,
					  ip4_address_t * ip4_addr,
					  ip6_address_t * ip6_addr);
void sctp_prepare_abort_for_collision (sctp_connection_t * sctp_conn, u8 idx,
				       vlib_buffer_t * b,
				       ip4_address_t * ip4_addr,
				       ip6_address_t * ip6_addr);
void
sctp_prepare_operation_error (sctp_connection_t * sctp_conn, u8 idx,
			      vlib_buffer_t * b, u8 err_cause);
void sctp_prepare_cookie_echo_chunk (sctp_connection_t * sctp_conn, u8 idx,
				     vlib_buffer_t * b,
				     sctp_state_cookie_param_t * sc);
void sctp_prepare_cookie_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				    vlib_buffer_t * b);
void sctp_prepare_sack_chunk (sctp_connection_t * sctp_conn, u8 idx,
			      vlib_buffer_t * b);
void sctp_prepare_heartbeat_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
				       vlib_buffer_t * b);

u16 sctp_check_outstanding_data_chunks (sctp_connection_t * sctp_conn);

void sctp_api_reference (void);

#define IP_PROTOCOL_SCTP	132

/** SSCTP FSM state definitions as per RFC4960. */
#define foreach_sctp_fsm_state                \
  _(CLOSED, "CLOSED")                         \
  _(COOKIE_WAIT, "COOKIE_WAIT")               \
  _(COOKIE_ECHOED, "COOKIE_ECHOED")           \
  _(ESTABLISHED, "ESTABLISHED")               \
  _(SHUTDOWN_PENDING, "SHUTDOWN_PENDING")     \
  _(SHUTDOWN_SENT, "SHUTDOWN_SENT")           \
  _(SHUTDOWN_RECEIVED, "SHUTDOWN_RECEIVED")   \
  _(SHUTDOWN_ACK_SENT, "SHUTDOWN_ACK_SENT")

typedef enum _sctp_state
{
#define _(sym, str) SCTP_STATE_##sym,
  foreach_sctp_fsm_state
#undef _
  SCTP_N_STATES
} sctp_state_t;

always_inline char *
sctp_state_to_string (u8 state)
{
  switch (state)
    {
    case SCTP_STATE_CLOSED:
      return "SCTP_STATE_CLOSED";
    case SCTP_STATE_COOKIE_WAIT:
      return "SCTP_STATE_COOKIE_WAIT";
    case SCTP_STATE_COOKIE_ECHOED:
      return "SCTP_STATE_COOKIE_ECHOED";
    case SCTP_STATE_ESTABLISHED:
      return "SCTP_STATE_ESTABLISHED";
    case SCTP_STATE_SHUTDOWN_PENDING:
      return "SCTP_STATE_SHUTDOWN_PENDING";
    case SCTP_STATE_SHUTDOWN_SENT:
      return "SCTP_STATE_SHUTDOWN_SENT";
    case SCTP_STATE_SHUTDOWN_RECEIVED:
      return "SCTP_STATE_SHUTDOWN_RECEIVED";
    case SCTP_STATE_SHUTDOWN_ACK_SENT:
      return "SCTP_STATE_SHUTDOWN_ACK_SENT";
    }
  return NULL;
}

always_inline char *
sctp_chunk_to_string (u8 type)
{
  switch (type)
    {
    case DATA:
      return "DATA";
    case INIT:
      return "INIT";
    case INIT_ACK:
      return "INIT_ACK";
    case SACK:
      return "SACK";
    case HEARTBEAT:
      return "HEARTBEAT";
    case HEARTBEAT_ACK:
      return "HEARTBEAT_ACK";
    case ABORT:
      return "ABORT";
    case SHUTDOWN:
      return "SHUTDOWN";
    case SHUTDOWN_ACK:
      return "SHUTDOWN_ACK";
    case OPERATION_ERROR:
      return "OPERATION_ERROR";
    case COOKIE_ECHO:
      return "COOKIE_ECHO";
    case COOKIE_ACK:
      return "COOKIE_ACK";
    case ECNE:
      return "ECNE";
    case CWR:
      return "CWR";
    case SHUTDOWN_COMPLETE:
      return "SHUTDOWN_COMPLETE";
    }
  return NULL;
}

always_inline char *
sctp_optparam_type_to_string (u8 type)
{
  switch (type)
    {
    case SCTP_IPV4_ADDRESS_TYPE:
      return "SCTP_IPV4_ADDRESS_TYPE";
    case SCTP_IPV6_ADDRESS_TYPE:
      return "SCTP_IPV6_ADDRESS_TYPE";
    case SCTP_STATE_COOKIE_TYPE:
      return "SCTP_STATE_COOKIE_TYPE";
    case SCTP_UNRECOGNIZED_TYPE:
      return "SCTP_UNRECOGNIZED_TYPE";
    case SCTP_COOKIE_PRESERVATIVE_TYPE:
      return "SCTP_COOKIE_PRESERVATIVE_TYPE";
    case SCTP_HOSTNAME_ADDRESS_TYPE:
      return "SCTP_HOSTNAME_ADDRESS_TYPE";
    case SCTP_SUPPORTED_ADDRESS_TYPES:
      return "SCTP_SUPPORTED_ADDRESS_TYPES";
    }
  return NULL;
}

#define SCTP_TICK 0.001			/**< SCTP tick period (s) */
#define SHZ (u32) (1/SCTP_TICK)		/**< SCTP tick frequency */
#define SCTP_TSTAMP_RESOLUTION SCTP_TICK	/**< Time stamp resolution */

/* As per RFC4960, page 83 */
#define SCTP_RTO_INIT 3 * SHZ	/* 3 seconds */
#define SCTP_RTO_MIN 1 * SHZ	/* 1 second */
#define SCTP_RTO_MAX 60 * SHZ	/* 60 seconds */
#define SCTP_RTO_BURST 4
#define SCTP_RTO_ALPHA 1/8
#define SCTP_RTO_BETA 1/4
#define SCTP_VALID_COOKIE_LIFE 60 * SHZ	/* 60 seconds */
#define SCTP_ASSOCIATION_MAX_RETRANS 10	// the overall connection
#define SCTP_PATH_MAX_RETRANS 5	// number of attempts per destination address
#define SCTP_MAX_INIT_RETRANS 8	// number of attempts
#define SCTP_HB_INTERVAL 30 * SHZ
#define SCTP_HB_MAX_BURST 1

#define SCTP_DATA_IDLE_INTERVAL 15 * SHZ	/* 15 seconds; the time-interval after which the connetion is considered IDLE */

#define SCTP_TO_TIMER_TICK       SCTP_TICK*10	/* Period for converting from SCTP_TICK */

typedef struct _sctp_lookup_dispatch
{
  u8 next, error;
} sctp_lookup_dispatch_t;

typedef struct _sctp_main
{
  /* Per-worker thread SCTP connection pools */
  sctp_connection_t **connections;

  /* Pool of listeners. */
  sctp_connection_t *listener_pool;

	  /** Dispatch table by state and flags */
  sctp_lookup_dispatch_t dispatch_table[SCTP_N_STATES][64];

  u8 log2_tstamp_clocks_per_tick;
  f64 tstamp_ticks_per_clock;
  u32 *time_now;

	  /** per-worker tx buffer free lists */
  u32 **tx_buffers;
	  /** per-worker tx frames to SCTP 4/6 output nodes */
  vlib_frame_t **tx_frames[2];
	  /** per-worker tx frames to ip 4/6 lookup nodes */
  vlib_frame_t **ip_lookup_tx_frames[2];

  /* Per worker-thread timer wheel for connections timers */
  tw_timer_wheel_16t_2w_512sl_t *timer_wheels;

  /* Pool of half-open connections on which we've sent a SYN */
  sctp_connection_t *half_open_connections;
  clib_spinlock_t half_open_lock;

  /* TODO: Congestion control algorithms registered */
  /* sctp_cc_algorithm_t *cc_algos; */

  /* Flag that indicates if stack is on or off */
  u8 is_enabled;

	  /** Number of preallocated connections */
  u32 preallocated_connections;

	  /** Transport table (preallocation) size parameters */
  u32 local_endpoints_table_memory;
  u32 local_endpoints_table_buckets;

	  /** Vectors of src addresses. Optional unless one needs > 63K active-opens */
  ip4_address_t *ip4_src_addresses;
  u32 last_v4_address_rotor;
  u32 last_v6_address_rotor;
  ip6_address_t *ip6_src_addresses;

	  /** vlib buffer size */
  u32 bytes_per_buffer;

  u8 punt_unknown4;
  u8 punt_unknown6;

} sctp_main_t;

extern sctp_main_t sctp_main;
extern vlib_node_registration_t sctp4_input_node;
extern vlib_node_registration_t sctp6_input_node;
extern vlib_node_registration_t sctp4_output_node;
extern vlib_node_registration_t sctp6_output_node;

always_inline sctp_main_t *
vnet_get_sctp_main ()
{
  return &sctp_main;
}

always_inline sctp_header_t *
sctp_buffer_hdr (vlib_buffer_t * b)
{
  ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
  return (sctp_header_t *) (b->data + b->current_data
			    + vnet_buffer (b)->sctp.hdr_offset);
}

clib_error_t *vnet_sctp_enable_disable (vlib_main_t * vm, u8 is_en);

always_inline sctp_connection_t *
sctp_half_open_connection_get (u32 conn_index)
{
  sctp_connection_t *tc = 0;
  clib_spinlock_lock_if_init (&sctp_main.half_open_lock);
  if (!pool_is_free_index (sctp_main.half_open_connections, conn_index))
    tc = pool_elt_at_index (sctp_main.half_open_connections, conn_index);
  tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].subconn_idx = MAIN_SCTP_SUB_CONN_IDX;
  clib_spinlock_unlock_if_init (&sctp_main.half_open_lock);
  return tc;
}

/**
 * Cleanup half-open connection
 *
 */
always_inline void
sctp_half_open_connection_del (sctp_connection_t * tc)
{
  sctp_main_t *sctp_main = vnet_get_sctp_main ();
  clib_spinlock_lock_if_init (&sctp_main->half_open_lock);
  pool_put_index (sctp_main->half_open_connections,
		  tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_c_index);
  if (CLIB_DEBUG)
    memset (tc, 0xFA, sizeof (*tc));
  clib_spinlock_unlock_if_init (&sctp_main->half_open_lock);
}

always_inline u32
sctp_set_time_now (u32 thread_index)
{
  sctp_main.time_now[thread_index] = clib_cpu_time_now ()
    * sctp_main.tstamp_ticks_per_clock;
  return sctp_main.time_now[thread_index];
}

always_inline void
sctp_timer_set (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
		u32 interval)
{
  ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
	  vlib_get_thread_index ());
  ASSERT (tc->sub_conn[conn_idx].timers[timer_id] ==
	  SCTP_TIMER_HANDLE_INVALID);

  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];
  sub->timers[timer_id] =
    tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				 sub->c_c_index, timer_id, interval);
}

always_inline void
sctp_timer_reset (sctp_connection_t * tc, u8 conn_idx, u8 timer_id)
{
  ASSERT (tc->sub_conn[conn_idx].c_thread_index == vlib_get_thread_index ());
  if (tc->sub_conn[conn_idx].timers[timer_id] == SCTP_TIMER_HANDLE_INVALID)
    return;

  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];

  tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
			      sub->timers[timer_id]);
  sub->timers[timer_id] = SCTP_TIMER_HANDLE_INVALID;
}

/**
 * Try to cleanup half-open connection
 *
 * If called from a thread that doesn't own tc, the call won't have any
 * effect.
 *
 * @param tc - connection to be cleaned up
 * @return non-zero if cleanup failed.
 */
always_inline int
sctp_half_open_connection_cleanup (sctp_connection_t * tc)
{
  /* Make sure this is the owning thread */
  if (tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_thread_index !=
      vlib_get_thread_index ())
    return 1;
  sctp_timer_reset (tc, MAIN_SCTP_SUB_CONN_IDX, SCTP_TIMER_T1_INIT);
  sctp_half_open_connection_del (tc);
  return 0;
}

always_inline u32
sctp_header_bytes ()
{
  return sizeof (sctp_header_t);
}

always_inline sctp_connection_t *
sctp_get_connection_from_transport (transport_connection_t * tconn)
{
  ASSERT (tconn != NULL);

  sctp_sub_connection_t *sub = (sctp_sub_connection_t *) tconn;
#if SCTP_ADV_DEBUG
  if (sub == NULL)
    SCTP_ADV_DBG ("sub == NULL");
  if (sub->parent == NULL)
    SCTP_ADV_DBG ("sub->parent == NULL");
#endif
  if (sub->subconn_idx > 0)
    return (sctp_connection_t *) sub -
      (sizeof (sctp_sub_connection_t) * (sub->subconn_idx - 1));

  return (sctp_connection_t *) sub;
}

always_inline u32
sctp_time_now (void)
{
  return sctp_main.time_now[vlib_get_thread_index ()];
}

#define ABS(x) ((x) > 0) ? (x) : -(x);

always_inline void
sctp_calculate_rto (sctp_connection_t * sctp_conn, u8 conn_idx)
{
  /* See RFC4960, 6.3.1.  RTO Calculation */
  u32 RTO = 0;
  f32 RTTVAR = 0;
  u32 now = sctp_time_now ();
  u32 prev_ts = sctp_conn->sub_conn[conn_idx].rtt_ts;
  u32 R = prev_ts - now;

  if (sctp_conn->sub_conn[conn_idx].RTO == 0)	// C1: Let's initialize our RTO
    {
      sctp_conn->sub_conn[conn_idx].RTO = SCTP_RTO_MIN;
      return;
    }

  if (sctp_conn->sub_conn[conn_idx].RTO == SCTP_RTO_MIN && sctp_conn->sub_conn[conn_idx].SRTT == 0)	// C2: First RTT calculation
    {
      sctp_conn->sub_conn[conn_idx].SRTT = R;
      RTTVAR = R / 2;

      if (RTTVAR == 0)
	RTTVAR = 100e-3;	/* 100 ms */

      sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;
    }
  else				// C3: RTT already exists; let's recalculate
    {
      RTTVAR = (1 - SCTP_RTO_BETA) * sctp_conn->sub_conn[conn_idx].RTTVAR +
	SCTP_RTO_BETA * ABS (sctp_conn->sub_conn[conn_idx].SRTT - R);

      if (RTTVAR == 0)
	RTTVAR = 100e-3;	/* 100 ms */

      sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;

      sctp_conn->sub_conn[conn_idx].SRTT =
	(1 - SCTP_RTO_ALPHA) * sctp_conn->sub_conn[conn_idx].SRTT +
	SCTP_RTO_ALPHA * R;
    }

  RTO =
    sctp_conn->sub_conn[conn_idx].SRTT +
    4 * sctp_conn->sub_conn[conn_idx].RTTVAR;
  if (RTO < SCTP_RTO_MIN)	// C6
    RTO = SCTP_RTO_MIN;

  if (RTO > SCTP_RTO_MAX)	// C7
    RTO = SCTP_RTO_MAX;

  sctp_conn->sub_conn[conn_idx].RTO = RTO;
}

always_inline void
sctp_timer_update (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
		   u32 interval)
{
  ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
	  vlib_get_thread_index ());
  sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];

  if (tc->sub_conn[conn_idx].timers[timer_id] != SCTP_TIMER_HANDLE_INVALID)
    tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				sub->timers[timer_id]);

  tc->sub_conn[conn_idx].timers[timer_id] =
    tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
				 sub->c_c_index, timer_id, interval);
}

always_inline sctp_connection_t *
sctp_listener_get (u32 tli)
{
  return pool_elt_at_index (sctp_main.listener_pool, tli);
}

#endif

always_inline sctp_connection_t *
sctp_connection_get (u32 conn_index, u32 thread_index)
{
  if (PREDICT_FALSE
      (pool_is_free_index (sctp_main.connections[thread_index], conn_index)))
    return 0;
  return pool_elt_at_index (sctp_main.connections[thread_index], conn_index);
}

#define SELECT_MAX_RETRIES 8

always_inline u8
sctp_data_subconn_select (sctp_connection_t * sctp_conn)
{
  u32 sub = MAIN_SCTP_SUB_CONN_IDX;
  u8 i, cwnd = sctp_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].cwnd;
  for (i = 1; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN)
	continue;

      if (sctp_conn->sub_conn[i].cwnd > cwnd)
	{
	  sub = i;
	  cwnd = sctp_conn->sub_conn[i].cwnd;
	}
    }
  return sub;
}

always_inline u8
sctp_sub_conn_id_via_ip6h (sctp_connection_t * sctp_conn, ip6_header_t * ip6h)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].connection.lcl_ip.ip6.as_u64[0] ==
	  ip6h->dst_address.as_u64[0] &&
	  sctp_conn->sub_conn[i].connection.lcl_ip.ip6.as_u64[1] ==
	  ip6h->dst_address.as_u64[1] &&
	  sctp_conn->sub_conn[i].connection.rmt_ip.ip6.as_u64[0] ==
	  ip6h->src_address.as_u64[0] &&
	  sctp_conn->sub_conn[i].connection.rmt_ip.ip6.as_u64[1] ==
	  ip6h->src_address.as_u64[1])
	return i;
    }
  clib_warning ("Did not find a sub-connection; defaulting to %u",
		MAIN_SCTP_SUB_CONN_IDX);
  return MAIN_SCTP_SUB_CONN_IDX;
}

always_inline u8
sctp_sub_conn_id_via_ip4h (sctp_connection_t * sctp_conn, ip4_header_t * ip4h)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].connection.lcl_ip.ip4.as_u32 ==
	  ip4h->dst_address.as_u32
	  && sctp_conn->sub_conn[i].connection.rmt_ip.ip4.as_u32 ==
	  ip4h->src_address.as_u32)
	return i;
    }
  clib_warning ("Did not find a sub-connection; defaulting to %u",
		MAIN_SCTP_SUB_CONN_IDX);
  return MAIN_SCTP_SUB_CONN_IDX;
}

/**
 * Push SCTP header to buffer
 *
 * @param vm - vlib_main
 * @param b - buffer to write the header to
 * @param sp_net - source port net order
 * @param dp_net - destination port net order
 * @param sctp_hdr_opts_len - header and options length in bytes
 *
 * @return - pointer to start of SCTP header
 */
always_inline void *
vlib_buffer_push_sctp_net_order (vlib_buffer_t * b, u16 sp, u16 dp,
				 u8 sctp_hdr_opts_len)
{
  sctp_full_hdr_t *full_hdr;

  full_hdr = vlib_buffer_push_uninit (b, sctp_hdr_opts_len);

  full_hdr->hdr.src_port = sp;
  full_hdr->hdr.dst_port = dp;
  full_hdr->hdr.checksum = 0;
  return full_hdr;
}

/**
 * Push SCTP header to buffer
 *
 * @param b - buffer to write the header to
 * @param sp_net - source port net order
 * @param dp_net - destination port net order
 * @param sctp_hdr_opts_len - header and options length in bytes
 *
 * @return - pointer to start of SCTP header
 */
always_inline void *
vlib_buffer_push_sctp (vlib_buffer_t * b, u16 sp_net, u16 dp_net,
		       u8 sctp_hdr_opts_len)
{
  return vlib_buffer_push_sctp_net_order (b, sp_net, dp_net,
					  sctp_hdr_opts_len);
}

always_inline u8
sctp_next_avail_subconn (sctp_connection_t * sctp_conn)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN)
	return i;
    }
  return MAX_SCTP_CONNECTIONS;
}

always_inline void
update_smallest_pmtu_idx (sctp_connection_t * sctp_conn)
{
  u8 i;
  u8 smallest_pmtu_index = MAIN_SCTP_SUB_CONN_IDX;

  for (i = 1; i < MAX_SCTP_CONNECTIONS; i++)
    {
      if (sctp_conn->sub_conn[i].state != SCTP_SUBCONN_STATE_DOWN)
	{
	  if (sctp_conn->sub_conn[i].PMTU <
	      sctp_conn->sub_conn[smallest_pmtu_index].PMTU)
	    smallest_pmtu_index = i;
	}
    }

  sctp_conn->smallest_PMTU_idx = smallest_pmtu_index;
}

/* As per RFC4960; section 7.2.1: Slow-Start */
always_inline void
sctp_init_cwnd (sctp_connection_t * sctp_conn)
{
  u8 i;
  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      /* Section 7.2.1; point (1) */
      sctp_conn->sub_conn[i].cwnd =
	clib_min (4 * sctp_conn->sub_conn[i].PMTU,
		  clib_max (2 * sctp_conn->sub_conn[i].PMTU, 4380));

      /* Section 7.2.1; point (3) */
      sctp_conn->sub_conn[i].ssthresh = SCTP_INITIAL_SSHTRESH;

      /* Section 7.2.2; point (1) */
      sctp_conn->sub_conn[i].partially_acked_bytes = 0;
    }
}

always_inline u8
sctp_in_cong_recovery (sctp_connection_t * sctp_conn, u8 idx)
{
  return 0;
}

always_inline u8
cwnd_fully_utilized (sctp_connection_t * sctp_conn, u8 idx)
{
  return 0;
}

/* As per RFC4960; section 7.2.1: Slow-Start */
always_inline void
update_cwnd (sctp_connection_t * sctp_conn)
{
  u8 i;

  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
    {
      /* Section 7.2.1; point (2) */
      if (sctp_conn->sub_conn[i].is_retransmitting)
	{
	  sctp_conn->sub_conn[i].cwnd = 1 * sctp_conn->sub_conn[i].PMTU;
	  continue;
	}

      /* Section 7.2.2; point (4) */
      if (sctp_conn->sub_conn[i].last_data_ts >
	  sctp_time_now () + SCTP_DATA_IDLE_INTERVAL)
	{
	  sctp_conn->sub_conn[i].cwnd =
	    clib_max (sctp_conn->sub_conn[i].cwnd / 2,
		      4 * sctp_conn->sub_conn[i].PMTU);
	  continue;
	}

      /* Section 7.2.1; point (5) */
      if (sctp_conn->sub_conn[i].cwnd <= sctp_conn->sub_conn[i].ssthresh)
	{
	  if (!cwnd_fully_utilized (sctp_conn, i))
	    continue;

	  if (sctp_in_cong_recovery (sctp_conn, i))
	    continue;

	  sctp_conn->sub_conn[i].cwnd =
	    clib_min (sctp_conn->sub_conn[i].PMTU, 1);
	}
    }
}

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