ccid3.c 36.7 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
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
static int ccid3_debug;
#define ccid3_pr_debug(format, a...)	DCCP_PR_DEBUG(ccid3_debug, format, ##a)
47 48 49 50
#else
#define ccid3_pr_debug(format, a...)
#endif

51 52
static struct dccp_tx_hist *ccid3_tx_hist;
static struct dccp_rx_hist *ccid3_rx_hist;
53
static struct dccp_li_hist *ccid3_li_hist;
54

55
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
56 57 58 59 60 61 62 63 64 65 66 67 68
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

69 70
static void ccid3_hc_tx_set_state(struct sock *sk,
				  enum ccid3_hc_tx_states state)
71
{
72
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
73 74 75
	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
76 77
		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
		       ccid3_tx_state_name(state));
78 79 80 81
	WARN_ON(state == oldstate);
	hctx->ccid3hctx_state = state;
}

82 83 84 85 86
/*
 * Recalculate scheduled nominal send time t_nom, inter-packet interval
 * t_ipi, and delta value. Should be called after each change to X.
 */
static inline void ccid3_update_send_time(struct ccid3_hc_tx_sock *hctx)
87
{
88 89
	timeval_sub_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);

90 91 92
	/* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
	hctx->ccid3hctx_t_ipi = scaled_div(hctx->ccid3hctx_s,
					   hctx->ccid3hctx_x >> 6);
93

94 95 96 97
	/* Update nominal send time with regard to the new t_ipi */
	timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);

	/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
98 99
	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
					   TFRC_OPSYS_HALF_TIME_GRAN);
100 101 102 103
}
/*
 * Update X by
 *    If (p > 0)
104
 *       X_calc = calcX(s, R, p);
105 106 107 108 109
 *       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;
110
 *
111 112 113 114
 * Note: X and X_recv are both stored in units of 64 * bytes/second, to support
 *       fine-grained resolution of sending rates. This requires scaling by 2^6
 *       throughout the code. Only X_calc is unscaled (in bytes/second).
 *
115 116
 * If X has changed, we also update the scheduled send time t_now,
 * the inter-packet interval t_ipi, and the delta value.
117
 */
118 119
static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now)

120
{
121
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
122
	const  __u64 old_x = hctx->ccid3hctx_x;
123

124
	if (hctx->ccid3hctx_p > 0) {
125

126 127 128 129 130
		hctx->ccid3hctx_x = min(((__u64)hctx->ccid3hctx_x_calc) << 6,
					hctx->ccid3hctx_x_recv * 2           );
		hctx->ccid3hctx_x = max(hctx->ccid3hctx_x,
					(((__u64)hctx->ccid3hctx_s) << 6) /
					 			   TFRC_T_MBI);
131

G
Gerrit Renker 已提交
132 133
	} else if (timeval_delta(now, &hctx->ccid3hctx_t_ld) -
			(suseconds_t)hctx->ccid3hctx_rtt >= 0 ) {
134

135 136 137 138
		hctx->ccid3hctx_x =
			max(2 * min(hctx->ccid3hctx_x, hctx->ccid3hctx_x_recv),
			    scaled_div(((__u64)hctx->ccid3hctx_s) << 6,
				       hctx->ccid3hctx_rtt             )      );
139
		hctx->ccid3hctx_t_ld = *now;
140
	}
141

142 143
	if (hctx->ccid3hctx_x != old_x)
		ccid3_update_send_time(hctx);
144 145
}

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/*
 * 	Track the mean packet size `s' (cf. RFC 4342, 5.3 and  RFC 3448, 4.1)
 * 	@len: DCCP packet payload size in bytes
 */
static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
{
	if (unlikely(len == 0))
		ccid3_pr_debug("Packet payload length is 0 - not updating\n");
	else
		hctx->ccid3hctx_s = hctx->ccid3hctx_s == 0 ? len :
				    (9 * hctx->ccid3hctx_s + len) / 10;
	/*
	 * Note: We could do a potential optimisation here - when `s' changes,
	 *	 recalculate sending rate and consequently t_ipi, t_delta, and
	 *	 t_now. This is however non-standard, and the benefits are not
	 *	 clear, so it is currently left out.
	 */
}

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
/*
 * 	Update Window Counter using the algorithm from [RFC 4342, 8.1].
 * 	The algorithm is not applicable if RTT < 4 microseconds.
 */
static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
						struct timeval *now)
{
	suseconds_t delta;
	u32 quarter_rtts;

	if (unlikely(hctx->ccid3hctx_rtt < 4))	/* avoid divide-by-zero */
		return;

	delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count);
	DCCP_BUG_ON(delta < 0);

	quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);

	if (quarter_rtts > 0) {
		hctx->ccid3hctx_t_last_win_count = *now;
		hctx->ccid3hctx_last_win_count	+= min_t(u32, quarter_rtts, 5);
		hctx->ccid3hctx_last_win_count	&= 0xF;		/* mod 16 */

		ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
	}
}

192 193 194
static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
	struct sock *sk = (struct sock *)data;
195
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
196
	unsigned long t_nfb = USEC_PER_SEC / 5;
197 198 199 200 201

	bh_lock_sock(sk);
	if (sock_owned_by_user(sk)) {
		/* Try again later. */
		/* XXX: set some sensible MIB */
202
		goto restart_timer;
203 204
	}

205
	ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
206
		       ccid3_tx_state_name(hctx->ccid3hctx_state));
207

208 209
	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_FBACK:
210
		/* RFC 3448, 4.4: Halve send rate directly */
211 212 213
		hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
					(((__u64)hctx->ccid3hctx_s) << 6) /
								    TFRC_T_MBI);
214

215 216
		ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
			       "bytes/s\n", dccp_role(sk), sk,
217
			       ccid3_tx_state_name(hctx->ccid3hctx_state),
218
			       (unsigned)(hctx->ccid3hctx_x >> 6));
219 220
		/* The value of R is still undefined and so we can not recompute
		 * the timout value. Keep initial value as per [RFC 4342, 5]. */
221
		t_nfb = TFRC_INITIAL_TIMEOUT;
222
		ccid3_update_send_time(hctx);
223 224
		break;
	case TFRC_SSTATE_FBACK:
225 226
		/*
		 * Check if IDLE since last timeout and recv rate is less than
227
		 * 4 packets (in units of 64*bytes/sec) per RTT
228 229
		 */
		if (!hctx->ccid3hctx_idle ||
230
		    (hctx->ccid3hctx_x_recv >= 4 *
231
		     scaled_div(((__u64)hctx->ccid3hctx_s) << 6, hctx->ccid3hctx_rtt))) {
232 233
			struct timeval now;

234
			ccid3_pr_debug("%s(%p, state=%s), not idle\n",
235
				       dccp_role(sk), sk,
236 237
				       ccid3_tx_state_name(hctx->ccid3hctx_state));

238 239 240 241
			/*
			 *  Modify the cached value of X_recv [RFC 3448, 4.4]
			 *
			 *  If (p == 0 || X_calc > 2 * X_recv)
242 243 244
			 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
			 *  Else
			 *    X_recv = X_calc / 4;
245 246
			 *
			 *  Note that X_recv is scaled by 2^6 while X_calc is not
247
			 */
248
			BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
249

250
			if (hctx->ccid3hctx_p  == 0 ||
251 252 253
			    hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))  {

				hctx->ccid3hctx_x_recv =
254 255
					max(hctx->ccid3hctx_x_recv / 2,
					    (((__u64)hctx->ccid3hctx_s) << 6) /
256 257
					      			(2*TFRC_T_MBI));

258 259
				if (hctx->ccid3hctx_p == 0)
					dccp_timestamp(sk, &now);
260 261 262 263
			} else {
				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
				hctx->ccid3hctx_x_recv <<= 4;
			}
264
			/* Now recalculate X [RFC 3448, 4.3, step (4)] */
265
			ccid3_hc_tx_update_x(sk, &now);
266
		}
267 268
		/*
		 * Schedule no feedback timer to expire in
269 270
		 * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
		 * See comments in packet_recv() regarding the value of t_RTO.
271
		 */
272
		t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
273
		break;
274
	case TFRC_SSTATE_NO_SENT:
275
		DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
276 277
		/* fall through */
	case TFRC_SSTATE_TERM:
278 279 280 281
		goto out;
	}

	hctx->ccid3hctx_idle = 1;
282 283 284

restart_timer:
	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
285
		           jiffies + usecs_to_jiffies(t_nfb));
286 287 288 289 290
out:
	bh_unlock_sock(sk);
	sock_put(sk);
}

291 292 293 294 295 296
/*
 * returns
 *   > 0: delay (in msecs) that should pass before actually sending
 *   = 0: can send immediately
 *   < 0: error condition; do not send packet
 */
297
static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
298 299
{
	struct dccp_sock *dp = dccp_sk(sk);
300
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
301
	struct timeval now;
G
Gerrit Renker 已提交
302
	suseconds_t delay;
303

304
	BUG_ON(hctx == NULL);
305

306
	/*
307 308 309
	 * This function is called only for Data and DataAck packets. Sending
	 * zero-sized Data(Ack)s is theoretically possible, but for congestion
	 * control this case is pathological - ignore it.
310
	 */
311
	if (unlikely(skb->len == 0))
312
		return -EBADMSG;
313

314
	dccp_timestamp(sk, &now);
315 316 317

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
318 319
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
320 321 322 323
		hctx->ccid3hctx_last_win_count	 = 0;
		hctx->ccid3hctx_t_last_win_count = now;
		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);

324
		/* Set initial sending rate X/s to 1pps (X is scaled by 2^6) */
325
		ccid3_hc_tx_update_s(hctx, skb->len);
326 327
		hctx->ccid3hctx_x = hctx->ccid3hctx_s;
		hctx->ccid3hctx_x <<= 6;
328

329 330 331 332 333 334
		/* First timeout, according to [RFC 3448, 4.2], is 1 second */
		hctx->ccid3hctx_t_ipi = USEC_PER_SEC;
		/* Initial delta: minimum of 0.5 sec and t_gran/2 */
		hctx->ccid3hctx_delta = TFRC_OPSYS_HALF_TIME_GRAN;

		/* Set t_0 for initial packet */
335 336 337 338
		hctx->ccid3hctx_t_nom = now;
		break;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
339 340 341 342 343 344 345 346 347
		delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
		/*
		 * 	Scheduling of packet transmissions [RFC 3448, 4.6]
		 *
		 * if (t_now > t_nom - delta)
		 *       // send the packet now
		 * else
		 *       // send the packet in (t_nom - t_now) milliseconds.
		 */
G
Gerrit Renker 已提交
348
		if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
349
			return delay / 1000L;
350 351

		ccid3_hc_tx_update_win_count(hctx, &now);
352
		break;
353
	case TFRC_SSTATE_TERM:
354
		DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
355
		return -EINVAL;
356 357
	}

358 359
	/* prepare to send now (add options etc.) */
	dp->dccps_hc_tx_insert_options = 1;
360 361 362
	DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;

	/* set the nominal send time for the next following packet */
363 364 365
	timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);

	return 0;
366 367
}

368
static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
369
{
370
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
371
	struct timeval now;
372
	struct dccp_tx_hist_entry *packet;
373

374
	BUG_ON(hctx == NULL);
375

376
	ccid3_hc_tx_update_s(hctx, len);
377

378
	packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC);
379
	if (unlikely(packet == NULL)) {
380
		DCCP_CRIT("packet history - out of memory!");
381 382
		return;
	}
383 384 385
	dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet);

	dccp_timestamp(sk, &now);
386
	packet->dccphtx_tstamp = now;
387 388 389 390
	packet->dccphtx_seqno  = dccp_sk(sk)->dccps_gss;
	packet->dccphtx_rtt    = hctx->ccid3hctx_rtt;
	packet->dccphtx_sent   = 1;
	hctx->ccid3hctx_idle   = 0;
391 392 393 394
}

static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
395 396
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
397
	struct ccid3_options_received *opt_recv;
398
	struct dccp_tx_hist_entry *packet;
399
	struct timeval now;
400
	unsigned long t_nfb;
401
	u32 pinv;
402
	long r_sample, t_elapsed;
403

404
	BUG_ON(hctx == NULL);
405 406 407 408 409 410 411 412 413 414 415

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

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
416
		/* get packet from history to look up t_recvdata */
417 418
		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
419
		if (unlikely(packet == NULL)) {
420
			DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist "
421
				  "in history!\n",  dccp_role(sk), sk,
422
			    (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
423
				  dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
424 425 426
			return;
		}

427
		/* Update receive rate in units of 64 * bytes/second */
428 429
		hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
		hctx->ccid3hctx_x_recv <<= 6;
430 431 432

		/* Update loss event rate */
		pinv = opt_recv->ccid3or_loss_event_rate;
433
		if (pinv == ~0U || pinv == 0)	       /* see RFC 4342, 8.5   */
434
			hctx->ccid3hctx_p = 0;
435
		else				       /* can not exceed 100% */
436
 			hctx->ccid3hctx_p = 1000000 / pinv;
437

438
		dccp_timestamp(sk, &now);
439 440 441 442 443 444 445 446

		/*
		 * Calculate new round trip sample as per [RFC 3448, 4.3] by
		 * 	R_sample  =  (now - t_recvdata) - t_elapsed
		 */
		r_sample  = timeval_delta(&now, &packet->dccphtx_tstamp);
		t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;

G
Gerrit Renker 已提交
447 448
		DCCP_BUG_ON(r_sample < 0);
		if (unlikely(r_sample <= t_elapsed))
449
			DCCP_WARN("WARNING: r_sample=%ldus <= t_elapsed=%ldus\n",
450
				  r_sample, t_elapsed);
451 452
		else
			r_sample -= t_elapsed;
453
		CCID3_RTT_SANITY_CHECK(r_sample);
454

455
		/* Update RTT estimate by
456 457 458 459 460 461 462 463
		 * 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) {
464 465 466 467
			/*
			 * Larger Initial Windows [RFC 4342, sec. 5]
			 * We deviate in that we use `s' instead of `MSS'.
			 */
468 469
			__u64 w_init = min(    4 * hctx->ccid3hctx_s,
					   max(2 * hctx->ccid3hctx_s, 4380));
470
			hctx->ccid3hctx_rtt  = r_sample;
471
			hctx->ccid3hctx_x    = scaled_div(w_init << 6, r_sample);
472 473 474
			hctx->ccid3hctx_t_ld = now;

			ccid3_update_send_time(hctx);
475

476
			ccid3_pr_debug("%s(%p), s=%u, w_init=%llu, "
477 478
				       "R_sample=%ldus, X=%u\n", dccp_role(sk),
				       sk, hctx->ccid3hctx_s, w_init, r_sample,
479
				       (unsigned)(hctx->ccid3hctx_x >> 6));
480

481 482 483 484
			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
		} else {
			hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
					           (u32)r_sample        ) / 10;
485

486 487 488 489 490 491
			/* Update sending rate (step 4 of [RFC 3448, 4.3]) */
			if (hctx->ccid3hctx_p > 0)
				hctx->ccid3hctx_x_calc =
					tfrc_calc_x(hctx->ccid3hctx_s,
						    hctx->ccid3hctx_rtt,
						    hctx->ccid3hctx_p);
492
			ccid3_hc_tx_update_x(sk, &now);
493

494
			ccid3_pr_debug("%s(%p), RTT=%uus (sample=%ldus), s=%u, "
495
				       "p=%u, X_calc=%u, X_recv=%u, X=%u\n", dccp_role(sk),
496 497 498
				       sk, hctx->ccid3hctx_rtt, r_sample,
				       hctx->ccid3hctx_s, hctx->ccid3hctx_p,
				       hctx->ccid3hctx_x_calc,
499 500
				       (unsigned)(hctx->ccid3hctx_x_recv >> 6),
				       (unsigned)(hctx->ccid3hctx_x >> 6)     );
501 502 503 504 505 506
		}

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

		/* remove all packets older than the one acked from history */
507 508
		dccp_tx_hist_purge_older(ccid3_tx_hist,
					 &hctx->ccid3hctx_hist, packet);
509 510
		/*
		 * As we have calculated new ipi, delta, t_nom it is possible that
511
		 * we now can send a packet, so wake up dccp_wait_for_ccid
512 513
		 */
		sk->sk_write_space(sk);
514

515 516 517 518 519 520
		/*
		 * Update timeout interval for the nofeedback timer.
		 * We use a configuration option to increase the lower bound.
		 * This can help avoid triggering the nofeedback timer too often
		 * ('spinning') on LANs with small RTTs.
		 */
521
		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
522 523
						   CONFIG_IP_DCCP_CCID3_RTO *
						   (USEC_PER_SEC/1000)	     );
524 525
		/*
		 * Schedule no feedback timer to expire in
526
		 * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
527
		 */
528
		t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
529

530 531 532 533 534
		ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
			       "expire in %lu jiffies (%luus)\n", dccp_role(sk),
			       sk, usecs_to_jiffies(t_nfb), t_nfb);

		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
535
				   jiffies + usecs_to_jiffies(t_nfb));
536 537

		/* set idle flag */
538
		hctx->ccid3hctx_idle = 1;
539
		break;
G
Gerrit Renker 已提交
540
	case TFRC_SSTATE_NO_SENT:
541 542
		/* XXX when implementing bidirectional rx/tx check this again */
		DCCP_WARN("Illegal ACK received - no packet sent\n");
G
Gerrit Renker 已提交
543 544
		/* fall through */
	case TFRC_SSTATE_TERM:		/* ignore feedback when closing */
545 546 547 548 549
		break;
	}
}

static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
550 551
				     unsigned char len, u16 idx,
				     unsigned char *value)
552 553
{
	int rc = 0;
554 555
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
556 557
	struct ccid3_options_received *opt_recv;

558
	BUG_ON(hctx == NULL);
559 560 561 562 563 564 565 566 567 568 569 570 571

	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:
572
		if (unlikely(len != 4)) {
573
			DCCP_WARN("%s(%p), invalid len %d "
574 575
				  "for TFRC_OPT_LOSS_EVENT_RATE\n",
				  dccp_role(sk), sk, len);
576 577
			rc = -EINVAL;
		} else {
578
			opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
579
			ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
580 581 582 583 584 585 586
				       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;
587
		ccid3_pr_debug("%s(%p), LOSS_INTERVALS=(%u, %u)\n",
588 589 590 591 592
			       dccp_role(sk), sk,
			       opt_recv->ccid3or_loss_intervals_idx,
			       opt_recv->ccid3or_loss_intervals_len);
		break;
	case TFRC_OPT_RECEIVE_RATE:
593
		if (unlikely(len != 4)) {
594
			DCCP_WARN("%s(%p), invalid len %d "
595 596
				  "for TFRC_OPT_RECEIVE_RATE\n",
				  dccp_role(sk), sk, len);
597 598
			rc = -EINVAL;
		} else {
599
			opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
600
			ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
601 602 603 604 605 606 607 608 609
				       dccp_role(sk), sk,
				       opt_recv->ccid3or_receive_rate);
		}
		break;
	}

	return rc;
}

610
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
611
{
612
	struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
613

614
	hctx->ccid3hctx_s     = 0;
615
	hctx->ccid3hctx_rtt   = 0;
616 617
	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
618 619 620

	hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
	hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
621 622 623 624 625 626 627
	init_timer(&hctx->ccid3hctx_no_feedback_timer);

	return 0;
}

static void ccid3_hc_tx_exit(struct sock *sk)
{
628
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
629 630 631 632 633 634 635

	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 */
636
	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
637 638 639 640 641 642
}

/*
 * RX Half Connection methods
 */

643
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
644 645 646 647 648 649 650 651 652 653 654 655
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

656 657
static void ccid3_hc_rx_set_state(struct sock *sk,
				  enum ccid3_hc_rx_states state)
658
{
659
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
660 661 662
	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
663 664
		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
		       ccid3_rx_state_name(state));
665 666 667 668
	WARN_ON(state == oldstate);
	hcrx->ccid3hcrx_state = state;
}

669 670 671 672 673 674 675 676 677
static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
{
	if (unlikely(len == 0))	/* don't update on empty packets (e.g. ACKs) */
		ccid3_pr_debug("Packet payload length is 0 - not updating\n");
	else
		hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
				    (9 * hcrx->ccid3hcrx_s + len) / 10;
}

678 679
static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
680
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
681
	struct dccp_sock *dp = dccp_sk(sk);
682
	struct dccp_rx_hist_entry *packet;
683
	struct timeval now;
G
Gerrit Renker 已提交
684
	suseconds_t delta;
685

686
	ccid3_pr_debug("%s(%p) - entry \n", dccp_role(sk), sk);
687

688
	dccp_timestamp(sk, &now);
689

690 691 692 693
	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
		hcrx->ccid3hcrx_x_recv = 0;
		break;
G
Gerrit Renker 已提交
694 695 696 697
	case TFRC_RSTATE_DATA:
		delta = timeval_delta(&now,
				      &hcrx->ccid3hcrx_tstamp_last_feedback);
		DCCP_BUG_ON(delta < 0);
698 699
		hcrx->ccid3hcrx_x_recv =
			scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
700
		break;
701
	case TFRC_RSTATE_TERM:
702
		DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
703 704 705
		return;
	}

706
	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
707
	if (unlikely(packet == NULL)) {
708
		DCCP_WARN("%s(%p), no data packet in history!\n",
709
			  dccp_role(sk), sk);
710 711 712
		return;
	}

713
	hcrx->ccid3hcrx_tstamp_last_feedback = now;
I
Ian McDonald 已提交
714
	hcrx->ccid3hcrx_ccval_last_counter   = packet->dccphrx_ccval;
715 716
	hcrx->ccid3hcrx_bytes_recv	     = 0;

G
Gerrit Renker 已提交
717 718 719 720
	/* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
	delta = timeval_delta(&now, &packet->dccphrx_tstamp);
	DCCP_BUG_ON(delta < 0);
	hcrx->ccid3hcrx_elapsed_time = delta / 10;
721

722
	if (hcrx->ccid3hcrx_p == 0)
723 724 725 726 727
		hcrx->ccid3hcrx_pinv = ~0U;	/* see RFC 4342, 8.5 */
	else if (hcrx->ccid3hcrx_p > 1000000) {
		DCCP_WARN("p (%u) > 100%%\n", hcrx->ccid3hcrx_p);
		hcrx->ccid3hcrx_pinv = 1;	/* use 100% in this case */
	} else
728
		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
729

730
	dp->dccps_hc_rx_insert_options = 1;
731 732 733
	dccp_send_ack(sk);
}

734
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
735
{
736
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
737
	__be32 x_recv, pinv;
738

739 740 741
	BUG_ON(hcrx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
742
		return 0;
743

I
Ian McDonald 已提交
744
	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
745 746

	if (dccp_packet_without_ack(skb))
747 748
		return 0;

749 750
	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
	pinv   = htonl(hcrx->ccid3hcrx_pinv);
751 752 753 754 755 756 757 758 759 760 761 762

	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;
763 764 765 766 767 768 769 770
}

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

static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
771
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
772
	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
G
Gerrit Renker 已提交
773 774
	u32 x_recv, p;
	suseconds_t rtt, delta;
775
	struct timeval tstamp = { 0, };
776 777 778
	int interval = 0;
	int win_count = 0;
	int step = 0;
779
	u64 fval;
780

781 782 783
	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
				 dccphrx_node) {
		if (dccp_rx_hist_entry_data_packet(entry)) {
784 785 786 787
			tail = entry;

			switch (step) {
			case 0:
788
				tstamp	  = entry->dccphrx_tstamp;
789
				win_count = entry->dccphrx_ccval;
790 791 792
				step = 1;
				break;
			case 1:
793
				interval = win_count - entry->dccphrx_ccval;
794 795 796 797 798 799 800 801 802
				if (interval < 0)
					interval += TFRC_WIN_COUNT_LIMIT;
				if (interval > 4)
					goto found;
				break;
			}
		}
	}

803
	if (unlikely(step == 0)) {
804
		DCCP_WARN("%s(%p), packet history has no data packets!\n",
805
			  dccp_role(sk), sk);
806 807 808
		return ~0;
	}

809
	if (unlikely(interval == 0)) {
810
		DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
811
			  "Defaulting to 1\n", dccp_role(sk), sk);
812 813 814
		interval = 1;
	}
found:
I
Ian McDonald 已提交
815
	if (!tail) {
816
		DCCP_CRIT("tail is null\n");
I
Ian McDonald 已提交
817 818
		return ~0;
	}
G
Gerrit Renker 已提交
819 820 821 822 823

	delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
	DCCP_BUG_ON(delta < 0);

	rtt = delta * 4 / interval;
824
	ccid3_pr_debug("%s(%p), approximated RTT to %ldus\n",
825
		       dccp_role(sk), sk, rtt);
826

827 828 829 830 831 832 833 834 835 836 837
	/*
	 * Determine the length of the first loss interval via inverse lookup.
	 * Assume that X_recv can be computed by the throughput equation
	 *      	    s
	 * 	X_recv = --------
	 * 		 R * fval
	 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
	 */
	if (rtt == 0) {			/* would result in divide-by-zero */
		DCCP_WARN("RTT==0, returning 1/p = 1\n");
		return 1000000;
838
	}
839

840 841
	dccp_timestamp(sk, &tstamp);
	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
G
Gerrit Renker 已提交
842
	DCCP_BUG_ON(delta <= 0);
843

G
Gerrit Renker 已提交
844
	x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
845 846 847 848 849 850
	if (x_recv == 0) {		/* would also trigger divide-by-zero */
		DCCP_WARN("X_recv==0\n");
		if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
			DCCP_BUG("stored value of X_recv is zero");
			return 1000000;
		}
I
Ian McDonald 已提交
851 852
	}

853 854
	fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
	fval = scaled_div32(fval, x_recv);
855
	p = tfrc_calc_x_reverse_lookup(fval);
856

857
	ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
858
		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
859 860 861 862 863 864 865 866 867

	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)
{
868
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
869
	struct dccp_li_hist_entry *head;
I
Ian McDonald 已提交
870
	u64 seq_temp;
871

I
Ian McDonald 已提交
872 873 874 875
	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;
876

877 878 879
		head = list_entry(hcrx->ccid3hcrx_li_hist.next,
		   struct dccp_li_hist_entry, dccplih_node);
		head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
I
Ian McDonald 已提交
880 881 882 883
	} else {
		struct dccp_li_hist_entry *entry;
		struct list_head *tail;

884 885
		head = list_entry(hcrx->ccid3hcrx_li_hist.next,
		   struct dccp_li_hist_entry, dccplih_node);
I
Ian McDonald 已提交
886 887 888 889 890 891 892
		/* 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);
893
		entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
I
Ian McDonald 已提交
894 895

		if (entry == NULL) {
896
			DCCP_BUG("out of memory - can not allocate entry");
897
			return;
I
Ian McDonald 已提交
898 899 900 901 902 903 904 905 906 907 908 909 910
		}

		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;
	}
911 912
}

I
Ian McDonald 已提交
913 914
static int ccid3_hc_rx_detect_loss(struct sock *sk,
                                    struct dccp_rx_hist_entry *packet)
915
{
916
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
I
Ian McDonald 已提交
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932
	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;
	}

933

I
Ian McDonald 已提交
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
	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;
963 964 965 966
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
967
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
968
	const struct dccp_options_received *opt_recv;
969
	struct dccp_rx_hist_entry *packet;
970
	struct timeval now;
G
Gerrit Renker 已提交
971 972
	u32 p_prev, rtt_prev;
	suseconds_t r_sample, t_elapsed;
973
	int loss, payload_size;
974

975
	BUG_ON(hcrx == NULL);
976

977
	opt_recv = &dccp_sk(sk)->dccps_options_received;
978

979 980 981 982 983
	switch (DCCP_SKB_CB(skb)->dccpd_type) {
	case DCCP_PKT_ACK:
		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			return;
	case DCCP_PKT_DATAACK:
984
		if (opt_recv->dccpor_timestamp_echo == 0)
985
			break;
I
Ian McDonald 已提交
986
		rtt_prev = hcrx->ccid3hcrx_rtt;
987
		dccp_timestamp(sk, &now);
988 989 990 991
		timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
		r_sample = timeval_usecs(&now);
		t_elapsed = opt_recv->dccpor_elapsed_time * 10;

G
Gerrit Renker 已提交
992
		DCCP_BUG_ON(r_sample < 0);
993
		if (unlikely(r_sample <= t_elapsed))
G
Gerrit Renker 已提交
994
			DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n",
995
				  r_sample, t_elapsed);
996 997
		else
			r_sample -= t_elapsed;
998
		CCID3_RTT_SANITY_CHECK(r_sample);
999 1000 1001 1002 1003 1004 1005

		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 已提交
1006
		if (rtt_prev != hcrx->ccid3hcrx_rtt)
1007 1008
			ccid3_pr_debug("%s(%p), New RTT=%uus, elapsed time=%u\n",
				       dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
1009
				       opt_recv->dccpor_elapsed_time);
1010 1011 1012
		break;
	case DCCP_PKT_DATA:
		break;
1013
	default: /* We're not interested in other packet types, move along */
1014 1015 1016
		return;
	}

1017
	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
1018
					skb, GFP_ATOMIC);
1019
	if (unlikely(packet == NULL)) {
1020
		DCCP_WARN("%s(%p), Not enough mem to add rx packet "
1021
			  "to history, consider it lost!\n", dccp_role(sk), sk);
1022 1023 1024
		return;
	}

I
Ian McDonald 已提交
1025
	loss = ccid3_hc_rx_detect_loss(sk, packet);
1026 1027 1028 1029

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

1030 1031 1032
	payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
	ccid3_hc_rx_update_s(hcrx, payload_size);

1033 1034
	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
1035 1036
		ccid3_pr_debug("%s(%p, state=%s), skb=%p, sending initial "
			       "feedback\n", dccp_role(sk), sk,
1037
			       dccp_state_name(sk->sk_state), skb);
1038 1039 1040 1041
		ccid3_hc_rx_send_feedback(sk);
		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
		return;
	case TFRC_RSTATE_DATA:
1042
		hcrx->ccid3hcrx_bytes_recv += payload_size;
I
Ian McDonald 已提交
1043
		if (loss)
1044 1045
			break;

1046
		dccp_timestamp(sk, &now);
G
Gerrit Renker 已提交
1047 1048
		if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) -
					(suseconds_t)hcrx->ccid3hcrx_rtt >= 0) {
1049 1050
			hcrx->ccid3hcrx_tstamp_last_ack = now;
			ccid3_hc_rx_send_feedback(sk);
1051
		}
1052
		return;
1053
	case TFRC_RSTATE_TERM:
1054
		DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
1055 1056 1057 1058
		return;
	}

	/* Dealing with packet loss */
1059
	ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n",
1060
		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1061 1062 1063 1064

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

1068
		/* Scaling up by 1000000 as fixed decimal */
I
Ian McDonald 已提交
1069 1070
		if (i_mean != 0)
			hcrx->ccid3hcrx_p = 1000000 / i_mean;
1071 1072
	} else
		DCCP_BUG("empty loss history");
1073 1074 1075 1076 1077 1078 1079

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

1080
static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1081
{
1082
	struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1083

1084
	ccid3_pr_debug("entry\n");
1085 1086 1087

	hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1088
	INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1089
	dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1090
	hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
1091
	hcrx->ccid3hcrx_s   = 0;
1092
	hcrx->ccid3hcrx_rtt = 0;
1093 1094 1095 1096 1097
	return 0;
}

static void ccid3_hc_rx_exit(struct sock *sk)
{
1098
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1099

1100
	BUG_ON(hcrx == NULL);
1101 1102 1103 1104

	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

	/* Empty packet history */
1105
	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1106 1107

	/* Empty loss interval history */
1108
	dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1109 1110
}

1111 1112
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
1113
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1114

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

1119
	BUG_ON(hcrx == NULL);
1120 1121 1122 1123 1124 1125 1126 1127

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

1130 1131 1132 1133
	/* Listen socks doesn't have a private CCID block */
	if (sk->sk_state == DCCP_LISTEN)
		return;

1134
	BUG_ON(hctx == NULL);
1135 1136 1137 1138 1139

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

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 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
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;
}

1194
static struct ccid_operations ccid3 = {
I
Ian McDonald 已提交
1195
	.ccid_id		   = DCCPC_CCID3,
1196 1197
	.ccid_name		   = "ccid3",
	.ccid_owner		   = THIS_MODULE,
1198
	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
1199 1200 1201 1202 1203 1204
	.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_parse_options  = ccid3_hc_tx_parse_options,
1205
	.ccid_hc_rx_obj_size	   = sizeof(struct ccid3_hc_rx_sock),
1206 1207 1208 1209
	.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,
1210 1211
	.ccid_hc_rx_get_info	   = ccid3_hc_rx_get_info,
	.ccid_hc_tx_get_info	   = ccid3_hc_tx_get_info,
1212 1213
	.ccid_hc_rx_getsockopt	   = ccid3_hc_rx_getsockopt,
	.ccid_hc_tx_getsockopt	   = ccid3_hc_tx_getsockopt,
1214 1215
};
 
1216
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
1217 1218
module_param(ccid3_debug, int, 0444);
MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
1219
#endif
1220 1221 1222

static __init int ccid3_module_init(void)
{
1223
	int rc = -ENOBUFS;
1224

1225 1226
	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
	if (ccid3_rx_hist == NULL)
1227 1228
		goto out;

1229 1230 1231
	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
	if (ccid3_tx_hist == NULL)
		goto out_free_rx;
1232

1233 1234
	ccid3_li_hist = dccp_li_hist_new("ccid3");
	if (ccid3_li_hist == NULL)
1235
		goto out_free_tx;
1236 1237 1238 1239 1240 1241

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

1243
out_free_loss_interval_history:
1244 1245
	dccp_li_hist_delete(ccid3_li_hist);
	ccid3_li_hist = NULL;
1246 1247 1248 1249 1250 1251
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;
1252 1253 1254 1255 1256 1257 1258 1259
	goto out;
}
module_init(ccid3_module_init);

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

1260 1261 1262
	if (ccid3_tx_hist != NULL) {
		dccp_tx_hist_delete(ccid3_tx_hist);
		ccid3_tx_hist = NULL;
1263
	}
1264 1265 1266
	if (ccid3_rx_hist != NULL) {
		dccp_rx_hist_delete(ccid3_rx_hist);
		ccid3_rx_hist = NULL;
1267
	}
1268 1269 1270
	if (ccid3_li_hist != NULL) {
		dccp_li_hist_delete(ccid3_li_hist);
		ccid3_li_hist = NULL;
1271 1272 1273 1274
	}
}
module_exit(ccid3_module_exit);

1275
MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
1276
	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
1277 1278 1279
MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
MODULE_LICENSE("GPL");
MODULE_ALIAS("net-dccp-ccid-3");