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

64
65
66
67

#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
static int ccid3_debug;
#define ccid3_pr_debug(format, a...)	DCCP_PR_DEBUG(ccid3_debug, format, ##a)
68
69
70
71
#else
#define ccid3_pr_debug(format, a...)
#endif

72
73
static struct dccp_tx_hist *ccid3_tx_hist;
static struct dccp_rx_hist *ccid3_rx_hist;
74
static struct dccp_li_hist *ccid3_li_hist;
75

76
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
77
78
79
80
81
82
83
84
85
86
87
88
89
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

90
91
static void ccid3_hc_tx_set_state(struct sock *sk,
				  enum ccid3_hc_tx_states state)
92
{
93
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
94
95
96
	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
97
98
		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
		       ccid3_tx_state_name(state));
99
100
101
102
103
104
105
	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)
{
106
	hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_x);
107
108
109
110
111
}

/* 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)
{
112
113
	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
					   TFRC_OPSYS_HALF_TIME_GRAN);
114
115
116
117
118
119
120
121
122
123
124
125
126
127
}

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

130
131
	/* To avoid large error in calcX */
	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
132
133
134
		hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
						     hctx->ccid3hctx_rtt,
						     hctx->ccid3hctx_p);
135
136
137
138
		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));
139
140
141
	} else {
		struct timeval now;

142
		dccp_timestamp(sk, &now);
143
144
	       	if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
		    hctx->ccid3hctx_rtt) {
145
146
147
148
			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));
149
150
			hctx->ccid3hctx_t_ld = now;
		}
151
152
153
154
155
156
157
	}
}

static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
	struct sock *sk = (struct sock *)data;
	unsigned long next_tmout = 0;
158
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
159
160
161
162
163

	bh_lock_sock(sk);
	if (sock_owned_by_user(sk)) {
		/* Try again later. */
		/* XXX: set some sensible MIB */
164
165
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + HZ / 5);
166
167
168
169
170
171
172
173
174
175
		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_NO_FBACK:
		/* Halve send rate */
		hctx->ccid3hctx_x /= 2;
176
177
		if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s /
					 TFRC_MAX_BACK_OFF_TIME))
178
179
			hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
					     TFRC_MAX_BACK_OFF_TIME);
180

181
182
183
184
		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),
185
			       hctx->ccid3hctx_x);
186
187
		next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x),
188
189
190
191
192
193
					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
		 */
194
195
		break;
	case TFRC_SSTATE_FBACK:
196
197
198
199
200
		/*
		 * Check if IDLE since last timeout and recv rate is less than
		 * 4 packets per RTT
		 */
		if (!hctx->ccid3hctx_idle ||
201
202
		    (hctx->ccid3hctx_x_recv >=
		     4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) {
203
204
			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
				       dccp_role(sk), sk,
205
206
207
208
209
210
211
212
				       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;
			 */
213
214
			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P &&
			       hctx->ccid3hctx_x_calc == 0);
215
216
217
218
219
220
221
222
223
224
225
226

			/* 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);
		}
227
228
229
230
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
231
		next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 
232
233
					2 * usecs_div(hctx->ccid3hctx_s,
						      hctx->ccid3hctx_x));
234
		break;
235
236
237
238
	case TFRC_SSTATE_NO_SENT:
		DCCP_BUG("Illegal %s state NO_SENT, sk=%p", dccp_role(sk), sk);
		/* fall through */
	case TFRC_SSTATE_TERM:
239
240
241
242
		goto out;
	}

	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
243
		      jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
244
245
246
247
248
249
	hctx->ccid3hctx_idle = 1;
out:
	bh_unlock_sock(sk);
	sock_put(sk);
}

250
251
252
253
254
255
/*
 * returns
 *   > 0: delay (in msecs) that should pass before actually sending
 *   = 0: can send immediately
 *   < 0: error condition; do not send packet
 */
256
257
static int ccid3_hc_tx_send_packet(struct sock *sk,
				   struct sk_buff *skb, int len)
258
259
{
	struct dccp_sock *dp = dccp_sk(sk);
260
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
261
	struct dccp_tx_hist_entry *new_packet;
262
	struct timeval now;
263
	long delay;
264

265
	BUG_ON(hctx == NULL);
266

267
	/*
268
269
270
	 * 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.
271
	 */
272
	if (unlikely(len == 0))
273
		return -EBADMSG;
274
275

	/* See if last packet allocated was not sent */
276
277
	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
	if (new_packet == NULL || new_packet->dccphtx_sent) {
278
279
		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
						    SLAB_ATOMIC);
280

281
		if (unlikely(new_packet == NULL)) {
282
283
			DCCP_WARN("%s, sk=%p, not enough mem to add to history,"
				  "send refused\n", dccp_role(sk), sk);
284
			return -ENOBUFS;
285
286
		}

287
		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
288
289
	}

290
	dccp_timestamp(sk, &now);
291
292
293

	switch (hctx->ccid3hctx_state) {
	case TFRC_SSTATE_NO_SENT:
294
295
		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
			       jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
296
297
298
299
		hctx->ccid3hctx_last_win_count	 = 0;
		hctx->ccid3hctx_t_last_win_count = now;
		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);

300
301
302
303
304
305
		/* 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 */
306
307
308
309
		hctx->ccid3hctx_t_nom = now;
		break;
	case TFRC_SSTATE_NO_FBACK:
	case TFRC_SSTATE_FBACK:
310
311
312
313
314
315
316
317
318
		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.
		 */
319
320
		if (delay >= hctx->ccid3hctx_delta)
			return delay / 1000L;
321
		break;
322
323
	case TFRC_SSTATE_TERM:
		DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
324
		return -EINVAL;
325
326
	}

327
328
329
330
331
332
333
	/* prepare to send now (add options etc.) */
	dp->dccps_hc_tx_insert_options = 1;
	new_packet->dccphtx_ccval = DCCP_SKB_CB(skb)->dccpd_ccval =
				    hctx->ccid3hctx_last_win_count;
	timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);

	return 0;
334
335
336
337
}

static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
{
338
339
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
340
341
	struct timeval now;

342
	BUG_ON(hctx == NULL);
343

344
	dccp_timestamp(sk, &now);
345
346
347
348

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

351
		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
352
		if (unlikely(packet == NULL)) {
353
			DCCP_WARN("packet doesn't exist in history!\n");
354
355
			return;
		}
356
		if (unlikely(packet->dccphtx_sent)) {
357
			DCCP_WARN("no unsent packet in history!\n");
358
359
			return;
		}
360
361
		packet->dccphtx_tstamp = now;
		packet->dccphtx_seqno  = dp->dccps_gss;
362
		/*
363
		 * Check if win_count have changed
364
		 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
365
		 */
366
367
368
369
		quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
		if (likely(hctx->ccid3hctx_rtt > 8))
			quarter_rtt /= hctx->ccid3hctx_rtt / 4;

370
371
372
373
		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;
374
375
			ccid3_pr_debug("%s, sk=%p, window changed from "
				       "%u to %u!\n",
376
				       dccp_role(sk), sk,
377
				       packet->dccphtx_ccval,
378
379
				       hctx->ccid3hctx_last_win_count);
		}
380

381
		hctx->ccid3hctx_idle = 0;
382
		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
383
		packet->dccphtx_sent = 1;
384
385
386
387
388
389
	} 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:
390
		/* fall through */
391
	case TFRC_SSTATE_NO_FBACK:
392
393
		/* t_nom, t_ipi, delta do not change until feedback arrives */
		return;
394
395
	case TFRC_SSTATE_FBACK:
		if (len > 0) {
Ian McDonald's avatar
Ian McDonald committed
396
397
			timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
398
399
			ccid3_calc_new_t_ipi(hctx);
			ccid3_calc_new_delta(hctx);
400
401
			timeval_add_usecs(&hctx->ccid3hctx_t_nom,
					  hctx->ccid3hctx_t_ipi);
402
403
		}
		break;
404
405
	case TFRC_SSTATE_TERM:
		DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
406
407
408
409
410
411
		break;
	}
}

static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
412
413
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
414
	struct ccid3_options_received *opt_recv;
415
	struct dccp_tx_hist_entry *packet;
416
	struct timeval now;
417
	unsigned long next_tmout; 
418
	u32 t_elapsed;
419
420
421
	u32 pinv;
	u32 x_recv;
	u32 r_sample;
422

423
	BUG_ON(hctx == NULL);
424
425
426
427
428
429
430
431

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

432
	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
433
434
435
436
437
438
439
440
441
442
443
444
	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 */
445
446
		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
447
		if (unlikely(packet == NULL)) {
448
449
			DCCP_WARN("%s, sk=%p, seqno %llu(%s) does't exist "
				  "in history!\n",  dccp_role(sk), sk,
450
			    (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
451
				  dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
452
453
454
455
			return;
		}

		/* Update RTT */
456
457
		dccp_timestamp(sk, &now);
		r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
458
		if (unlikely(r_sample <= t_elapsed))
459
460
			DCCP_WARN("r_sample=%uus,t_elapsed=%uus\n",
				  r_sample, t_elapsed);
461
462
		else
			r_sample -= t_elapsed;
463
464
465
466
467
468
469
470
471
472
473
474
475

		/* 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
476
477
			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
					      r_sample / 10;
478

479
480
481
		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
			       "r_sample=%us\n", dccp_role(sk), sk,
			       hctx->ccid3hctx_rtt, r_sample);
482
483

		/* Update timeout interval */
484
485
		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
					      USEC_PER_SEC);
486
487

		/* Update receive rate */
488
		hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
489
490
491
492
493
494
495
496
497

		/* 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;
498
499
				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n",
					       dccp_role(sk), sk);
500
501
502
503
504
505
506
507
508
509
			}
		}

		/* 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 */
510
511
		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
512
		ccid3_calc_new_t_ipi(hctx);
513
514
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
515
516
517
		ccid3_calc_new_delta(hctx);

		/* remove all packets older than the one acked from history */
518
519
		dccp_tx_hist_purge_older(ccid3_tx_hist,
					 &hctx->ccid3hctx_hist, packet);
520
521
522
523
524
		/*
		 * 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);
525

526
527
528
529
		/*
		 * Schedule no feedback timer to expire in
		 * max(4 * R, 2 * s / X)
		 */
530
		next_tmout = max(hctx->ccid3hctx_t_rto,
531
532
533
				 2 * usecs_div(hctx->ccid3hctx_s,
					       hctx->ccid3hctx_x));
			
534
535
536
537
		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); 
538
539

		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
540
			       jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
541
542
543
544

		/* set idle flag */
		hctx->ccid3hctx_idle = 1;   
		break;
545
546
	case TFRC_SSTATE_TERM:
		DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
547
548
549
550
		break;
	}
}

551
static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
552
{
553
	const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
554

555
556
	BUG_ON(hctx == NULL);

557
558
559
	if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
		DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
	return 0;
560
561
562
}

static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
563
564
				     unsigned char len, u16 idx,
				     unsigned char *value)
565
566
{
	int rc = 0;
567
568
	const struct dccp_sock *dp = dccp_sk(sk);
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
569
570
	struct ccid3_options_received *opt_recv;

571
	BUG_ON(hctx == NULL);
572
573
574
575
576
577
578
579
580
581
582
583
584

	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:
585
		if (unlikely(len != 4)) {
586
587
588
			DCCP_WARN("%s, sk=%p, invalid len %d "
				  "for TFRC_OPT_LOSS_EVENT_RATE\n",
				  dccp_role(sk), sk, len);
589
590
			rc = -EINVAL;
		} else {
591
			opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
592
593
594
595
596
597
598
599
600
601
602
603
604
605
			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:
606
		if (unlikely(len != 4)) {
607
608
609
			DCCP_WARN("%s, sk=%p, invalid len %d "
				  "for TFRC_OPT_RECEIVE_RATE\n",
				  dccp_role(sk), sk, len);
610
611
			rc = -EINVAL;
		} else {
612
			opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
613
614
615
616
617
618
619
620
621
622
			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
				       dccp_role(sk), sk,
				       opt_recv->ccid3or_receive_rate);
		}
		break;
	}

	return rc;
}

623
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
624
625
{
	struct dccp_sock *dp = dccp_sk(sk);
626
	struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
627

628
629
630
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hctx->ccid3hctx_s = dp->dccps_packet_size;
631
632
633
	else
		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;

634
635
	/* Set transmission rate to 1 packet per second */
	hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
636
	hctx->ccid3hctx_t_rto = USEC_PER_SEC;
637
638
	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
639
640
641

	hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
	hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
642
643
644
645
646
647
648
	init_timer(&hctx->ccid3hctx_no_feedback_timer);

	return 0;
}

static void ccid3_hc_tx_exit(struct sock *sk)
{
649
	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
650
651
652
653
654
655
656

	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 */
657
	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
658
659
660
661
662
663
}

/*
 * RX Half Connection methods
 */

664
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
665
666
667
668
669
670
671
672
673
674
675
676
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

677
678
static void ccid3_hc_rx_set_state(struct sock *sk,
				  enum ccid3_hc_rx_states state)
679
{
680
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
681
682
683
	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;

	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
684
685
		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
		       ccid3_rx_state_name(state));
686
687
688
689
690
691
	WARN_ON(state == oldstate);
	hcrx->ccid3hcrx_state = state;
}

static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
692
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
693
	struct dccp_sock *dp = dccp_sk(sk);
694
	struct dccp_rx_hist_entry *packet;
695
	struct timeval now;
696
697
698

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

699
	dccp_timestamp(sk, &now);
700

701
702
703
704
705
	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
		hcrx->ccid3hcrx_x_recv = 0;
		break;
	case TFRC_RSTATE_DATA: {
706
707
		const u32 delta = timeval_delta(&now,
					&hcrx->ccid3hcrx_tstamp_last_feedback);
708
709
		hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
						   delta);
710
711
	}
		break;
712
713
	case TFRC_RSTATE_TERM:
		DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
714
715
716
		return;
	}

717
	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
718
	if (unlikely(packet == NULL)) {
719
720
		DCCP_WARN("%s, sk=%p, no data packet in history!\n",
			  dccp_role(sk), sk);
721
722
723
		return;
	}

724
	hcrx->ccid3hcrx_tstamp_last_feedback = now;
Ian McDonald's avatar
Ian McDonald committed
725
	hcrx->ccid3hcrx_ccval_last_counter   = packet->dccphrx_ccval;
726
727
728
	hcrx->ccid3hcrx_bytes_recv	     = 0;

	/* Convert to multiples of 10us */
729
730
	hcrx->ccid3hcrx_elapsed_time =
			timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
731
732
733
734
	if (hcrx->ccid3hcrx_p == 0)
		hcrx->ccid3hcrx_pinv = ~0;
	else
		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
735
	dp->dccps_hc_rx_insert_options = 1;
736
737
738
	dccp_send_ack(sk);
}

739
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
740
{
741
	const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
742
	__be32 x_recv, pinv;
743

744
745
746
	BUG_ON(hcrx == NULL);

	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
747
		return 0;
748

Ian McDonald's avatar
Ian McDonald committed
749
	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
750
751

	if (dccp_packet_without_ack(skb))
752
753
		return 0;

754
755
	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
	pinv   = htonl(hcrx->ccid3hcrx_pinv);
756
757
758
759
760
761
762
763
764
765
766
767

	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;
768
769
770
771
772
773
774
775
}

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

static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
776
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
777
	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
778
	u32 rtt, delta, x_recv, fval, p, tmp2;
779
	struct timeval tstamp = { 0, };
780
781
782
783
784
	int interval = 0;
	int win_count = 0;
	int step = 0;
	u64 tmp1;

785
786
787
	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
				 dccphrx_node) {
		if (dccp_rx_hist_entry_data_packet(entry)) {
788
789
790
791
			tail = entry;

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

807
	if (unlikely(step == 0)) {
808
809
		DCCP_WARN("%s, sk=%p, packet history has no data packets!\n",
			  dccp_role(sk), sk);
810
811
812
		return ~0;
	}

813
	if (unlikely(interval == 0)) {
814
815
		DCCP_WARN("%s, sk=%p, Could not find a win_count interval > 0."
			  "Defaulting to 1\n", dccp_role(sk), sk);
816
817
818
		interval = 1;
	}
found:
Ian McDonald's avatar
Ian McDonald committed
819
	if (!tail) {
820
		DCCP_CRIT("tail is null\n");
Ian McDonald's avatar
Ian McDonald committed
821
822
		return ~0;
	}
823
	rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
824
825
	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
		       dccp_role(sk), sk, rtt);
826
827
828
829
830

	if (rtt == 0) {
		DCCP_WARN("RTT==0, setting to 1\n");
 		rtt = 1;
	}
831

832
833
834
	dccp_timestamp(sk, &tstamp);
	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
	x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
835

Ian McDonald's avatar
Ian McDonald committed
836
837
838
	if (x_recv == 0)
		x_recv = hcrx->ccid3hcrx_x_recv;

839
840
841
	tmp1 = (u64)x_recv * (u64)rtt;
	do_div(tmp1,10000000);
	tmp2 = (u32)tmp1;
Ian McDonald's avatar
Ian McDonald committed
842
843

	if (!tmp2) {
844
		DCCP_CRIT("tmp2 = 0, x_recv = %u, rtt =%u\n", x_recv, rtt);
Ian McDonald's avatar
Ian McDonald committed
845
846
847
		return ~0;
	}

848
849
	fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
	/* do not alter order above or you will get overflow on 32 bit */
850
	p = tfrc_calc_x_reverse_lookup(fval);
851
852
	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
853
854
855
856
857
858
859
860
861

	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)
{
862
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
863
	struct dccp_li_hist_entry *head;
Ian McDonald's avatar
Ian McDonald committed
864
	u64 seq_temp;
865

Ian McDonald's avatar
Ian McDonald committed
866
867
868
869
	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;
870

871
872
873
		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);
Ian McDonald's avatar
Ian McDonald committed
874
875
876
877
	} else {
		struct dccp_li_hist_entry *entry;
		struct list_head *tail;

878
879
		head = list_entry(hcrx->ccid3hcrx_li_hist.next,
		   struct dccp_li_hist_entry, dccplih_node);
Ian McDonald's avatar
Ian McDonald committed
880
881
882
883
884
885
886
887
888
889
		/* 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) {
890
			DCCP_BUG("out of memory - can not allocate entry");
891
			return;
Ian McDonald's avatar
Ian McDonald committed
892
893
894
895
896
897
898
899
900
901
902
903
904
		}

		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;
	}
905
906
}

Ian McDonald's avatar
Ian McDonald committed
907
908
static int ccid3_hc_rx_detect_loss(struct sock *sk,
                                    struct dccp_rx_hist_entry *packet)
909
{
910
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
Ian McDonald's avatar
Ian McDonald committed
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
	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;
	}

927

Ian McDonald's avatar
Ian McDonald committed
928
929
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
	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;
957
958
959
960
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
961
	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
962
	const struct dccp_options_received *opt_recv;
963
	struct dccp_rx_hist_entry *packet;
964
	struct timeval now;
Ian McDonald's avatar
Ian McDonald committed
965
966
	u32 p_prev, rtt_prev, r_sample, t_elapsed;
	int loss;
967

968
	BUG_ON(hcrx == NULL);
969

970
	opt_recv = &dccp_sk(sk)->dccps_options_received;
971

972
973
974
975
976
	switch (DCCP_SKB_CB(skb)->dccpd_type) {
	case DCCP_PKT_ACK:
		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
			return;
	case DCCP_PKT_DATAACK:
977
		if (opt_recv->dccpor_timestamp_echo == 0)
978
			break;
Ian McDonald's avatar
Ian McDonald committed
979
		rtt_prev = hcrx->ccid3hcrx_rtt;
980
		dccp_timestamp(sk, &now);
981
982
983
984
985
		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))
986
987
			DCCP_WARN("r_sample=%uus, t_elapsed=%uus\n",
				  r_sample, t_elapsed);
988
989
990
991
992
993
994
995
996
		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;

Ian McDonald's avatar
Ian McDonald committed
997
998
		if (rtt_prev != hcrx->ccid3hcrx_rtt)
			ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n",
999
1000
				       dccp_role(sk), hcrx->ccid3hcrx_rtt,
				       opt_recv->dccpor_elapsed_time);
1001
1002
1003
		break;
	case DCCP_PKT_DATA:
		break;
1004
	default: /* We're not interested in other packet types, move along */
1005
1006
1007
		return;
	}

1008
	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
1009
					skb, SLAB_ATOMIC);
1010
	if (unlikely(packet == NULL)) {
1011
1012
		DCCP_WARN("%s, sk=%p, Not enough mem to add rx packet "
			  "to history, consider it lost!\n", dccp_role(sk), sk);
1013
1014
1015
		return;
	}

Ian McDonald's avatar
Ian McDonald committed
1016
	loss = ccid3_hc_rx_detect_loss(sk, packet);
1017
1018
1019
1020
1021
1022

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

	switch (hcrx->ccid3hcrx_state) {
	case TFRC_RSTATE_NO_DATA:
1023
1024
1025
1026
		ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
			       "feedback\n",
			       dccp_role(sk), sk,
			       dccp_state_name(sk->sk_state), skb);
1027
1028
1029
1030
		ccid3_hc_rx_send_feedback(sk);
		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
		return;
	case TFRC_RSTATE_DATA:
1031
1032
		hcrx->ccid3hcrx_bytes_recv += skb->len -
					      dccp_hdr(skb)->dccph_doff * 4;
Ian McDonald's avatar
Ian McDonald committed
1033
		if (loss)
1034
1035
			break;

1036
		dccp_timestamp(sk, &now);
1037
1038
1039
1040
		if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
		    hcrx->ccid3hcrx_rtt) {
			hcrx->ccid3hcrx_tstamp_last_ack = now;
			ccid3_hc_rx_send_feedback(sk);
1041
		}
1042
		return;
1043
1044
	case TFRC_RSTATE_TERM:
		DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
1045
1046
1047
1048
		return;
	}

	/* Dealing with packet loss */
1049
1050
	ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1051
1052
1053
1054

	p_prev = hcrx->ccid3hcrx_p;
	
	/* Calculate loss event rate */
1055
1056
1057
	if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
		u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);

1058
		/* Scaling up by 1000000 as fixed decimal */
1059
1060
		if (i_mean != 0)
			hcrx->ccid3hcrx_p = 1000000 / i_mean;
1061
1062
	} else
		DCCP_BUG("empty loss history");
1063
1064
1065
1066
1067
1068
1069

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

1070
static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1071
1072
{
	struct dccp_sock *dp = dccp_sk(sk);
1073
	struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1074
1075
1076

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

1077
1078
1079
	if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
	    dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
		hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1080
1081
1082
1083
1084
	else
		hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;

	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
1088
	hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
	hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1089
1090
1091
1092
1093
	return 0;
}

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

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

	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

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

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

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

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

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

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

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

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

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

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152