ccid3.c 35.7 KB
Newer Older
1 2 3 4
/*
 *  net/dccp/ccids/ccid3.c
 *
 *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
I
Ian McDonald 已提交
5
 *  Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 *
 *  An implementation of the DCCP protocol
 *
 *  This code has been developed by the University of Waikato WAND
 *  research group. For further information please see http://www.wand.net.nz/
 *
 *  This code also uses code from Lulea University, rereleased as GPL by its
 *  authors:
 *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
 *
 *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft
 *  and to make it work as a loadable module in the DCCP stack written by
 *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
 *
 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

37
#include <linux/config.h>
38 39
#include "../ccid.h"
#include "../dccp.h"
40
#include "lib/packet_history.h"
41
#include "lib/loss_interval.h"
42
#include "lib/tfrc.h"
43 44
#include "ccid3.h"

45
/*
46 47
 * Reason for maths here is to avoid 32 bit overflow when a is big.
 * With this we get close to the limit.
48 49 50
 */
static inline u32 usecs_div(const u32 a, const u32 b)
{
51 52 53 54 55 56 57 58 59 60 61
	const u32 div = a < (UINT_MAX / (USEC_PER_SEC /    10)) ?    10 :
			a < (UINT_MAX / (USEC_PER_SEC /    50)) ?    50 :
			a < (UINT_MAX / (USEC_PER_SEC /   100)) ?   100 :
			a < (UINT_MAX / (USEC_PER_SEC /   500)) ?   500 :
			a < (UINT_MAX / (USEC_PER_SEC /  1000)) ?  1000 :
			a < (UINT_MAX / (USEC_PER_SEC /  5000)) ?  5000 :
			a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
			a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
								 100000;
	const u32 tmp = a * (USEC_PER_SEC / div);
	return (b >= 2 * div) ? tmp / (b / div) : tmp;
62 63
}

64
static int ccid3_debug;
65

66
#ifdef CCID3_DEBUG
67 68 69 70 71 72 73 74
#define ccid3_pr_debug(format, a...) \
	do { if (ccid3_debug) \
		printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
	} while (0)
#else
#define ccid3_pr_debug(format, a...)
#endif

75 76
static struct dccp_tx_hist *ccid3_tx_hist;
static struct dccp_rx_hist *ccid3_rx_hist;
77
static struct dccp_li_hist *ccid3_li_hist;
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

static int ccid3_init(struct sock *sk)
{
	return 0;
}

static void ccid3_exit(struct sock *sk)
{
}

/* TFRC sender states */
enum ccid3_hc_tx_states {
       	TFRC_SSTATE_NO_SENT = 1,
	TFRC_SSTATE_NO_FBACK,
	TFRC_SSTATE_FBACK,
	TFRC_SSTATE_TERM,
};

#ifdef CCID3_DEBUG
static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
{
	static char *ccid3_state_names[] = {
	[TFRC_SSTATE_NO_SENT]  = "NO_SENT",
	[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
	[TFRC_SSTATE_FBACK]    = "FBACK",
	[TFRC_SSTATE_TERM]     = "TERM",
	};

	return ccid3_state_names[state];
}
#endif

110 111
static inline void ccid3_hc_tx_set_state(struct sock *sk,
					 enum ccid3_hc_tx_states state)
112
{
113
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
114 115 116
	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
117 118
		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
		       ccid3_tx_state_name(state));
119 120 121 122 123 124 125
	WARN_ON(state == oldstate);
	hctx->ccid3hctx_state = state;
}

/* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
{
126 127 128 129 130 131 132
	/*
	 * If no feedback spec says t_ipi is 1 second (set elsewhere and then
	 * doubles after every no feedback timer (separate function)
	 */
	if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
		hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s,
						  hctx->ccid3hctx_x);
133 134 135 136 137
}

/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
{
138 139
	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
					   TFRC_OPSYS_HALF_TIME_GRAN);
140 141 142 143 144 145 146 147 148 149 150 151 152 153
}

/*
 * Update X by
 *    If (p > 0)
 *       x_calc = calcX(s, R, p);
 *       X = max(min(X_calc, 2 * X_recv), s / t_mbi);
 *    Else
 *       If (now - tld >= R)
 *          X = max(min(2 * X, 2 * X_recv), s / R);
 *          tld = now;
 */ 
static void ccid3_hc_tx_update_x(struct sock *sk)
{
154
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
155

156 157
	/* To avoid large error in calcX */
	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
158 159 160
		hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
						     hctx->ccid3hctx_rtt,
						     hctx->ccid3hctx_p);
161 162 163 164
		hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc,
							  2 * hctx->ccid3hctx_x_recv),
					       (hctx->ccid3hctx_s /
					        TFRC_MAX_BACK_OFF_TIME));
165 166 167
	} else {
		struct timeval now;

168
		dccp_timestamp(sk, &now);
169 170
	       	if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
		    hctx->ccid3hctx_rtt) {
171 172 173 174
			hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv,
								  hctx->ccid3hctx_x) * 2,
						       usecs_div(hctx->ccid3hctx_s,
							       	 hctx->ccid3hctx_rtt));
175 176
			hctx->ccid3hctx_t_ld = now;
		}
177 178 179 180 181 182 183
	}
}

static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
	struct sock *sk = (struct sock *)data;
	unsigned long next_tmout = 0;
184
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
185 186 187 188 189

	bh_lock_sock(sk);
	if (sock_owned_by_user(sk)) {
		/* Try again later. */
		/* XXX: set some sensible MIB */
190 191
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + HZ / 5);
192 193 194 195 196 197 198 199 200 201 202 203
		goto out;
	}

	ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
		       ccid3_tx_state_name(hctx->ccid3hctx_state));
	
	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_TERM:
		goto out;
	case TFRC_SSTATE_NO_FBACK:
		/* Halve send rate */
		hctx->ccid3hctx_x /= 2;
204 205
		if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s /
					 TFRC_MAX_BACK_OFF_TIME))
206 207
			hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
					     TFRC_MAX_BACK_OFF_TIME);
208

209 210 211 212
		ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d "
			       "bytes/s\n",
			       dccp_role(sk), sk,
			       ccid3_tx_state_name(hctx->ccid3hctx_state),
213
			       hctx->ccid3hctx_x);
214 215
		next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x),
216 217 218 219 220 221
					TFRC_INITIAL_TIMEOUT);
		/*
		 * FIXME - not sure above calculation is correct. See section
		 * 5 of CCID3 11 should adjust tx_t_ipi and double that to
		 * achieve it really
		 */
222 223
		break;
	case TFRC_SSTATE_FBACK:
224 225 226 227 228
		/*
		 * Check if IDLE since last timeout and recv rate is less than
		 * 4 packets per RTT
		 */
		if (!hctx->ccid3hctx_idle ||
229 230
		    (hctx->ccid3hctx_x_recv >=
		     4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) {
231 232
			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
				       dccp_role(sk), sk,
233 234 235 236 237 238 239 240
				       ccid3_tx_state_name(hctx->ccid3hctx_state));
			/* Halve sending rate */

			/*  If (X_calc > 2 * X_recv)
			 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
			 *  Else
			 *    X_recv = X_calc / 4;
			 */
241 242
			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P &&
			       hctx->ccid3hctx_x_calc == 0);
243 244 245 246 247 248 249 250 251 252 253 254

			/* check also if p is zero -> x_calc is infinity? */
			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
			    hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
				hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
								    hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
			else
				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;

			/* Update sending rate */
			ccid3_hc_tx_update_x(sk);
		}
255 256 257 258
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
259
		next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 
260 261
					2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x));
262 263 264 265 266 267 268 269 270
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
		dump_stack();
		goto out;
	}

	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
271
		      jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
272 273 274 275 276 277
	hctx->ccid3hctx_idle = 1;
out:
	bh_unlock_sock(sk);
	sock_put(sk);
}

278 279
static int ccid3_hc_tx_send_packet(struct sock *sk,
				   struct sk_buff *skb, int len)
280 281
{
	struct dccp_sock *dp = dccp_sk(sk);
282
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
283
	struct dccp_tx_hist_entry *new_packet;
284
	struct timeval now;
285
	long delay;
286 287
	int rc = -ENOTCONN;

288
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
289

290
	/* Check if pure ACK or Terminating*/
291
	/*
292 293
	 * XXX: We only call this function for DATA and DATAACK, on, these
	 * packets can have zero length, but why the comment about "pure ACK"?
294
	 */
295
	if (unlikely(len == 0))
296 297 298
		goto out;

	/* See if last packet allocated was not sent */
299 300
	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
	if (new_packet == NULL || new_packet->dccphtx_sent) {
301 302
		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
						    SLAB_ATOMIC);
303 304

		rc = -ENOBUFS;
305 306 307 308
		if (unlikely(new_packet == NULL)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough "
				       "mem to add to history, send refused\n",
				       __FUNCTION__, dccp_role(sk), sk);
309 310 311
			goto out;
		}

312
		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
313 314
	}

315
	dccp_timestamp(sk, &now);
316 317 318 319 320

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
		hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
		hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
321 322
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
323 324 325
		hctx->ccid3hctx_last_win_count	 = 0;
		hctx->ccid3hctx_t_last_win_count = now;
		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
326
		hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
327 328 329

		/* Set nominal send time for initial packet */
		hctx->ccid3hctx_t_nom = now;
330 331
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
332 333 334 335 336
		ccid3_calc_new_delta(hctx);
		rc = 0;
		break;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
337 338
		delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
		         hctx->ccid3hctx_delta);
339
		delay /= -1000;
340
		/* divide by -1000 is to convert to ms and get sign right */
341
		rc = delay > 0 ? delay : 0;
342 343 344 345 346 347 348 349 350 351
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
		dump_stack();
		rc = -EINVAL;
		break;
	}

	/* Can we send? if so add options and add to packet history */
352 353
	if (rc == 0) {
		dp->dccps_hc_tx_insert_options = 1;
354
		new_packet->dccphtx_ccval =
355 356
			DCCP_SKB_CB(skb)->dccpd_ccval =
				hctx->ccid3hctx_last_win_count;
357
	}
358 359 360 361 362 363
out:
	return rc;
}

static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
{
364 365
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
366 367
	struct timeval now;

368
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
369

370
	dccp_timestamp(sk, &now);
371 372 373 374

	/* check if we have sent a data packet */
	if (len > 0) {
		unsigned long quarter_rtt;
375
		struct dccp_tx_hist_entry *packet;
376

377
		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
378 379 380
		if (unlikely(packet == NULL)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
				       "exists in history!\n", __FUNCTION__);
381 382
			return;
		}
383 384 385
		if (unlikely(packet->dccphtx_sent)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
				       "history!\n", __FUNCTION__);
386 387
			return;
		}
388 389
		packet->dccphtx_tstamp = now;
		packet->dccphtx_seqno  = dp->dccps_gss;
390
		/*
391 392 393
		 * Check if win_count have changed
		 * Algorithm in "8.1. Window Counter Valuer" in
		 * draft-ietf-dccp-ccid3-11.txt
394
		 */
395 396 397 398
		quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
		if (likely(hctx->ccid3hctx_rtt > 8))
			quarter_rtt /= hctx->ccid3hctx_rtt / 4;

399 400 401 402
		if (quarter_rtt > 0) {
			hctx->ccid3hctx_t_last_win_count = now;
			hctx->ccid3hctx_last_win_count	 = (hctx->ccid3hctx_last_win_count +
							    min_t(unsigned long, quarter_rtt, 5)) % 16;
403 404
			ccid3_pr_debug("%s, sk=%p, window changed from "
				       "%u to %u!\n",
405
				       dccp_role(sk), sk,
406
				       packet->dccphtx_ccval,
407 408
				       hctx->ccid3hctx_last_win_count);
		}
409

410
		hctx->ccid3hctx_idle = 0;
411
		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
412
		packet->dccphtx_sent = 1;
413 414 415 416 417 418 419 420
	} else
		ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
			       dccp_role(sk), sk, dp->dccps_gss);

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
		/* if first wasn't pure ack */
		if (len != 0)
421 422
			printk(KERN_CRIT "%s: %s, First packet sent is noted "
					 "as a data packet\n",
423 424 425 426 427 428 429 430
			       __FUNCTION__, dccp_role(sk));
		return;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
		if (len > 0) {
			hctx->ccid3hctx_t_nom = now;
			ccid3_calc_new_t_ipi(hctx);
			ccid3_calc_new_delta(hctx);
431 432
			timeval_add_usecs(&hctx->ccid3hctx_t_nom,
					  hctx->ccid3hctx_t_ipi);
433 434 435 436 437 438 439 440 441 442 443 444
		}
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
		dump_stack();
		break;
	}
}

static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
445 446
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
447
	struct ccid3_options_received *opt_recv;
448
	struct dccp_tx_hist_entry *packet;
449
	struct timeval now;
450
	unsigned long next_tmout; 
I
Ian McDonald 已提交
451
	u32 t_elapsed;
452 453 454
	u32 pinv;
	u32 x_recv;
	u32 r_sample;
455

456
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
457 458 459 460 461 462 463 464

	/* we are only interested in ACKs */
	if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
	      DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
		return;

	opt_recv = &hctx->ccid3hctx_options_received;

465
	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
466 467 468 469 470 471 472 473 474 475 476 477
	x_recv = opt_recv->ccid3or_receive_rate;
	pinv = opt_recv->ccid3or_loss_event_rate;

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
		/* FIXME: what to do here? */
		return;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
		/* Calculate new round trip sample by
		 * R_sample = (now - t_recvdata) - t_delay */
		/* get t_recvdata from history */
478 479
		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
480 481 482 483 484 485
		if (unlikely(packet == NULL)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno "
				       "%llu(%s) does't exist in history!\n",
				       __FUNCTION__, dccp_role(sk), sk,
			    (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
				dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
486 487 488 489
			return;
		}

		/* Update RTT */
490 491
		dccp_timestamp(sk, &now);
		r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
492
		if (unlikely(r_sample <= t_elapsed))
493 494
			LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
				       "t_elapsed=%uus\n",
495 496 497
				       __FUNCTION__, r_sample, t_elapsed);
		else
			r_sample -= t_elapsed;
498 499 500 501 502 503 504 505 506 507 508 509 510

		/* Update RTT estimate by 
		 * If (No feedback recv)
		 *    R = R_sample;
		 * Else
		 *    R = q * R + (1 - q) * R_sample;
		 *
		 * q is a constant, RFC 3448 recomments 0.9
		 */
		if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
			hctx->ccid3hctx_rtt = r_sample;
		} else
511 512
			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
					      r_sample / 10;
513

514 515 516
		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
			       "r_sample=%us\n", dccp_role(sk), sk,
			       hctx->ccid3hctx_rtt, r_sample);
517 518

		/* Update timeout interval */
519 520
		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
					      USEC_PER_SEC);
521 522

		/* Update receive rate */
523
		hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
524 525 526 527 528 529 530 531 532

		/* Update loss event rate */
		if (pinv == ~0 || pinv == 0)
			hctx->ccid3hctx_p = 0;
		else {
			hctx->ccid3hctx_p = 1000000 / pinv;

			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
				hctx->ccid3hctx_p = TFRC_SMALLEST_P;
533 534
				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n",
					       dccp_role(sk), sk);
535 536 537 538 539 540 541 542 543 544
			}
		}

		/* unschedule no feedback timer */
		sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);

		/* Update sending rate */
		ccid3_hc_tx_update_x(sk);

		/* Update next send time */
545 546
		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
547
		ccid3_calc_new_t_ipi(hctx);
548 549
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
550 551 552
		ccid3_calc_new_delta(hctx);

		/* remove all packets older than the one acked from history */
553 554
		dccp_tx_hist_purge_older(ccid3_tx_hist,
					 &hctx->ccid3hctx_hist, packet);
555 556 557 558 559
		/*
		 * As we have calculated new ipi, delta, t_nom it is possible that
		 * we now can send a packet, so wake up dccp_wait_for_ccids.
		 */
		sk->sk_write_space(sk);
560

561 562 563 564
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
565
		next_tmout = max(hctx->ccid3hctx_t_rto,
566 567 568
				 2 * usecs_div(hctx->ccid3hctx_s,
					       hctx->ccid3hctx_x));
			
569 570 571 572
		ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
			       "expire in %lu jiffies (%luus)\n",
			       dccp_role(sk), sk,
			       usecs_to_jiffies(next_tmout), next_tmout); 
573 574

		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
575
			       jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
576 577 578 579 580 581 582 583 584 585 586 587 588 589

		/* set idle flag */
		hctx->ccid3hctx_idle = 1;   
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
		dump_stack();
		break;
	}
}

static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
{
590
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
591

592 593 594
	BUG_ON(hctx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
595 596 597 598 599 600
		return;

	 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
}

static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
601 602
				     unsigned char len, u16 idx,
				     unsigned char *value)
603 604
{
	int rc = 0;
605 606
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
607 608
	struct ccid3_options_received *opt_recv;

609
	BUG_ON(hctx == NULL);
610 611 612 613 614 615 616 617 618 619 620 621 622

	opt_recv = &hctx->ccid3hctx_options_received;

	if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
		opt_recv->ccid3or_seqno		     = dp->dccps_gsr;
		opt_recv->ccid3or_loss_event_rate    = ~0;
		opt_recv->ccid3or_loss_intervals_idx = 0;
		opt_recv->ccid3or_loss_intervals_len = 0;
		opt_recv->ccid3or_receive_rate	     = 0;
	}

	switch (option) {
	case TFRC_OPT_LOSS_EVENT_RATE:
623 624 625 626
		if (unlikely(len != 4)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
				       "len for TFRC_OPT_LOSS_EVENT_RATE\n",
				       __FUNCTION__, dccp_role(sk), sk);
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
			rc = -EINVAL;
		} else {
			opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
			ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
				       dccp_role(sk), sk,
				       opt_recv->ccid3or_loss_event_rate);
		}
		break;
	case TFRC_OPT_LOSS_INTERVALS:
		opt_recv->ccid3or_loss_intervals_idx = idx;
		opt_recv->ccid3or_loss_intervals_len = len;
		ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
			       dccp_role(sk), sk,
			       opt_recv->ccid3or_loss_intervals_idx,
			       opt_recv->ccid3or_loss_intervals_len);
		break;
	case TFRC_OPT_RECEIVE_RATE:
644 645 646 647
		if (unlikely(len != 4)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
				       "len for TFRC_OPT_RECEIVE_RATE\n",
				       __FUNCTION__, dccp_role(sk), sk);
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
			rc = -EINVAL;
		} else {
			opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
				       dccp_role(sk), sk,
				       opt_recv->ccid3or_receive_rate);
		}
		break;
	}

	return rc;
}

static int ccid3_hc_tx_init(struct sock *sk)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx;

666 667
	dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
	if (dp->dccps_hc_tx_ccid_private == NULL)
668 669
		return -ENOMEM;

670
	hctx = ccid3_hc_tx_sk(sk);
671 672
	memset(hctx, 0, sizeof(*hctx));

673 674 675
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hctx->ccid3hctx_s = dp->dccps_packet_size;
676 677 678
	else
		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;

679 680
	/* Set transmission rate to 1 packet per second */
	hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
681
	hctx->ccid3hctx_t_rto = USEC_PER_SEC;
682 683 684 685 686 687 688 689 690 691
	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
	init_timer(&hctx->ccid3hctx_no_feedback_timer);

	return 0;
}

static void ccid3_hc_tx_exit(struct sock *sk)
{
	struct dccp_sock *dp = dccp_sk(sk);
692
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
693 694 695 696 697 698 699

	BUG_ON(hctx == NULL);

	ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
	sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);

	/* Empty packet history */
700
	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729

	kfree(dp->dccps_hc_tx_ccid_private);
	dp->dccps_hc_tx_ccid_private = NULL;
}

/*
 * RX Half Connection methods
 */

/* TFRC receiver states */
enum ccid3_hc_rx_states {
       	TFRC_RSTATE_NO_DATA = 1,
	TFRC_RSTATE_DATA,
	TFRC_RSTATE_TERM    = 127,
};

#ifdef CCID3_DEBUG
static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
{
	static char *ccid3_rx_state_names[] = {
	[TFRC_RSTATE_NO_DATA] = "NO_DATA",
	[TFRC_RSTATE_DATA]    = "DATA",
	[TFRC_RSTATE_TERM]    = "TERM",
	};

	return ccid3_rx_state_names[state];
}
#endif

730 731
static inline void ccid3_hc_rx_set_state(struct sock *sk,
					 enum ccid3_hc_rx_states state)
732
{
733
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
734 735 736
	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
737 738
		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
		       ccid3_rx_state_name(state));
739 740 741 742 743 744
	WARN_ON(state == oldstate);
	hcrx->ccid3hcrx_state = state;
}

static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
745
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
746
	struct dccp_sock *dp = dccp_sk(sk);
747
	struct dccp_rx_hist_entry *packet;
748
	struct timeval now;
749 750 751

	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);

752
	dccp_timestamp(sk, &now);
753

754 755 756 757 758
	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
		hcrx->ccid3hcrx_x_recv = 0;
		break;
	case TFRC_RSTATE_DATA: {
759 760
		const u32 delta = timeval_delta(&now,
					&hcrx->ccid3hcrx_tstamp_last_feedback);
761 762
		hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
						   delta);
763 764 765 766 767 768 769 770 771
	}
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
		dump_stack();
		return;
	}

772
	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
773 774 775 776
	if (unlikely(packet == NULL)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet "
			       "in history!\n",
			       __FUNCTION__, dccp_role(sk), sk);
777 778 779
		return;
	}

780
	hcrx->ccid3hcrx_tstamp_last_feedback = now;
781
	hcrx->ccid3hcrx_last_counter	     = packet->dccphrx_ccval;
782
	hcrx->ccid3hcrx_seqno_last_counter   = packet->dccphrx_seqno;
783 784 785
	hcrx->ccid3hcrx_bytes_recv	     = 0;

	/* Convert to multiples of 10us */
786 787
	hcrx->ccid3hcrx_elapsed_time =
			timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
788 789 790 791
	if (hcrx->ccid3hcrx_p == 0)
		hcrx->ccid3hcrx_pinv = ~0;
	else
		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
792
	dp->dccps_hc_rx_insert_options = 1;
793 794 795 796 797
	dccp_send_ack(sk);
}

static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
{
798
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
799
	u32 x_recv, pinv;
800

801 802 803
	BUG_ON(hcrx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
804 805 806
		return;

	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
807 808 809 810 811 812 813 814 815 816 817 818 819 820

	if (dccp_packet_without_ack(skb))
		return;
		
	if (hcrx->ccid3hcrx_elapsed_time != 0)
		dccp_insert_option_elapsed_time(sk, skb,
						hcrx->ccid3hcrx_elapsed_time);
	dccp_insert_option_timestamp(sk, skb);
	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
	pinv   = htonl(hcrx->ccid3hcrx_pinv);
	dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
			   &pinv, sizeof(pinv));
	dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
			   &x_recv, sizeof(x_recv));
821 822 823 824 825 826 827 828
}

/* calculate first loss interval
 *
 * returns estimated loss interval in usecs */

static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
829
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
830
	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
831
	u32 rtt, delta, x_recv, fval, p, tmp2;
832
	struct timeval tstamp = { 0, };
833 834 835 836 837
	int interval = 0;
	int win_count = 0;
	int step = 0;
	u64 tmp1;

838 839 840
	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
				 dccphrx_node) {
		if (dccp_rx_hist_entry_data_packet(entry)) {
841 842 843 844
			tail = entry;

			switch (step) {
			case 0:
845
				tstamp	  = entry->dccphrx_tstamp;
846
				win_count = entry->dccphrx_ccval;
847 848 849
				step = 1;
				break;
			case 1:
850
				interval = win_count - entry->dccphrx_ccval;
851 852 853 854 855 856 857 858 859
				if (interval < 0)
					interval += TFRC_WIN_COUNT_LIMIT;
				if (interval > 4)
					goto found;
				break;
			}
		}
	}

860 861 862 863
	if (unlikely(step == 0)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history "
			       "contains no data packets!\n",
			       __FUNCTION__, dccp_role(sk), sk);
864 865 866
		return ~0;
	}

867 868 869 870
	if (unlikely(interval == 0)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a "
			       "win_count interval > 0. Defaulting to 1\n",
			       __FUNCTION__, dccp_role(sk), sk);
871 872 873
		interval = 1;
	}
found:
874
	rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
875 876 877 878 879
	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
		       dccp_role(sk), sk, rtt);
	if (rtt == 0)
		rtt = 1;

880 881 882
	dccp_timestamp(sk, &tstamp);
	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
	x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
883 884 885 886 887 888

	tmp1 = (u64)x_recv * (u64)rtt;
	do_div(tmp1,10000000);
	tmp2 = (u32)tmp1;
	fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
	/* do not alter order above or you will get overflow on 32 bit */
889
	p = tfrc_calc_x_reverse_lookup(fval);
890 891
	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
892 893 894 895 896 897 898 899 900

	if (p == 0)
		return ~0;
	else
		return 1000000 / p; 
}

static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
{
901
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
902

903 904 905
	if (seq_loss != DCCP_MAX_SEQNO + 1 &&
	    list_empty(&hcrx->ccid3hcrx_li_hist)) {
		struct dccp_li_hist_entry *li_tail;
906

907 908 909 910 911 912
		li_tail = dccp_li_hist_interval_new(ccid3_li_hist,
						    &hcrx->ccid3hcrx_li_hist,
						    seq_loss, win_loss);
		if (li_tail == NULL)
			return;
		li_tail->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
913 914 915
	} else
		    LIMIT_NETDEBUG(KERN_WARNING "%s: FIXME: find end of "
				   "interval\n", __FUNCTION__);
916 917 918 919
}

static void ccid3_hc_rx_detect_loss(struct sock *sk)
{
920
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
921 922 923 924
	u8 win_loss;
	const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
						      &hcrx->ccid3hcrx_li_hist,
						      &win_loss);
925 926 927 928 929 930

	ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
931
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
932
	const struct dccp_options_received *opt_recv;
933
	struct dccp_rx_hist_entry *packet;
934 935
	struct timeval now;
	u8 win_count;
936
	u32 p_prev, r_sample, t_elapsed;
937
	int ins;
938

939 940
	BUG_ON(hcrx == NULL ||
	       !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
941 942
		 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));

943
	opt_recv = &dccp_sk(sk)->dccps_options_received;
944

945 946 947 948 949
	switch (DCCP_SKB_CB(skb)->dccpd_type) {
	case DCCP_PKT_ACK:
		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			return;
	case DCCP_PKT_DATAACK:
950
		if (opt_recv->dccpor_timestamp_echo == 0)
951 952
			break;
		p_prev = hcrx->ccid3hcrx_rtt;
953
		dccp_timestamp(sk, &now);
954 955 956 957 958
		timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
		r_sample = timeval_usecs(&now);
		t_elapsed = opt_recv->dccpor_elapsed_time * 10;

		if (unlikely(r_sample <= t_elapsed))
959 960
			LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
				       "t_elapsed=%uus\n",
961 962 963 964 965 966 967 968 969 970
				       __FUNCTION__, r_sample, t_elapsed);
		else
			r_sample -= t_elapsed;

		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			hcrx->ccid3hcrx_rtt = r_sample;
		else
			hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
					      r_sample / 10;

971
		if (p_prev != hcrx->ccid3hcrx_rtt)
972 973 974
			ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
				       dccp_role(sk), hcrx->ccid3hcrx_rtt,
				       opt_recv->dccpor_elapsed_time);
975 976 977
		break;
	case DCCP_PKT_DATA:
		break;
978
	default: /* We're not interested in other packet types, move along */
979 980 981
		return;
	}

982
	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
983
					skb, SLAB_ATOMIC);
984 985 986 987
	if (unlikely(packet == NULL)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to "
				"add rx packet to history, consider it lost!\n",
			       __FUNCTION__, dccp_role(sk), sk);
988 989 990
		return;
	}

991
	win_count = packet->dccphrx_ccval;
992

993 994
	ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
				      &hcrx->ccid3hcrx_li_hist, packet);
995 996 997 998 999 1000

	if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
		return;

	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
1001 1002 1003 1004
		ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
			       "feedback\n",
			       dccp_role(sk), sk,
			       dccp_state_name(sk->sk_state), skb);
1005 1006 1007 1008
		ccid3_hc_rx_send_feedback(sk);
		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
		return;
	case TFRC_RSTATE_DATA:
1009 1010
		hcrx->ccid3hcrx_bytes_recv += skb->len -
					      dccp_hdr(skb)->dccph_doff * 4;
1011 1012 1013
		if (ins != 0)
			break;

1014
		dccp_timestamp(sk, &now);
1015 1016 1017 1018
		if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
		    hcrx->ccid3hcrx_rtt) {
			hcrx->ccid3hcrx_tstamp_last_ack = now;
			ccid3_hc_rx_send_feedback(sk);
1019
		}
1020
		return;
1021 1022 1023 1024 1025 1026 1027 1028
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
		dump_stack();
		return;
	}

	/* Dealing with packet loss */
1029 1030
	ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1031 1032 1033 1034 1035

	ccid3_hc_rx_detect_loss(sk);
	p_prev = hcrx->ccid3hcrx_p;
	
	/* Calculate loss event rate */
1036
	if (!list_empty(&hcrx->ccid3hcrx_li_hist))
1037
		/* Scaling up by 1000000 as fixed decimal */
1038
		hcrx->ccid3hcrx_p = 1000000 / dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052

	if (hcrx->ccid3hcrx_p > p_prev) {
		ccid3_hc_rx_send_feedback(sk);
		return;
	}
}

static int ccid3_hc_rx_init(struct sock *sk)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_rx_sock *hcrx;

	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);

1053 1054
	dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
	if (dp->dccps_hc_rx_ccid_private == NULL)
1055 1056
		return -ENOMEM;

1057
	hcrx = ccid3_hc_rx_sk(sk);
1058 1059
	memset(hcrx, 0, sizeof(*hcrx));

1060 1061 1062
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1063 1064 1065 1066 1067
	else
		hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;

	hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1068
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1069
	dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1070 1071
	hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
	hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1072 1073 1074 1075 1076
	return 0;
}

static void ccid3_hc_rx_exit(struct sock *sk)
{
1077
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1078 1079
	struct dccp_sock *dp = dccp_sk(sk);

1080
	BUG_ON(hcrx == NULL);
1081 1082 1083 1084

	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

	/* Empty packet history */
1085
	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1086 1087

	/* Empty loss interval history */
1088
	dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1089 1090 1091 1092 1093

	kfree(dp->dccps_hc_rx_ccid_private);
	dp->dccps_hc_rx_ccid_private = NULL;
}

1094 1095
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
1096
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1097

1098 1099 1100 1101
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return;

1102
	BUG_ON(hcrx == NULL);
1103 1104 1105 1106 1107 1108 1109 1110

	info->tcpi_ca_state	= hcrx->ccid3hcrx_state;
	info->tcpi_options	|= TCPI_OPT_TIMESTAMPS;
	info->tcpi_rcv_rtt	= hcrx->ccid3hcrx_rtt;
}

static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
{
1111
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
1112

1113 1114 1115 1116
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return;

1117
	BUG_ON(hctx == NULL);
1118 1119 1120 1121 1122

	info->tcpi_rto = hctx->ccid3hctx_t_rto;
	info->tcpi_rtt = hctx->ccid3hctx_rtt;
}

1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
				  u32 __user *optval, int __user *optlen)
{
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
	const void *val;
	
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return -EINVAL;

	switch (optname) {
	case DCCP_SOCKOPT_CCID_RX_INFO:
		if (len < sizeof(hcrx->ccid3hcrx_tfrc))
			return -EINVAL;
		len = sizeof(hcrx->ccid3hcrx_tfrc);
		val = &hcrx->ccid3hcrx_tfrc;
		break;
	default:
		return -ENOPROTOOPT;
	}

	if (put_user(len, optlen) || copy_to_user(optval, val, len))
		return -EFAULT;

	return 0;
}

static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
				  u32 __user *optval, int __user *optlen)
{
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
	const void *val;
	
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return -EINVAL;

	switch (optname) {
	case DCCP_SOCKOPT_CCID_TX_INFO:
		if (len < sizeof(hctx->ccid3hctx_tfrc))
			return -EINVAL;
		len = sizeof(hctx->ccid3hctx_tfrc);
		val = &hctx->ccid3hctx_tfrc;
		break;
	default:
		return -ENOPROTOOPT;
	}

	if (put_user(len, optlen) || copy_to_user(optval, val, len))
		return -EFAULT;

	return 0;
}

1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
static struct ccid ccid3 = {
	.ccid_id		   = 3,
	.ccid_name		   = "ccid3",
	.ccid_owner		   = THIS_MODULE,
	.ccid_init		   = ccid3_init,
	.ccid_exit		   = ccid3_exit,
	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
	.ccid_hc_tx_send_packet	   = ccid3_hc_tx_send_packet,
	.ccid_hc_tx_packet_sent	   = ccid3_hc_tx_packet_sent,
	.ccid_hc_tx_packet_recv	   = ccid3_hc_tx_packet_recv,
	.ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
	.ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
	.ccid_hc_rx_init	   = ccid3_hc_rx_init,
	.ccid_hc_rx_exit	   = ccid3_hc_rx_exit,
	.ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
	.ccid_hc_rx_packet_recv	   = ccid3_hc_rx_packet_recv,
1194 1195
	.ccid_hc_rx_get_info	   = ccid3_hc_rx_get_info,
	.ccid_hc_tx_get_info	   = ccid3_hc_tx_get_info,
1196 1197
	.ccid_hc_rx_getsockopt	   = ccid3_hc_rx_getsockopt,
	.ccid_hc_tx_getsockopt	   = ccid3_hc_tx_getsockopt,
1198 1199 1200 1201 1202 1203 1204
};
 
module_param(ccid3_debug, int, 0444);
MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");

static __init int ccid3_module_init(void)
{
1205
	int rc = -ENOBUFS;
1206

1207 1208
	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
	if (ccid3_rx_hist == NULL)
1209 1210
		goto out;

1211 1212 1213
	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
	if (ccid3_tx_hist == NULL)
		goto out_free_rx;
1214

1215 1216
	ccid3_li_hist = dccp_li_hist_new("ccid3");
	if (ccid3_li_hist == NULL)
1217
		goto out_free_tx;
1218 1219 1220 1221 1222 1223

	rc = ccid_register(&ccid3);
	if (rc != 0) 
		goto out_free_loss_interval_history;
out:
	return rc;
1224

1225
out_free_loss_interval_history:
1226 1227
	dccp_li_hist_delete(ccid3_li_hist);
	ccid3_li_hist = NULL;
1228 1229 1230 1231 1232 1233
out_free_tx:
	dccp_tx_hist_delete(ccid3_tx_hist);
	ccid3_tx_hist = NULL;
out_free_rx:
	dccp_rx_hist_delete(ccid3_rx_hist);
	ccid3_rx_hist = NULL;
1234 1235 1236 1237 1238 1239
	goto out;
}
module_init(ccid3_module_init);

static __exit void ccid3_module_exit(void)
{
1240 1241 1242 1243 1244 1245 1246 1247 1248
#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
	/*
	 * Hack to use while developing, so that we get rid of the control
	 * sock, that is what keeps a refcount on dccp.ko -acme
	 */
	extern void dccp_ctl_sock_exit(void);

	dccp_ctl_sock_exit();
#endif
1249 1250
	ccid_unregister(&ccid3);

1251 1252 1253
	if (ccid3_tx_hist != NULL) {
		dccp_tx_hist_delete(ccid3_tx_hist);
		ccid3_tx_hist = NULL;
1254
	}
1255 1256 1257
	if (ccid3_rx_hist != NULL) {
		dccp_rx_hist_delete(ccid3_rx_hist);
		ccid3_rx_hist = NULL;
1258
	}
1259 1260 1261
	if (ccid3_li_hist != NULL) {
		dccp_li_hist_delete(ccid3_li_hist);
		ccid3_li_hist = NULL;
1262 1263 1264 1265
	}
}
module_exit(ccid3_module_exit);

1266 1267
MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz>, "
	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
1268 1269 1270
MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
MODULE_LICENSE("GPL");
MODULE_ALIAS("net-dccp-ccid-3");