ccid3.c 37.5 KB
Newer Older
1 2 3 4
/*
 *  net/dccp/ccids/ccid3.c
 *
 *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
5
 *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.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 37 38
 *
 *  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.
 */

#include "../ccid.h"
#include "../dccp.h"
39
#include "lib/packet_history.h"
40
#include "lib/loss_interval.h"
41
#include "lib/tfrc.h"
42 43
#include "ccid3.h"

44
/*
45 46
 * Reason for maths here is to avoid 32 bit overflow when a is big.
 * With this we get close to the limit.
47
 */
48
static u32 usecs_div(const u32 a, const u32 b)
49
{
50 51 52 53 54 55 56 57 58 59 60
	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;
61 62
}

63
static int ccid3_debug;
64

65
#ifdef CCID3_DEBUG
66 67 68 69 70 71 72 73
#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

74 75
static struct dccp_tx_hist *ccid3_tx_hist;
static struct dccp_rx_hist *ccid3_rx_hist;
76
static struct dccp_li_hist *ccid3_li_hist;
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

/* 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

100 101
static void ccid3_hc_tx_set_state(struct sock *sk,
				  enum ccid3_hc_tx_states state)
102
{
103
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
104 105 106
	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
107 108
		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
		       ccid3_tx_state_name(state));
109 110 111 112 113 114 115
	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)
{
116 117 118 119 120 121 122
	/*
	 * 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);
123 124 125 126 127
}

/* 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)
{
128 129
	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
					   TFRC_OPSYS_HALF_TIME_GRAN);
130 131 132 133 134 135 136 137 138 139 140 141 142 143
}

/*
 * 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)
{
144
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
145

146 147
	/* To avoid large error in calcX */
	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
148 149 150
		hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
						     hctx->ccid3hctx_rtt,
						     hctx->ccid3hctx_p);
151 152 153 154
		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));
155 156 157
	} else {
		struct timeval now;

158
		dccp_timestamp(sk, &now);
159 160
	       	if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
		    hctx->ccid3hctx_rtt) {
161 162 163 164
			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));
165 166
			hctx->ccid3hctx_t_ld = now;
		}
167 168 169 170 171 172 173
	}
}

static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
	struct sock *sk = (struct sock *)data;
	unsigned long next_tmout = 0;
174
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
175 176 177 178 179

	bh_lock_sock(sk);
	if (sock_owned_by_user(sk)) {
		/* Try again later. */
		/* XXX: set some sensible MIB */
180 181
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + HZ / 5);
182 183 184 185 186 187 188 189 190 191 192 193
		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;
194 195
		if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s /
					 TFRC_MAX_BACK_OFF_TIME))
196 197
			hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
					     TFRC_MAX_BACK_OFF_TIME);
198

199 200 201 202
		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),
203
			       hctx->ccid3hctx_x);
204 205
		next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x),
206 207 208 209 210 211
					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
		 */
212 213
		break;
	case TFRC_SSTATE_FBACK:
214 215 216 217 218
		/*
		 * Check if IDLE since last timeout and recv rate is less than
		 * 4 packets per RTT
		 */
		if (!hctx->ccid3hctx_idle ||
219 220
		    (hctx->ccid3hctx_x_recv >=
		     4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) {
221 222
			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
				       dccp_role(sk), sk,
223 224 225 226 227 228 229 230
				       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;
			 */
231 232
			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P &&
			       hctx->ccid3hctx_x_calc == 0);
233 234 235 236 237 238 239 240 241 242 243 244

			/* 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);
		}
245 246 247 248
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
249
		next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 
250 251
					2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x));
252 253 254 255 256 257 258 259 260
		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, 
261
		      jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
262 263 264 265 266 267
	hctx->ccid3hctx_idle = 1;
out:
	bh_unlock_sock(sk);
	sock_put(sk);
}

268 269
static int ccid3_hc_tx_send_packet(struct sock *sk,
				   struct sk_buff *skb, int len)
270 271
{
	struct dccp_sock *dp = dccp_sk(sk);
272
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
273
	struct dccp_tx_hist_entry *new_packet;
274
	struct timeval now;
275
	long delay;
276 277
	int rc = -ENOTCONN;

278
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
279

280
	/* Check if pure ACK or Terminating*/
281
	/*
282 283
	 * XXX: We only call this function for DATA and DATAACK, on, these
	 * packets can have zero length, but why the comment about "pure ACK"?
284
	 */
285
	if (unlikely(len == 0))
286 287 288
		goto out;

	/* See if last packet allocated was not sent */
289 290
	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
	if (new_packet == NULL || new_packet->dccphtx_sent) {
291 292
		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
						    SLAB_ATOMIC);
293 294

		rc = -ENOBUFS;
295 296 297 298
		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);
299 300 301
			goto out;
		}

302
		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
303 304
	}

305
	dccp_timestamp(sk, &now);
306 307 308

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
309 310
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
311 312 313
		hctx->ccid3hctx_last_win_count	 = 0;
		hctx->ccid3hctx_t_last_win_count = now;
		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
314
		hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
315 316 317

		/* Set nominal send time for initial packet */
		hctx->ccid3hctx_t_nom = now;
318 319
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
320 321 322 323 324
		ccid3_calc_new_delta(hctx);
		rc = 0;
		break;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
325 326
		delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
		         hctx->ccid3hctx_delta);
327
		delay /= -1000;
328
		/* divide by -1000 is to convert to ms and get sign right */
329
		rc = delay > 0 ? delay : 0;
330 331 332 333 334 335 336 337 338 339
		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 */
340 341
	if (rc == 0) {
		dp->dccps_hc_tx_insert_options = 1;
342
		new_packet->dccphtx_ccval =
343 344
			DCCP_SKB_CB(skb)->dccpd_ccval =
				hctx->ccid3hctx_last_win_count;
I
Ian McDonald 已提交
345 346
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
347
	}
348 349 350 351 352 353
out:
	return rc;
}

static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
{
354 355
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
356 357
	struct timeval now;

358
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
359

360
	dccp_timestamp(sk, &now);
361 362 363 364

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

367
		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
368 369 370
		if (unlikely(packet == NULL)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
				       "exists in history!\n", __FUNCTION__);
371 372
			return;
		}
373 374 375
		if (unlikely(packet->dccphtx_sent)) {
			LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
				       "history!\n", __FUNCTION__);
376 377
			return;
		}
378 379
		packet->dccphtx_tstamp = now;
		packet->dccphtx_seqno  = dp->dccps_gss;
380
		/*
381 382 383
		 * Check if win_count have changed
		 * Algorithm in "8.1. Window Counter Valuer" in
		 * draft-ietf-dccp-ccid3-11.txt
384
		 */
385 386 387 388
		quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
		if (likely(hctx->ccid3hctx_rtt > 8))
			quarter_rtt /= hctx->ccid3hctx_rtt / 4;

389 390 391 392
		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;
393 394
			ccid3_pr_debug("%s, sk=%p, window changed from "
				       "%u to %u!\n",
395
				       dccp_role(sk), sk,
396
				       packet->dccphtx_ccval,
397 398
				       hctx->ccid3hctx_last_win_count);
		}
399

400
		hctx->ccid3hctx_idle = 0;
401
		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
402
		packet->dccphtx_sent = 1;
403 404 405 406 407 408 409 410
	} 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)
411 412
			printk(KERN_CRIT "%s: %s, First packet sent is noted "
					 "as a data packet\n",
413 414 415 416 417
			       __FUNCTION__, dccp_role(sk));
		return;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
		if (len > 0) {
I
Ian McDonald 已提交
418 419
			timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
420 421
			ccid3_calc_new_t_ipi(hctx);
			ccid3_calc_new_delta(hctx);
422 423
			timeval_add_usecs(&hctx->ccid3hctx_t_nom,
					  hctx->ccid3hctx_t_ipi);
424 425 426 427 428 429 430 431 432 433 434 435
		}
		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)
{
436 437
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
438
	struct ccid3_options_received *opt_recv;
439
	struct dccp_tx_hist_entry *packet;
440
	struct timeval now;
441
	unsigned long next_tmout; 
I
Ian McDonald 已提交
442
	u32 t_elapsed;
443 444 445
	u32 pinv;
	u32 x_recv;
	u32 r_sample;
446

447
	BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
448 449 450 451 452 453 454 455

	/* 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;

456
	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
457 458 459 460 461 462 463 464 465 466 467 468
	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 */
469 470
		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
471 472 473 474 475 476
		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));
477 478 479 480
			return;
		}

		/* Update RTT */
481 482
		dccp_timestamp(sk, &now);
		r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
483
		if (unlikely(r_sample <= t_elapsed))
484 485
			LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
				       "t_elapsed=%uus\n",
486 487 488
				       __FUNCTION__, r_sample, t_elapsed);
		else
			r_sample -= t_elapsed;
489 490 491 492 493 494 495 496 497 498 499 500 501

		/* 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
502 503
			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
					      r_sample / 10;
504

505 506 507
		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
			       "r_sample=%us\n", dccp_role(sk), sk,
			       hctx->ccid3hctx_rtt, r_sample);
508 509

		/* Update timeout interval */
510 511
		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
					      USEC_PER_SEC);
512 513

		/* Update receive rate */
514
		hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
515 516 517 518 519 520 521 522 523

		/* 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;
524 525
				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n",
					       dccp_role(sk), sk);
526 527 528 529 530 531 532 533 534 535
			}
		}

		/* 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 */
536 537
		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
538
		ccid3_calc_new_t_ipi(hctx);
539 540
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
541 542 543
		ccid3_calc_new_delta(hctx);

		/* remove all packets older than the one acked from history */
544 545
		dccp_tx_hist_purge_older(ccid3_tx_hist,
					 &hctx->ccid3hctx_hist, packet);
546 547 548 549 550
		/*
		 * 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);
551

552 553 554 555
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
556
		next_tmout = max(hctx->ccid3hctx_t_rto,
557 558 559
				 2 * usecs_div(hctx->ccid3hctx_s,
					       hctx->ccid3hctx_x));
			
560 561 562 563
		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); 
564 565

		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
566
			       jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
567 568 569 570 571 572 573 574 575 576 577 578

		/* 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;
	}
}

579
static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
580
{
581
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
582

583 584
	BUG_ON(hctx == NULL);

585 586 587
	if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
		DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
	return 0;
588 589 590
}

static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
591 592
				     unsigned char len, u16 idx,
				     unsigned char *value)
593 594
{
	int rc = 0;
595 596
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
597 598
	struct ccid3_options_received *opt_recv;

599
	BUG_ON(hctx == NULL);
600 601 602 603 604 605 606 607 608 609 610 611 612

	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:
613 614 615 616
		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);
617 618
			rc = -EINVAL;
		} else {
619
			opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
620 621 622 623 624 625 626 627 628 629 630 631 632 633
			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:
634 635 636 637
		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);
638 639
			rc = -EINVAL;
		} else {
640
			opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
641 642 643 644 645 646 647 648 649 650
			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
				       dccp_role(sk), sk,
				       opt_recv->ccid3or_receive_rate);
		}
		break;
	}

	return rc;
}

651
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
652 653
{
	struct dccp_sock *dp = dccp_sk(sk);
654
	struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
655

656 657 658
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hctx->ccid3hctx_s = dp->dccps_packet_size;
659 660 661
	else
		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;

662 663
	/* Set transmission rate to 1 packet per second */
	hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
664
	hctx->ccid3hctx_t_rto = USEC_PER_SEC;
665 666
	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
667 668 669

	hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
	hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
670 671 672 673 674 675 676
	init_timer(&hctx->ccid3hctx_no_feedback_timer);

	return 0;
}

static void ccid3_hc_tx_exit(struct sock *sk)
{
677
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
678 679 680 681 682 683 684

	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 */
685
	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
}

/*
 * 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

712 713
static void ccid3_hc_rx_set_state(struct sock *sk,
				  enum ccid3_hc_rx_states state)
714
{
715
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
716 717 718
	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
719 720
		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
		       ccid3_rx_state_name(state));
721 722 723 724 725 726
	WARN_ON(state == oldstate);
	hcrx->ccid3hcrx_state = state;
}

static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
727
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
728
	struct dccp_sock *dp = dccp_sk(sk);
729
	struct dccp_rx_hist_entry *packet;
730
	struct timeval now;
731 732 733

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

734
	dccp_timestamp(sk, &now);
735

736 737 738 739 740
	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
		hcrx->ccid3hcrx_x_recv = 0;
		break;
	case TFRC_RSTATE_DATA: {
741 742
		const u32 delta = timeval_delta(&now,
					&hcrx->ccid3hcrx_tstamp_last_feedback);
743 744
		hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
						   delta);
745 746 747 748 749 750 751 752 753
	}
		break;
	default:
		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
		dump_stack();
		return;
	}

754
	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
755 756 757 758
	if (unlikely(packet == NULL)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet "
			       "in history!\n",
			       __FUNCTION__, dccp_role(sk), sk);
759 760 761
		return;
	}

762
	hcrx->ccid3hcrx_tstamp_last_feedback = now;
I
Ian McDonald 已提交
763
	hcrx->ccid3hcrx_ccval_last_counter   = packet->dccphrx_ccval;
764 765 766
	hcrx->ccid3hcrx_bytes_recv	     = 0;

	/* Convert to multiples of 10us */
767 768
	hcrx->ccid3hcrx_elapsed_time =
			timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
769 770 771 772
	if (hcrx->ccid3hcrx_p == 0)
		hcrx->ccid3hcrx_pinv = ~0;
	else
		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
773
	dp->dccps_hc_rx_insert_options = 1;
774 775 776
	dccp_send_ack(sk);
}

777
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
778
{
779
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
780
	__be32 x_recv, pinv;
781

782 783 784
	BUG_ON(hcrx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
785
		return 0;
786

I
Ian McDonald 已提交
787
	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
788 789

	if (dccp_packet_without_ack(skb))
790 791
		return 0;

792 793
	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
	pinv   = htonl(hcrx->ccid3hcrx_pinv);
794 795 796 797 798 799 800 801 802 803 804 805

	if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
	     dccp_insert_option_elapsed_time(sk, skb,
					     hcrx->ccid3hcrx_elapsed_time)) ||
	    dccp_insert_option_timestamp(sk, skb) ||
	    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)))
		return -1;

	return 0;
806 807 808 809 810 811 812 813
}

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

static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
814
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
815
	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
816
	u32 rtt, delta, x_recv, fval, p, tmp2;
817
	struct timeval tstamp = { 0, };
818 819 820 821 822
	int interval = 0;
	int win_count = 0;
	int step = 0;
	u64 tmp1;

823 824 825
	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
				 dccphrx_node) {
		if (dccp_rx_hist_entry_data_packet(entry)) {
826 827 828 829
			tail = entry;

			switch (step) {
			case 0:
830
				tstamp	  = entry->dccphrx_tstamp;
831
				win_count = entry->dccphrx_ccval;
832 833 834
				step = 1;
				break;
			case 1:
835
				interval = win_count - entry->dccphrx_ccval;
836 837 838 839 840 841 842 843 844
				if (interval < 0)
					interval += TFRC_WIN_COUNT_LIMIT;
				if (interval > 4)
					goto found;
				break;
			}
		}
	}

845 846 847 848
	if (unlikely(step == 0)) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history "
			       "contains no data packets!\n",
			       __FUNCTION__, dccp_role(sk), sk);
849 850 851
		return ~0;
	}

852 853 854 855
	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);
856 857 858
		interval = 1;
	}
found:
I
Ian McDonald 已提交
859 860 861 862 863
	if (!tail) {
		LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n",
		   __FUNCTION__);
		return ~0;
	}
864
	rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
865 866 867 868 869
	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
		       dccp_role(sk), sk, rtt);
	if (rtt == 0)
		rtt = 1;

870 871 872
	dccp_timestamp(sk, &tstamp);
	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
	x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
873

I
Ian McDonald 已提交
874 875 876
	if (x_recv == 0)
		x_recv = hcrx->ccid3hcrx_x_recv;

877 878 879
	tmp1 = (u64)x_recv * (u64)rtt;
	do_div(tmp1,10000000);
	tmp2 = (u32)tmp1;
I
Ian McDonald 已提交
880 881 882 883 884 885 886 887

	if (!tmp2) {
		LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 "
		   "%s: x_recv = %u, rtt =%u\n",
		   __FUNCTION__, x_recv, rtt);
		return ~0;
	}

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

	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)
{
902
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
I
Ian McDonald 已提交
903 904
	struct dccp_li_hist_entry *next, *head;
	u64 seq_temp;
905

I
Ian McDonald 已提交
906 907 908 909
	if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
		if (!dccp_li_hist_interval_new(ccid3_li_hist,
		   &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
			return;
910

I
Ian McDonald 已提交
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
		next = (struct dccp_li_hist_entry *)
		   hcrx->ccid3hcrx_li_hist.next;
		next->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
	} else {
		struct dccp_li_hist_entry *entry;
		struct list_head *tail;

		head = (struct dccp_li_hist_entry *)
		   hcrx->ccid3hcrx_li_hist.next;
		/* FIXME win count check removed as was wrong */
		/* should make this check with receive history */
		/* and compare there as per section 10.2 of RFC4342 */

		/* new loss event detected */
		/* calculate last interval length */
		seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
		entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC);

		if (entry == NULL) {
			printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__);
			dump_stack();
932
			return;
I
Ian McDonald 已提交
933 934 935 936 937 938 939 940 941 942 943 944 945
		}

		list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);

		tail = hcrx->ccid3hcrx_li_hist.prev;
		list_del(tail);
		kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);

		/* Create the newest interval */
		entry->dccplih_seqno = seq_loss;
		entry->dccplih_interval = seq_temp;
		entry->dccplih_win_count = win_loss;
	}
946 947
}

I
Ian McDonald 已提交
948 949
static int ccid3_hc_rx_detect_loss(struct sock *sk,
                                    struct dccp_rx_hist_entry *packet)
950
{
951
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
I
Ian McDonald 已提交
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
	struct dccp_rx_hist_entry *rx_hist = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
	u64 seqno = packet->dccphrx_seqno;
	u64 tmp_seqno;
	int loss = 0;
	u8 ccval;


	tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;

	if (!rx_hist ||
	   follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
		hcrx->ccid3hcrx_seqno_nonloss = seqno;
		hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
		goto detect_out;
	}

968

I
Ian McDonald 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
	while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
	   > TFRC_RECV_NUM_LATE_LOSS) {
		loss = 1;
		ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss,
		   hcrx->ccid3hcrx_ccval_nonloss);
		tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
		dccp_inc_seqno(&tmp_seqno);
		hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
		dccp_inc_seqno(&tmp_seqno);
		while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist,
		   tmp_seqno, &ccval)) {
		   	hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
			hcrx->ccid3hcrx_ccval_nonloss = ccval;
			dccp_inc_seqno(&tmp_seqno);
		}
	}

	/* FIXME - this code could be simplified with above while */
	/* but works at moment */
	if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
		hcrx->ccid3hcrx_seqno_nonloss = seqno;
		hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
	}

detect_out:
	dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
		   &hcrx->ccid3hcrx_li_hist, packet,
		   hcrx->ccid3hcrx_seqno_nonloss);
	return loss;
998 999 1000 1001
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
1002
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1003
	const struct dccp_options_received *opt_recv;
1004
	struct dccp_rx_hist_entry *packet;
1005 1006
	struct timeval now;
	u8 win_count;
I
Ian McDonald 已提交
1007 1008
	u32 p_prev, rtt_prev, r_sample, t_elapsed;
	int loss;
1009

1010 1011
	BUG_ON(hcrx == NULL ||
	       !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
1012 1013
		 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));

1014
	opt_recv = &dccp_sk(sk)->dccps_options_received;
1015

1016 1017 1018 1019 1020
	switch (DCCP_SKB_CB(skb)->dccpd_type) {
	case DCCP_PKT_ACK:
		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			return;
	case DCCP_PKT_DATAACK:
1021
		if (opt_recv->dccpor_timestamp_echo == 0)
1022
			break;
I
Ian McDonald 已提交
1023
		rtt_prev = hcrx->ccid3hcrx_rtt;
1024
		dccp_timestamp(sk, &now);
1025 1026 1027 1028 1029
		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))
1030 1031
			LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
				       "t_elapsed=%uus\n",
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
				       __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;

I
Ian McDonald 已提交
1042 1043
		if (rtt_prev != hcrx->ccid3hcrx_rtt)
			ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n",
1044 1045
				       dccp_role(sk), hcrx->ccid3hcrx_rtt,
				       opt_recv->dccpor_elapsed_time);
1046 1047 1048
		break;
	case DCCP_PKT_DATA:
		break;
1049
	default: /* We're not interested in other packet types, move along */
1050 1051 1052
		return;
	}

1053
	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
1054
					skb, SLAB_ATOMIC);
1055 1056 1057 1058
	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);
1059 1060 1061
		return;
	}

1062
	win_count = packet->dccphrx_ccval;
1063

I
Ian McDonald 已提交
1064
	loss = ccid3_hc_rx_detect_loss(sk, packet);
1065 1066 1067 1068 1069 1070

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

	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
1071 1072 1073 1074
		ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
			       "feedback\n",
			       dccp_role(sk), sk,
			       dccp_state_name(sk->sk_state), skb);
1075 1076 1077 1078
		ccid3_hc_rx_send_feedback(sk);
		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
		return;
	case TFRC_RSTATE_DATA:
1079 1080
		hcrx->ccid3hcrx_bytes_recv += skb->len -
					      dccp_hdr(skb)->dccph_doff * 4;
I
Ian McDonald 已提交
1081
		if (loss)
1082 1083
			break;

1084
		dccp_timestamp(sk, &now);
1085 1086 1087 1088
		if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
		    hcrx->ccid3hcrx_rtt) {
			hcrx->ccid3hcrx_tstamp_last_ack = now;
			ccid3_hc_rx_send_feedback(sk);
1089
		}
1090
		return;
1091 1092 1093 1094 1095 1096 1097 1098
	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 */
1099 1100
	ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1101 1102 1103 1104

	p_prev = hcrx->ccid3hcrx_p;
	
	/* Calculate loss event rate */
I
Ian McDonald 已提交
1105 1106 1107
	if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
		u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);

1108
		/* Scaling up by 1000000 as fixed decimal */
I
Ian McDonald 已提交
1109 1110
		if (i_mean != 0)
			hcrx->ccid3hcrx_p = 1000000 / i_mean;
I
Ian McDonald 已提交
1111 1112 1113
	} else {
		printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__);
		dump_stack();
I
Ian McDonald 已提交
1114
	}
1115 1116 1117 1118 1119 1120 1121

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

1122
static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1123 1124
{
	struct dccp_sock *dp = dccp_sk(sk);
1125
	struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1126 1127 1128

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

1129 1130 1131
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1132 1133 1134 1135 1136
	else
		hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;

	hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1137
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1138
	dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1139 1140
	hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
	hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1141 1142 1143 1144 1145
	return 0;
}

static void ccid3_hc_rx_exit(struct sock *sk)
{
1146
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1147

1148
	BUG_ON(hcrx == NULL);
1149 1150 1151 1152

	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

	/* Empty packet history */
1153
	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1154 1155

	/* Empty loss interval history */
1156
	dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1157 1158
}

1159 1160
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
1161
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1162

1163 1164 1165 1166
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return;

1167
	BUG_ON(hcrx == NULL);
1168 1169 1170 1171 1172 1173 1174 1175

	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)
{
1176
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
1177

1178 1179 1180 1181
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return;

1182
	BUG_ON(hctx == NULL);
1183 1184 1185 1186 1187

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

1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
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;
}

1242
static struct ccid_operations ccid3 = {
1243 1244 1245
	.ccid_id		   = 3,
	.ccid_name		   = "ccid3",
	.ccid_owner		   = THIS_MODULE,
1246
	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
1247 1248 1249 1250 1251 1252 1253
	.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,
1254
	.ccid_hc_rx_obj_size	   = sizeof(struct ccid3_hc_rx_sock),
1255 1256 1257 1258
	.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,
1259 1260
	.ccid_hc_rx_get_info	   = ccid3_hc_rx_get_info,
	.ccid_hc_tx_get_info	   = ccid3_hc_tx_get_info,
1261 1262
	.ccid_hc_rx_getsockopt	   = ccid3_hc_rx_getsockopt,
	.ccid_hc_tx_getsockopt	   = ccid3_hc_tx_getsockopt,
1263 1264 1265 1266 1267 1268 1269
};
 
module_param(ccid3_debug, int, 0444);
MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");

static __init int ccid3_module_init(void)
{
1270
	int rc = -ENOBUFS;
1271

1272 1273
	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
	if (ccid3_rx_hist == NULL)
1274 1275
		goto out;

1276 1277 1278
	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
	if (ccid3_tx_hist == NULL)
		goto out_free_rx;
1279

1280 1281
	ccid3_li_hist = dccp_li_hist_new("ccid3");
	if (ccid3_li_hist == NULL)
1282
		goto out_free_tx;
1283 1284 1285 1286 1287 1288

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

1290
out_free_loss_interval_history:
1291 1292
	dccp_li_hist_delete(ccid3_li_hist);
	ccid3_li_hist = NULL;
1293 1294 1295 1296 1297 1298
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;
1299 1300 1301 1302 1303 1304 1305 1306
	goto out;
}
module_init(ccid3_module_init);

static __exit void ccid3_module_exit(void)
{
	ccid_unregister(&ccid3);

1307 1308 1309
	if (ccid3_tx_hist != NULL) {
		dccp_tx_hist_delete(ccid3_tx_hist);
		ccid3_tx_hist = NULL;
1310
	}
1311 1312 1313
	if (ccid3_rx_hist != NULL) {
		dccp_rx_hist_delete(ccid3_rx_hist);
		ccid3_rx_hist = NULL;
1314
	}
1315 1316 1317
	if (ccid3_li_hist != NULL) {
		dccp_li_hist_delete(ccid3_li_hist);
		ccid3_li_hist = NULL;
1318 1319 1320 1321
	}
}
module_exit(ccid3_module_exit);

1322
MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
1323
	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
1324 1325 1326
MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
MODULE_LICENSE("GPL");
MODULE_ALIAS("net-dccp-ccid-3");