ccid3.c 36.6 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

		hctx->ccid3hctx_x = min_t(u64, hctx->ccid3hctx_x_calc << 6,
					       hctx->ccid3hctx_x_recv * 2  );
		hctx->ccid3hctx_x = max_t(u64, hctx->ccid3hctx_x,
					  (hctx->ccid3hctx_s << 6)/TFRC_T_MBI);
130

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

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

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

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
/*
 * 	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.
	 */
}

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

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

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

	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_NO_FBACK:
209
		/* RFC 3448, 4.4: Halve send rate directly */
210
		hctx->ccid3hctx_x = max_t(u32, hctx->ccid3hctx_x / 2,
211
					  (hctx->ccid3hctx_s << 6)/TFRC_T_MBI);
212

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

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

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

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

				hctx->ccid3hctx_x_recv =
					max_t(u64, hctx->ccid3hctx_x_recv / 2,
					      	  (hctx->ccid3hctx_s << 6) /
					      			(2*TFRC_T_MBI));

257 258 259
				if (hctx->ccid3hctx_p == 0)
					dccp_timestamp(sk, &now);
			} else
260
				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc << 4;
261

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

	hctx->ccid3hctx_idle = 1;
280 281 282

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

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

302
	BUG_ON(hctx == NULL);
303

304
	/*
305 306 307
	 * 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.
308
	 */
309
	if (unlikely(skb->len == 0))
310
		return -EBADMSG;
311

312
	dccp_timestamp(sk, &now);
313 314 315

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

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

326 327 328 329 330 331
		/* 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 */
332 333 334 335
		hctx->ccid3hctx_t_nom = now;
		break;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
336 337 338 339 340 341 342 343 344
		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 已提交
345
		if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
346
			return delay / 1000L;
347 348

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

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

	/* set the nominal send time for the next following packet */
360 361 362
	timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);

	return 0;
363 364
}

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

371
	BUG_ON(hctx == NULL);
372

373
	ccid3_hc_tx_update_s(hctx, len);
374

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

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

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

401
	BUG_ON(hctx == NULL);
402 403 404 405 406 407 408 409 410 411 412

	/* 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:
413
		/* get packet from history to look up t_recvdata */
414 415
		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
416
		if (unlikely(packet == NULL)) {
417
			DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist "
418
				  "in history!\n",  dccp_role(sk), sk,
419
			    (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
420
				  dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
421 422 423
			return;
		}

424 425
		/* Update receive rate in units of 64 * bytes/second */
		hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate << 6;
426 427 428

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

434
		dccp_timestamp(sk, &now);
435 436 437 438 439 440 441 442

		/*
		 * 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 已提交
443 444
		DCCP_BUG_ON(r_sample < 0);
		if (unlikely(r_sample <= t_elapsed))
445
			DCCP_WARN("WARNING: r_sample=%ldus <= t_elapsed=%ldus\n",
446
				  r_sample, t_elapsed);
447 448
		else
			r_sample -= t_elapsed;
449
		CCID3_RTT_SANITY_CHECK(r_sample);
450

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

			ccid3_update_send_time(hctx);
471

472 473 474
			ccid3_pr_debug("%s(%p), s=%u, w_init=%u, "
				       "R_sample=%ldus, X=%u\n", dccp_role(sk),
				       sk, hctx->ccid3hctx_s, w_init, r_sample,
475
				       (unsigned)(hctx->ccid3hctx_x >> 6));
476

477 478 479 480
			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
		} else {
			hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
					           (u32)r_sample        ) / 10;
481

482 483 484 485 486 487
			/* 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);
488
			ccid3_hc_tx_update_x(sk, &now);
489

490 491 492 493 494
			ccid3_pr_debug("%s(%p), RTT=%uus (sample=%ldus), s=%u, "
				       "p=%u, X_calc=%u, X=%u\n", dccp_role(sk),
				       sk, hctx->ccid3hctx_rtt, r_sample,
				       hctx->ccid3hctx_s, hctx->ccid3hctx_p,
				       hctx->ccid3hctx_x_calc,
495
				       (unsigned)(hctx->ccid3hctx_x >> 6));
496 497 498 499 500 501
		}

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

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

510 511 512 513 514 515
		/*
		 * 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.
		 */
516
		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
517 518
						   CONFIG_IP_DCCP_CCID3_RTO *
						   (USEC_PER_SEC/1000)	     );
519 520
		/*
		 * Schedule no feedback timer to expire in
521
		 * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
522
		 */
523
		t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
524
			
525 526 527
		ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
			       "expire in %lu jiffies (%luus)\n",
			       dccp_role(sk), sk,
528
			       usecs_to_jiffies(t_nfb), t_nfb);
529 530

		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
531
				   jiffies + usecs_to_jiffies(t_nfb));
532 533

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

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

554
	BUG_ON(hctx == NULL);
555 556 557 558 559 560 561 562 563 564 565 566 567

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

	return rc;
}

606
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
607
{
608
	struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
609

610
	hctx->ccid3hctx_s     = 0;
611
	hctx->ccid3hctx_rtt   = 0;
612 613
	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
614 615 616

	hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
	hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
617 618 619 620 621 622 623
	init_timer(&hctx->ccid3hctx_no_feedback_timer);

	return 0;
}

static void ccid3_hc_tx_exit(struct sock *sk)
{
624
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
625 626 627 628 629 630 631

	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 */
632
	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
633 634 635 636 637 638
}

/*
 * RX Half Connection methods
 */

639
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
640 641 642 643 644 645 646 647 648 649 650 651
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

652 653
static void ccid3_hc_rx_set_state(struct sock *sk,
				  enum ccid3_hc_rx_states state)
654
{
655
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
656 657 658
	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
659 660
		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
		       ccid3_rx_state_name(state));
661 662 663 664
	WARN_ON(state == oldstate);
	hcrx->ccid3hcrx_state = state;
}

665 666 667 668 669 670 671 672 673
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;
}

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

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

684
	dccp_timestamp(sk, &now);
685

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

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

709
	hcrx->ccid3hcrx_tstamp_last_feedback = now;
I
Ian McDonald 已提交
710
	hcrx->ccid3hcrx_ccval_last_counter   = packet->dccphrx_ccval;
711 712
	hcrx->ccid3hcrx_bytes_recv	     = 0;

G
Gerrit Renker 已提交
713 714 715 716
	/* 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;
717

718
	if (hcrx->ccid3hcrx_p == 0)
719 720 721 722 723
		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
724
		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
725

726
	dp->dccps_hc_rx_insert_options = 1;
727 728 729
	dccp_send_ack(sk);
}

730
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
731
{
732
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
733
	__be32 x_recv, pinv;
734

735 736 737
	BUG_ON(hcrx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
738
		return 0;
739

I
Ian McDonald 已提交
740
	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
741 742

	if (dccp_packet_without_ack(skb))
743 744
		return 0;

745 746
	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
	pinv   = htonl(hcrx->ccid3hcrx_pinv);
747 748 749 750 751 752 753 754 755 756 757 758

	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;
759 760 761 762 763 764 765 766
}

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

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

777 778 779
	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
				 dccphrx_node) {
		if (dccp_rx_hist_entry_data_packet(entry)) {
780 781 782 783
			tail = entry;

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

799
	if (unlikely(step == 0)) {
800 801
		DCCP_WARN("%s, sk=%p, packet history has no data packets!\n",
			  dccp_role(sk), sk);
802 803 804
		return ~0;
	}

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

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

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

823 824 825 826 827 828 829 830 831 832 833
	/*
	 * 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;
834
	}
835

836 837
	dccp_timestamp(sk, &tstamp);
	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
G
Gerrit Renker 已提交
838
	DCCP_BUG_ON(delta <= 0);
839

G
Gerrit Renker 已提交
840
	x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
841 842 843 844 845 846
	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 已提交
847 848
	}

849 850
	fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
	fval = scaled_div32(fval, x_recv);
851
	p = tfrc_calc_x_reverse_lookup(fval);
852

853 854
	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
855 856 857 858 859 860 861 862 863

	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)
{
864
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
865
	struct dccp_li_hist_entry *head;
I
Ian McDonald 已提交
866
	u64 seq_temp;
867

I
Ian McDonald 已提交
868 869 870 871
	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;
872

873 874 875
		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 已提交
876 877 878 879
	} else {
		struct dccp_li_hist_entry *entry;
		struct list_head *tail;

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

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

		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;
	}
907 908
}

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

929

I
Ian McDonald 已提交
930 931 932 933 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
	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;
959 960 961 962
}

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

971
	BUG_ON(hcrx == NULL);
972

973
	opt_recv = &dccp_sk(sk)->dccps_options_received;
974

975 976 977 978 979
	switch (DCCP_SKB_CB(skb)->dccpd_type) {
	case DCCP_PKT_ACK:
		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			return;
	case DCCP_PKT_DATAACK:
980
		if (opt_recv->dccpor_timestamp_echo == 0)
981
			break;
I
Ian McDonald 已提交
982
		rtt_prev = hcrx->ccid3hcrx_rtt;
983
		dccp_timestamp(sk, &now);
984 985 986 987
		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 已提交
988
		DCCP_BUG_ON(r_sample < 0);
989
		if (unlikely(r_sample <= t_elapsed))
G
Gerrit Renker 已提交
990
			DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n",
991
				  r_sample, t_elapsed);
992 993
		else
			r_sample -= t_elapsed;
994
		CCID3_RTT_SANITY_CHECK(r_sample);
995 996 997 998 999 1000 1001

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

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

I
Ian McDonald 已提交
1021
	loss = ccid3_hc_rx_detect_loss(sk, packet);
1022 1023 1024 1025

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

1026 1027 1028
	payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
	ccid3_hc_rx_update_s(hcrx, payload_size);

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

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

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

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

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

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

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

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

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

static void ccid3_hc_rx_exit(struct sock *sk)
{
1095
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1096

1097
	BUG_ON(hcrx == NULL);
1098 1099 1100 1101

	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

	/* Empty packet history */
1102
	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1103 1104

	/* Empty loss interval history */
1105
	dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1106 1107
}

1108 1109
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
1110
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1111

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

1116
	BUG_ON(hcrx == NULL);
1117 1118 1119 1120 1121 1122 1123 1124

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

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

1131
	BUG_ON(hctx == NULL);
1132 1133 1134 1135 1136

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

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

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

static __init int ccid3_module_init(void)
{
1220
	int rc = -ENOBUFS;
1221

1222 1223
	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
	if (ccid3_rx_hist == NULL)
1224 1225
		goto out;

1226 1227 1228
	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
	if (ccid3_tx_hist == NULL)
		goto out_free_rx;
1229

1230 1231
	ccid3_li_hist = dccp_li_hist_new("ccid3");
	if (ccid3_li_hist == NULL)
1232
		goto out_free_tx;
1233 1234 1235 1236 1237 1238

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

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

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

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

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