/*
 *  net/dccp/options.c
 *
 *  An implementation of the DCCP protocol
 *  Copyright (c) 2005 Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
 *  Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */
#include <linux/config.h>
#include <linux/dccp.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>

#include "ccid.h"
#include "dccp.h"

static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
					     struct sock *sk,
					     const u64 ackno,
					     const unsigned char len,
					     const unsigned char *vector);

/* stores the default values for new connection. may be changed with sysctl */
static const struct dccp_options dccpo_default_values = {
	.dccpo_sequence_window	  = DCCPF_INITIAL_SEQUENCE_WINDOW,
	.dccpo_ccid		  = DCCPF_INITIAL_CCID,
	.dccpo_send_ack_vector	  = DCCPF_INITIAL_SEND_ACK_VECTOR,
	.dccpo_send_ndp_count	  = DCCPF_INITIAL_SEND_NDP_COUNT,
};

void dccp_options_init(struct dccp_options *dccpo)
{
	memcpy(dccpo, &dccpo_default_values, sizeof(*dccpo));
}

static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
{
	u32 value = 0;

	if (len > 3)
		value += *bf++ << 24;
	if (len > 2)
		value += *bf++ << 16;
	if (len > 1)
		value += *bf++ << 8;
	if (len > 0)
		value += *bf;

	return value;
}

int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
#ifdef CONFIG_IP_DCCP_DEBUG
	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT rx opt: " : "server rx opt: ";
#endif
	const struct dccp_hdr *dh = dccp_hdr(skb);
	const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
	unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
	unsigned char *opt_ptr = options;
	const unsigned char *opt_end = (unsigned char *)dh +
					(dh->dccph_doff * 4);
	struct dccp_options_received *opt_recv = &dp->dccps_options_received;
	unsigned char opt, len;
	unsigned char *value;

	memset(opt_recv, 0, sizeof(*opt_recv));

	while (opt_ptr != opt_end) {
		opt   = *opt_ptr++;
		len   = 0;
		value = NULL;

		/* Check if this isn't a single byte option */
		if (opt > DCCPO_MAX_RESERVED) {
			if (opt_ptr == opt_end)
				goto out_invalid_option;

			len = *opt_ptr++;
			if (len < 3)
				goto out_invalid_option;
			/*
			 * Remove the type and len fields, leaving
			 * just the value size
			 */
			len	-= 2;
			value	= opt_ptr;
			opt_ptr += len;

			if (opt_ptr > opt_end)
				goto out_invalid_option;
		}

		switch (opt) {
		case DCCPO_PADDING:
			break;
		case DCCPO_NDP_COUNT:
			if (len > 3)
				goto out_invalid_option;

			opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
			dccp_pr_debug("%sNDP count=%d\n", debug_prefix,
				      opt_recv->dccpor_ndp);
			break;
		case DCCPO_ACK_VECTOR_0:
			if (len > DCCP_MAX_ACK_VECTOR_LEN)
				goto out_invalid_option;

			if (pkt_type == DCCP_PKT_DATA)
				continue;

			opt_recv->dccpor_ack_vector_len = len;
			opt_recv->dccpor_ack_vector_idx = value - options;

			dccp_pr_debug("%sACK vector 0, len=%d, ack_ackno=%llu\n",
				      debug_prefix, len,
				      (unsigned long long)
				      DCCP_SKB_CB(skb)->dccpd_ack_seq);
			dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq,
					     value, len);
			dccp_ackpkts_check_rcv_ackvector(dp->dccps_hc_rx_ackpkts,
							 sk,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq,
							 len, value);
			break;
		case DCCPO_TIMESTAMP:
			if (len != 4)
				goto out_invalid_option;

			opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);

			dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
			do_gettimeofday(&dp->dccps_timestamp_time);

			dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
				      debug_prefix, opt_recv->dccpor_timestamp,
				      (unsigned long long)
				      DCCP_SKB_CB(skb)->dccpd_ack_seq);
			break;
		case DCCPO_TIMESTAMP_ECHO:
			if (len != 4 && len != 6 && len != 8)
				goto out_invalid_option;

			opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value);

			dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, ",
				      debug_prefix,
				      opt_recv->dccpor_timestamp_echo,
				      len + 2,
				      (unsigned long long)
				      DCCP_SKB_CB(skb)->dccpd_ack_seq);

			if (len > 4) {
				if (len == 6)
					opt_recv->dccpor_elapsed_time =
						 ntohs(*(u16 *)(value + 4));
				else
					opt_recv->dccpor_elapsed_time =
						 ntohl(*(u32 *)(value + 4));

				dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n",
				      debug_prefix,
				      opt_recv->dccpor_elapsed_time);
			}
			break;
		case DCCPO_ELAPSED_TIME:
			if (len != 2 && len != 4)
				goto out_invalid_option;

			if (pkt_type == DCCP_PKT_DATA)
				continue;

			if (len == 2)
				opt_recv->dccpor_elapsed_time =
							ntohs(*(u16 *)value);
			else
				opt_recv->dccpor_elapsed_time =
							ntohl(*(u32 *)value);

			dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
				      opt_recv->dccpor_elapsed_time);
			break;
			/*
			 * From draft-ietf-dccp-spec-11.txt:
			 *
			 *	Option numbers 128 through 191 are for
			 *	options sent from the HC-Sender to the
			 *	HC-Receiver; option numbers 192 through 255
			 *	are for options sent from the HC-Receiver to
			 *	the HC-Sender.
			 */
		case 128 ... 191: {
			const u16 idx = value - options;

			if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
						     opt, len, idx,
						     value) != 0)
				goto out_invalid_option;
		}
			break;
		case 192 ... 255: {
			const u16 idx = value - options;

			if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
						     opt, len, idx,
						     value) != 0)
				goto out_invalid_option;
		}
			break;
		default:
			pr_info("DCCP(%p): option %d(len=%d) not "
				"implemented, ignoring\n",
				sk, opt, len);
			break;
	        }
	}

	return 0;

out_invalid_option:
	DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
	DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
	pr_info("DCCP(%p): invalid option %d, len=%d\n", sk, opt, len);
	return -1;
}

static void dccp_encode_value_var(const u32 value, unsigned char *to,
				  const unsigned int len)
{
	if (len > 3)
		*to++ = (value & 0xFF000000) >> 24;
	if (len > 2)
		*to++ = (value & 0xFF0000) >> 16;
	if (len > 1)
		*to++ = (value & 0xFF00) >> 8;
	if (len > 0)
		*to++ = (value & 0xFF);
}

static inline int dccp_ndp_len(const int ndp)
{
	return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
}

void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
			const unsigned char option,
			const void *value, const unsigned char len)
{
	unsigned char *to;

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) {
		LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
			       "%d option!\n", option);
		return;
	}

	DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;

	to    = skb_push(skb, len + 2);
	*to++ = option;
	*to++ = len + 2;

	memcpy(to, value, len);
}

EXPORT_SYMBOL_GPL(dccp_insert_option);

static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
	int ndp = dp->dccps_ndp_count;

	if (dccp_non_data_packet(skb))
		++dp->dccps_ndp_count;
	else
		dp->dccps_ndp_count = 0;

	if (ndp > 0) {
		unsigned char *ptr;
		const int ndp_len = dccp_ndp_len(ndp);
		const int len = ndp_len + 2;

		if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
			return;

		DCCP_SKB_CB(skb)->dccpd_opt_len += len;

		ptr = skb_push(skb, len);
		*ptr++ = DCCPO_NDP_COUNT;
		*ptr++ = len;
		dccp_encode_value_var(ndp, ptr, ndp_len);
	}
}

static inline int dccp_elapsed_time_len(const u32 elapsed_time)
{
	return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
}

void dccp_insert_option_elapsed_time(struct sock *sk,
				     struct sk_buff *skb,
				     u32 elapsed_time)
{
#ifdef CONFIG_IP_DCCP_DEBUG
	struct dccp_sock *dp = dccp_sk(sk);
	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT TX opt: " : "server TX opt: ";
#endif
	const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
	const int len = 2 + elapsed_time_len;
	unsigned char *to;

	if (elapsed_time_len == 0)
		return;

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
		LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to "
					 "insert elapsed time!\n");
		return;
	}

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to    = skb_push(skb, len);
	*to++ = DCCPO_ELAPSED_TIME;
	*to++ = len;

	if (elapsed_time_len == 2) {
		const u16 var16 = htons((u16)elapsed_time);
		memcpy(to, &var16, 2);
	} else {
		const u32 var32 = htonl(elapsed_time);
		memcpy(to, &var32, 4);
	}

	dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n",
		      debug_prefix, elapsed_time,
		      len,
		      (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
}

EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);

static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
#ifdef CONFIG_IP_DCCP_DEBUG
	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT TX opt: " : "server TX opt: ";
#endif
	struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
	int len = ap->dccpap_buf_vector_len + 2;
	const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10;
	unsigned char *to, *from;

	if (elapsed_time != 0)
		dccp_insert_option_elapsed_time(sk, skb, elapsed_time);

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
		LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to "
					 "insert ACK Vector!\n");
		return;
	}

	/*
	 * XXX: now we have just one ack vector sent record, so
	 * we have to wait for it to be cleared.
	 *
	 * Of course this is not acceptable, but this is just for
	 * basic testing now.
	 */
	if (ap->dccpap_ack_seqno != DCCP_MAX_SEQNO + 1)
		return;

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to    = skb_push(skb, len);
	*to++ = DCCPO_ACK_VECTOR_0;
	*to++ = len;

	len  = ap->dccpap_buf_vector_len;
	from = ap->dccpap_buf + ap->dccpap_buf_head;

	/* Check if buf_head wraps */
	if (ap->dccpap_buf_head + len > ap->dccpap_buf_len) {
		const unsigned int tailsize = (ap->dccpap_buf_len -
					       ap->dccpap_buf_head);

		memcpy(to, from, tailsize);
		to   += tailsize;
		len  -= tailsize;
		from = ap->dccpap_buf;
	}

	memcpy(to, from, len);
	/*
	 *	From draft-ietf-dccp-spec-11.txt:
	 *
	 *	For each acknowledgement it sends, the HC-Receiver will add an
	 *	acknowledgement record.  ack_seqno will equal the HC-Receiver
	 *	sequence number it used for the ack packet; ack_ptr will equal
	 *	buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
	 *	equal buf_nonce.
	 *
	 * This implemention uses just one ack record for now.
	 */
	ap->dccpap_ack_seqno	  = DCCP_SKB_CB(skb)->dccpd_seq;
	ap->dccpap_ack_ptr	  = ap->dccpap_buf_head;
	ap->dccpap_ack_ackno	  = ap->dccpap_buf_ackno;
	ap->dccpap_ack_nonce	  = ap->dccpap_buf_nonce;
	ap->dccpap_ack_vector_len = ap->dccpap_buf_vector_len;

	dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, "
		      "ack_ackno=%llu\n",
		      debug_prefix, ap->dccpap_ack_vector_len,
		      (unsigned long long) ap->dccpap_ack_seqno,
		      (unsigned long long) ap->dccpap_ack_ackno);
}

void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
{
	struct timeval tv;
	u32 now;
	
	do_gettimeofday(&tv);
	now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10;
	/* yes this will overflow but that is the point as we want a
	 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */

	now = htonl(now);
	dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
}

EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);

static void dccp_insert_option_timestamp_echo(struct sock *sk,
					      struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
#ifdef CONFIG_IP_DCCP_DEBUG
	const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT TX opt: " : "server TX opt: ";
#endif
	u32 tstamp_echo;
	const u32 elapsed_time =
			timeval_now_delta(&dp->dccps_timestamp_time) / 10;
	const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
	const int len = 6 + elapsed_time_len;
	unsigned char *to;

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
		LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
					 "timestamp echo!\n");
		return;
	}

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to    = skb_push(skb, len);
	*to++ = DCCPO_TIMESTAMP_ECHO;
	*to++ = len;

	tstamp_echo = htonl(dp->dccps_timestamp_echo);
	memcpy(to, &tstamp_echo, 4);
	to += 4;
	
	if (elapsed_time_len == 2) {
		const u16 var16 = htons((u16)elapsed_time);
		memcpy(to, &var16, 2);
	} else if (elapsed_time_len == 4) {
		const u32 var32 = htonl(elapsed_time);
		memcpy(to, &var32, 4);
	}

	dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n",
		      debug_prefix, dp->dccps_timestamp_echo,
		      len,
		      (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);

	dp->dccps_timestamp_echo = 0;
	dp->dccps_timestamp_time.tv_sec = 0;
	dp->dccps_timestamp_time.tv_usec = 0;
}

void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);

	DCCP_SKB_CB(skb)->dccpd_opt_len = 0;

	if (dp->dccps_options.dccpo_send_ndp_count)
		dccp_insert_option_ndp(sk, skb);

	if (!dccp_packet_without_ack(skb)) {
		if (dp->dccps_options.dccpo_send_ack_vector &&
		    (dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno !=
		     DCCP_MAX_SEQNO + 1))
			dccp_insert_option_ack_vector(sk, skb);

		if (dp->dccps_timestamp_echo != 0)
			dccp_insert_option_timestamp_echo(sk, skb);
	}

	ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
	ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);

	/* XXX: insert other options when appropriate */

	if (DCCP_SKB_CB(skb)->dccpd_opt_len != 0) {
		/* The length of all options has to be a multiple of 4 */
		int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;

		if (padding != 0) {
			padding = 4 - padding;
			memset(skb_push(skb, padding), 0, padding);
			DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
		}
	}
}

struct dccp_ackpkts *dccp_ackpkts_alloc(const unsigned int len,
				        const unsigned int __nocast priority)
{
	struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);

	if (ap != NULL) {
#ifdef CONFIG_IP_DCCP_DEBUG
		memset(ap->dccpap_buf, 0xFF, len);
#endif
		ap->dccpap_buf_len   = len;
		ap->dccpap_buf_head  =
			ap->dccpap_buf_tail =
				ap->dccpap_buf_len - 1;
		ap->dccpap_buf_ackno =
			ap->dccpap_ack_ackno =
				ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
		ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0;
		ap->dccpap_ack_ptr   = 0;
		ap->dccpap_time.tv_sec = 0;
		ap->dccpap_time.tv_usec = 0;
		ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0;
	}

	return ap;
}

void dccp_ackpkts_free(struct dccp_ackpkts *ap)
{
	if (ap != NULL) {
#ifdef CONFIG_IP_DCCP_DEBUG
		memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len);
#endif
		kfree(ap);
	}
}

static inline u8 dccp_ackpkts_state(const struct dccp_ackpkts *ap,
				    const unsigned int index)
{
	return ap->dccpap_buf[index] & DCCP_ACKPKTS_STATE_MASK;
}

static inline u8 dccp_ackpkts_len(const struct dccp_ackpkts *ap,
				  const unsigned int index)
{
	return ap->dccpap_buf[index] & DCCP_ACKPKTS_LEN_MASK;
}

/*
 * If several packets are missing, the HC-Receiver may prefer to enter multiple
 * bytes with run length 0, rather than a single byte with a larger run length;
 * this simplifies table updates if one of the missing packets arrives.
 */
static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
						  const unsigned int packets,
						  const unsigned char state)
{
	unsigned int gap;
	signed long new_head;

	if (ap->dccpap_buf_vector_len + packets > ap->dccpap_buf_len)
		return -ENOBUFS;

	gap	 = packets - 1;
	new_head = ap->dccpap_buf_head - packets;

	if (new_head < 0) {
		if (gap > 0) {
			memset(ap->dccpap_buf, DCCP_ACKPKTS_STATE_NOT_RECEIVED,
			       gap + new_head + 1);
			gap = -new_head;
		}
		new_head += ap->dccpap_buf_len;
	} 

	ap->dccpap_buf_head = new_head;

	if (gap > 0)
		memset(ap->dccpap_buf + ap->dccpap_buf_head + 1,
		       DCCP_ACKPKTS_STATE_NOT_RECEIVED, gap);

	ap->dccpap_buf[ap->dccpap_buf_head] = state;
	ap->dccpap_buf_vector_len += packets;
	return 0;
}

/*
 * Implements the draft-ietf-dccp-spec-11.txt Appendix A
 */
int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
{
	/*
	 * Check at the right places if the buffer is full, if it is, tell the
	 * caller to start dropping packets till the HC-Sender acks our ACK
	 * vectors, when we will free up space in dccpap_buf.
	 *
	 * We may well decide to do buffer compression, etc, but for now lets
	 * just drop.
	 *
	 * From Appendix A:
	 *
	 *	Of course, the circular buffer may overflow, either when the
	 *	HC-Sender is sending data at a very high rate, when the
	 *	HC-Receiver's acknowledgements are not reaching the HC-Sender,
	 *	or when the HC-Sender is forgetting to acknowledge those acks
	 *	(so the HC-Receiver is unable to clean up old state). In this
	 *	case, the HC-Receiver should either compress the buffer (by
	 *	increasing run lengths when possible), transfer its state to
	 *	a larger buffer, or, as a last resort, drop all received
	 *	packets, without processing them whatsoever, until its buffer
	 *	shrinks again.
	 */

	/* See if this is the first ackno being inserted */
	if (ap->dccpap_buf_vector_len == 0) {
		ap->dccpap_buf[ap->dccpap_buf_head] = state;
		ap->dccpap_buf_vector_len = 1;
	} else if (after48(ackno, ap->dccpap_buf_ackno)) {
		const u64 delta = dccp_delta_seqno(ap->dccpap_buf_ackno,
						   ackno);

		/*
		 * Look if the state of this packet is the same as the
		 * previous ackno and if so if we can bump the head len.
		 */
		if (delta == 1 &&
		    dccp_ackpkts_state(ap, ap->dccpap_buf_head) == state &&
		    (dccp_ackpkts_len(ap, ap->dccpap_buf_head) <
		     DCCP_ACKPKTS_LEN_MASK))
			ap->dccpap_buf[ap->dccpap_buf_head]++;
		else if (dccp_ackpkts_set_buf_head_state(ap, delta, state))
			return -ENOBUFS;
	} else {
		/*
		 * A.1.2.  Old Packets
		 *
		 *	When a packet with Sequence Number S arrives, and
		 *	S <= buf_ackno, the HC-Receiver will scan the table
		 *	for the byte corresponding to S. (Indexing structures
		 *	could reduce the complexity of this scan.)
		 */
		u64 delta = dccp_delta_seqno(ackno, ap->dccpap_buf_ackno);
		unsigned int index = ap->dccpap_buf_head;

		while (1) {
			const u8 len = dccp_ackpkts_len(ap, index);
			const u8 state = dccp_ackpkts_state(ap, index);
			/*
			 * valid packets not yet in dccpap_buf have a reserved
			 * entry, with a len equal to 0.
			 */
			if (state == DCCP_ACKPKTS_STATE_NOT_RECEIVED &&
			    len == 0 && delta == 0) { /* Found our
							 reserved seat! */
				dccp_pr_debug("Found %llu reserved seat!\n",
					      (unsigned long long) ackno);
				ap->dccpap_buf[index] = state;
				goto out;
			}
			/* len == 0 means one packet */
			if (delta < len + 1)
				goto out_duplicate;

			delta -= len + 1;
			if (++index == ap->dccpap_buf_len)
				index = 0;
		}
	}

	ap->dccpap_buf_ackno = ackno;
	do_gettimeofday(&ap->dccpap_time);
out:
	dccp_pr_debug("");
	dccp_ackpkts_print(ap);
	return 0;

out_duplicate:
	/* Duplicate packet */
	dccp_pr_debug("Received a dup or already considered lost "
		      "packet: %llu\n", (unsigned long long) ackno);
	return -EILSEQ;
}

#ifdef CONFIG_IP_DCCP_DEBUG
void dccp_ackvector_print(const u64 ackno, const unsigned char *vector,
			  int len)
{
	if (!dccp_debug)
		return;

	printk("ACK vector len=%d, ackno=%llu |", len,
	       (unsigned long long) ackno);

	while (len--) {
		const u8 state = (*vector & DCCP_ACKPKTS_STATE_MASK) >> 6;
		const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);

		printk("%d,%d|", state, rl);
		++vector;
	}

	printk("\n");
}

void dccp_ackpkts_print(const struct dccp_ackpkts *ap)
{
	dccp_ackvector_print(ap->dccpap_buf_ackno,
			     ap->dccpap_buf + ap->dccpap_buf_head,
			     ap->dccpap_buf_vector_len);
}
#endif

static void dccp_ackpkts_trow_away_ack_record(struct dccp_ackpkts *ap)
{
	/*
	 * As we're keeping track of the ack vector size
	 * (dccpap_buf_vector_len) and the sent ack vector size
	 * (dccpap_ack_vector_len) we don't need dccpap_buf_tail at all, but
	 * keep this code here as in the future we'll implement a vector of
	 * ack records, as suggested in draft-ietf-dccp-spec-11.txt
	 * Appendix A. -acme
	 */
#if 0
	ap->dccpap_buf_tail = ap->dccpap_ack_ptr + 1;
	if (ap->dccpap_buf_tail >= ap->dccpap_buf_len)
		ap->dccpap_buf_tail -= ap->dccpap_buf_len;
#endif
	ap->dccpap_buf_vector_len -= ap->dccpap_ack_vector_len;
}

void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, struct sock *sk,
				 u64 ackno)
{
	/* Check if we actually sent an ACK vector */
	if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
		return;

	if (ackno == ap->dccpap_ack_seqno) {
#ifdef CONFIG_IP_DCCP_DEBUG
		struct dccp_sock *dp = dccp_sk(sk);
		const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT rx ack: " : "server rx ack: ";
#endif
		dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, "
			      "ack_ackno=%llu, ACKED!\n",
			      debug_prefix, 1,
			      (unsigned long long) ap->dccpap_ack_seqno,
			      (unsigned long long) ap->dccpap_ack_ackno);
		dccp_ackpkts_trow_away_ack_record(ap);
		ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
	}
}

static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
					     struct sock *sk, u64 ackno,
					     const unsigned char len,
					     const unsigned char *vector)
{
	unsigned char i;

	/* Check if we actually sent an ACK vector */
	if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
		return;
	/*
	 * We're in the receiver half connection, so if the received an ACK
	 * vector ackno (e.g. 50) before dccpap_ack_seqno (e.g. 52), we're
	 * not interested.
	 *
	 * Extra explanation with example:
	 * 
	 * if we received an ACK vector with ackno 50, it can only be acking
	 * 50, 49, 48, etc, not 52 (the seqno for the ACK vector we sent).
	 */
	/* dccp_pr_debug("is %llu < %llu? ", ackno, ap->dccpap_ack_seqno); */
	if (before48(ackno, ap->dccpap_ack_seqno)) {
		/* dccp_pr_debug_cat("yes\n"); */
		return;
	}
	/* dccp_pr_debug_cat("no\n"); */

	i = len;
	while (i--) {
		const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);
		u64 ackno_end_rl;

		dccp_set_seqno(&ackno_end_rl, ackno - rl);

		/*
		 * dccp_pr_debug("is %llu <= %llu <= %llu? ", ackno_end_rl,
		 * ap->dccpap_ack_seqno, ackno);
		 */
		if (between48(ap->dccpap_ack_seqno, ackno_end_rl, ackno)) {
			const u8 state = (*vector &
					  DCCP_ACKPKTS_STATE_MASK) >> 6;
			/* dccp_pr_debug_cat("yes\n"); */

			if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) {
#ifdef CONFIG_IP_DCCP_DEBUG
				struct dccp_sock *dp = dccp_sk(sk);
				const char *debug_prefix =
					dp->dccps_role == DCCP_ROLE_CLIENT ?
					"CLIENT rx ack: " : "server rx ack: ";
#endif
				dccp_pr_debug("%sACK vector 0, len=%d, "
					      "ack_seqno=%llu, ack_ackno=%llu, "
					      "ACKED!\n",
					      debug_prefix, len,
					      (unsigned long long)
					      ap->dccpap_ack_seqno,
					      (unsigned long long)
					      ap->dccpap_ack_ackno);
				dccp_ackpkts_trow_away_ack_record(ap);
			}
			/*
			 * If dccpap_ack_seqno was not received, no problem
			 * we'll send another ACK vector.
			 */
			ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
			break;
		}
		/* dccp_pr_debug_cat("no\n"); */

		dccp_set_seqno(&ackno, ackno_end_rl - 1);
		++vector;
	}
}
