/*
 *  net/dccp/options.c
 *
 *  An implementation of the DCCP protocol
 *  Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
 *  Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
 *
 *      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 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;
			dp->dccps_timestamp_time = jiffies;

			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 > 8)
				goto out_invalid_option;

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

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

			opt_recv->dccpor_elapsed_time =
					dccp_decode_value_var(value + 4,
							     len - 4);
			dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n",
				      debug_prefix,
				      opt_recv->dccpor_elapsed_time);
			break;
		case DCCPO_ELAPSED_TIME:
			if (len > 4)
				goto out_invalid_option;

			if (pkt_type == DCCP_PKT_DATA)
				continue;
			opt_recv->dccpor_elapsed_time =
					dccp_decode_value_var(value, len);
			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 <= 0xFF ? 1 :
	       elapsed_time <= 0xFFFF ? 2 :
	       elapsed_time <= 0xFFFFFF ? 3 : 4;
}

void dccp_insert_option_elapsed_time(struct sock *sk,
				     struct sk_buff *skb,
				     u32 elapsed_time)
{
#ifdef 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 == 0... */
	if (elapsed_time_len == 2)
		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;

	dccp_encode_value_var(elapsed_time, to, elapsed_time_len);

	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(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 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 = jiffies_to_usecs(jiffies - 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);
}

static inline void dccp_insert_option_timestamp(struct sock *sk,
						struct sk_buff *skb)
{
	const u32 now = htonl(tcp_time_stamp);
	dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
}

static void dccp_insert_option_timestamp_echo(struct sock *sk,
					      struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
#ifdef 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 = jiffies_to_usecs(jiffies -
						  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;
	dccp_encode_value_var(elapsed_time, to, elapsed_time_len);

	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 = 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);

		dccp_insert_option_timestamp(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(unsigned int len, int priority)
{
	struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);

	if (ap != NULL) {
#ifdef 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	     = 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 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;
	ap->dccpap_time = jiffies;
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 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 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 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;
	}
}
