Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[sfrench/cifs-2.6.git] / net / dccp / ccids / ccid3.c
1 /*
2  *  net/dccp/ccids/ccid3.c
3  *
4  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
5  *  Copyright (c) 2005-6 Ian McDonald <imcdnzl@gmail.com>
6  *
7  *  An implementation of the DCCP protocol
8  *
9  *  This code has been developed by the University of Waikato WAND
10  *  research group. For further information please see http://www.wand.net.nz/
11  *
12  *  This code also uses code from Lulea University, rereleased as GPL by its
13  *  authors:
14  *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
15  *
16  *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft
17  *  and to make it work as a loadable module in the DCCP stack written by
18  *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
19  *
20  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
21  *
22  *  This program is free software; you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation; either version 2 of the License, or
25  *  (at your option) any later version.
26  *
27  *  This program is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with this program; if not, write to the Free Software
34  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35  */
36
37 #include "../ccid.h"
38 #include "../dccp.h"
39 #include "lib/packet_history.h"
40 #include "lib/loss_interval.h"
41 #include "lib/tfrc.h"
42 #include "ccid3.h"
43
44 /*
45  * Reason for maths here is to avoid 32 bit overflow when a is big.
46  * With this we get close to the limit.
47  */
48 static u32 usecs_div(const u32 a, const u32 b)
49 {
50         const u32 div = a < (UINT_MAX / (USEC_PER_SEC /    10)) ?    10 :
51                         a < (UINT_MAX / (USEC_PER_SEC /    50)) ?    50 :
52                         a < (UINT_MAX / (USEC_PER_SEC /   100)) ?   100 :
53                         a < (UINT_MAX / (USEC_PER_SEC /   500)) ?   500 :
54                         a < (UINT_MAX / (USEC_PER_SEC /  1000)) ?  1000 :
55                         a < (UINT_MAX / (USEC_PER_SEC /  5000)) ?  5000 :
56                         a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
57                         a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
58                                                                  100000;
59         const u32 tmp = a * (USEC_PER_SEC / div);
60         return (b >= 2 * div) ? tmp / (b / div) : tmp;
61 }
62
63 static int ccid3_debug;
64
65 #ifdef CCID3_DEBUG
66 #define ccid3_pr_debug(format, a...) \
67         do { if (ccid3_debug) \
68                 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
69         } while (0)
70 #else
71 #define ccid3_pr_debug(format, a...)
72 #endif
73
74 static struct dccp_tx_hist *ccid3_tx_hist;
75 static struct dccp_rx_hist *ccid3_rx_hist;
76 static struct dccp_li_hist *ccid3_li_hist;
77
78 /* TFRC sender states */
79 enum ccid3_hc_tx_states {
80         TFRC_SSTATE_NO_SENT = 1,
81         TFRC_SSTATE_NO_FBACK,
82         TFRC_SSTATE_FBACK,
83         TFRC_SSTATE_TERM,
84 };
85
86 #ifdef CCID3_DEBUG
87 static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
88 {
89         static char *ccid3_state_names[] = {
90         [TFRC_SSTATE_NO_SENT]  = "NO_SENT",
91         [TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
92         [TFRC_SSTATE_FBACK]    = "FBACK",
93         [TFRC_SSTATE_TERM]     = "TERM",
94         };
95
96         return ccid3_state_names[state];
97 }
98 #endif
99
100 static void ccid3_hc_tx_set_state(struct sock *sk,
101                                   enum ccid3_hc_tx_states state)
102 {
103         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
104         enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
105
106         ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
107                        dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
108                        ccid3_tx_state_name(state));
109         WARN_ON(state == oldstate);
110         hctx->ccid3hctx_state = state;
111 }
112
113 /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
114 static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
115 {
116         /*
117          * If no feedback spec says t_ipi is 1 second (set elsewhere and then
118          * doubles after every no feedback timer (separate function)
119          */
120         if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
121                 hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s,
122                                                   hctx->ccid3hctx_x);
123 }
124
125 /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
126 static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
127 {
128         hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
129                                            TFRC_OPSYS_HALF_TIME_GRAN);
130 }
131
132 /*
133  * Update X by
134  *    If (p > 0)
135  *       x_calc = calcX(s, R, p);
136  *       X = max(min(X_calc, 2 * X_recv), s / t_mbi);
137  *    Else
138  *       If (now - tld >= R)
139  *          X = max(min(2 * X, 2 * X_recv), s / R);
140  *          tld = now;
141  */ 
142 static void ccid3_hc_tx_update_x(struct sock *sk)
143 {
144         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
145
146         /* To avoid large error in calcX */
147         if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
148                 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
149                                                      hctx->ccid3hctx_rtt,
150                                                      hctx->ccid3hctx_p);
151                 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc,
152                                                           2 * hctx->ccid3hctx_x_recv),
153                                                (hctx->ccid3hctx_s /
154                                                 TFRC_MAX_BACK_OFF_TIME));
155         } else {
156                 struct timeval now;
157
158                 dccp_timestamp(sk, &now);
159                 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
160                     hctx->ccid3hctx_rtt) {
161                         hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv,
162                                                                   hctx->ccid3hctx_x) * 2,
163                                                        usecs_div(hctx->ccid3hctx_s,
164                                                                  hctx->ccid3hctx_rtt));
165                         hctx->ccid3hctx_t_ld = now;
166                 }
167         }
168 }
169
170 static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
171 {
172         struct sock *sk = (struct sock *)data;
173         unsigned long next_tmout = 0;
174         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
175
176         bh_lock_sock(sk);
177         if (sock_owned_by_user(sk)) {
178                 /* Try again later. */
179                 /* XXX: set some sensible MIB */
180                 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
181                                jiffies + HZ / 5);
182                 goto out;
183         }
184
185         ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
186                        ccid3_tx_state_name(hctx->ccid3hctx_state));
187         
188         switch (hctx->ccid3hctx_state) {
189         case TFRC_SSTATE_TERM:
190                 goto out;
191         case TFRC_SSTATE_NO_FBACK:
192                 /* Halve send rate */
193                 hctx->ccid3hctx_x /= 2;
194                 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s /
195                                          TFRC_MAX_BACK_OFF_TIME))
196                         hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
197                                              TFRC_MAX_BACK_OFF_TIME);
198
199                 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d "
200                                "bytes/s\n",
201                                dccp_role(sk), sk,
202                                ccid3_tx_state_name(hctx->ccid3hctx_state),
203                                hctx->ccid3hctx_x);
204                 next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s,
205                                                       hctx->ccid3hctx_x),
206                                         TFRC_INITIAL_TIMEOUT);
207                 /*
208                  * FIXME - not sure above calculation is correct. See section
209                  * 5 of CCID3 11 should adjust tx_t_ipi and double that to
210                  * achieve it really
211                  */
212                 break;
213         case TFRC_SSTATE_FBACK:
214                 /*
215                  * Check if IDLE since last timeout and recv rate is less than
216                  * 4 packets per RTT
217                  */
218                 if (!hctx->ccid3hctx_idle ||
219                     (hctx->ccid3hctx_x_recv >=
220                      4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) {
221                         ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
222                                        dccp_role(sk), sk,
223                                        ccid3_tx_state_name(hctx->ccid3hctx_state));
224                         /* Halve sending rate */
225
226                         /*  If (X_calc > 2 * X_recv)
227                          *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
228                          *  Else
229                          *    X_recv = X_calc / 4;
230                          */
231                         BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P &&
232                                hctx->ccid3hctx_x_calc == 0);
233
234                         /* check also if p is zero -> x_calc is infinity? */
235                         if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
236                             hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
237                                 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
238                                                                     hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
239                         else
240                                 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
241
242                         /* Update sending rate */
243                         ccid3_hc_tx_update_x(sk);
244                 }
245                 /*
246                  * Schedule no feedback timer to expire in
247                  * max(4 * R, 2 * s / X)
248                  */
249                 next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 
250                                         2 * usecs_div(hctx->ccid3hctx_s,
251                                                       hctx->ccid3hctx_x));
252                 break;
253         default:
254                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
255                        __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
256                 dump_stack();
257                 goto out;
258         }
259
260         sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
261                       jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
262         hctx->ccid3hctx_idle = 1;
263 out:
264         bh_unlock_sock(sk);
265         sock_put(sk);
266 }
267
268 static int ccid3_hc_tx_send_packet(struct sock *sk,
269                                    struct sk_buff *skb, int len)
270 {
271         struct dccp_sock *dp = dccp_sk(sk);
272         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
273         struct dccp_tx_hist_entry *new_packet;
274         struct timeval now;
275         long delay;
276         int rc = -ENOTCONN;
277
278         BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
279
280         /* Check if pure ACK or Terminating*/
281         /*
282          * XXX: We only call this function for DATA and DATAACK, on, these
283          * packets can have zero length, but why the comment about "pure ACK"?
284          */
285         if (unlikely(len == 0))
286                 goto out;
287
288         /* See if last packet allocated was not sent */
289         new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
290         if (new_packet == NULL || new_packet->dccphtx_sent) {
291                 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
292                                                     SLAB_ATOMIC);
293
294                 rc = -ENOBUFS;
295                 if (unlikely(new_packet == NULL)) {
296                         LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough "
297                                        "mem to add to history, send refused\n",
298                                        __FUNCTION__, dccp_role(sk), sk);
299                         goto out;
300                 }
301
302                 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
303         }
304
305         dccp_timestamp(sk, &now);
306
307         switch (hctx->ccid3hctx_state) {
308         case TFRC_SSTATE_NO_SENT:
309                 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
310                                jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
311                 hctx->ccid3hctx_last_win_count   = 0;
312                 hctx->ccid3hctx_t_last_win_count = now;
313                 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
314                 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
315
316                 /* Set nominal send time for initial packet */
317                 hctx->ccid3hctx_t_nom = now;
318                 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
319                                   hctx->ccid3hctx_t_ipi);
320                 ccid3_calc_new_delta(hctx);
321                 rc = 0;
322                 break;
323         case TFRC_SSTATE_NO_FBACK:
324         case TFRC_SSTATE_FBACK:
325                 delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
326                          hctx->ccid3hctx_delta);
327                 delay /= -1000;
328                 /* divide by -1000 is to convert to ms and get sign right */
329                 rc = delay > 0 ? delay : 0;
330                 break;
331         default:
332                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
333                        __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
334                 dump_stack();
335                 rc = -EINVAL;
336                 break;
337         }
338
339         /* Can we send? if so add options and add to packet history */
340         if (rc == 0) {
341                 dp->dccps_hc_tx_insert_options = 1;
342                 new_packet->dccphtx_ccval =
343                         DCCP_SKB_CB(skb)->dccpd_ccval =
344                                 hctx->ccid3hctx_last_win_count;
345         }
346 out:
347         return rc;
348 }
349
350 static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
351 {
352         const struct dccp_sock *dp = dccp_sk(sk);
353         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
354         struct timeval now;
355
356         BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
357
358         dccp_timestamp(sk, &now);
359
360         /* check if we have sent a data packet */
361         if (len > 0) {
362                 unsigned long quarter_rtt;
363                 struct dccp_tx_hist_entry *packet;
364
365                 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
366                 if (unlikely(packet == NULL)) {
367                         LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
368                                        "exists in history!\n", __FUNCTION__);
369                         return;
370                 }
371                 if (unlikely(packet->dccphtx_sent)) {
372                         LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
373                                        "history!\n", __FUNCTION__);
374                         return;
375                 }
376                 packet->dccphtx_tstamp = now;
377                 packet->dccphtx_seqno  = dp->dccps_gss;
378                 /*
379                  * Check if win_count have changed
380                  * Algorithm in "8.1. Window Counter Valuer" in
381                  * draft-ietf-dccp-ccid3-11.txt
382                  */
383                 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
384                 if (likely(hctx->ccid3hctx_rtt > 8))
385                         quarter_rtt /= hctx->ccid3hctx_rtt / 4;
386
387                 if (quarter_rtt > 0) {
388                         hctx->ccid3hctx_t_last_win_count = now;
389                         hctx->ccid3hctx_last_win_count   = (hctx->ccid3hctx_last_win_count +
390                                                             min_t(unsigned long, quarter_rtt, 5)) % 16;
391                         ccid3_pr_debug("%s, sk=%p, window changed from "
392                                        "%u to %u!\n",
393                                        dccp_role(sk), sk,
394                                        packet->dccphtx_ccval,
395                                        hctx->ccid3hctx_last_win_count);
396                 }
397
398                 hctx->ccid3hctx_idle = 0;
399                 packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
400                 packet->dccphtx_sent = 1;
401         } else
402                 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
403                                dccp_role(sk), sk, dp->dccps_gss);
404
405         switch (hctx->ccid3hctx_state) {
406         case TFRC_SSTATE_NO_SENT:
407                 /* if first wasn't pure ack */
408                 if (len != 0)
409                         printk(KERN_CRIT "%s: %s, First packet sent is noted "
410                                          "as a data packet\n",
411                                __FUNCTION__, dccp_role(sk));
412                 return;
413         case TFRC_SSTATE_NO_FBACK:
414         case TFRC_SSTATE_FBACK:
415                 if (len > 0) {
416                         hctx->ccid3hctx_t_nom = now;
417                         ccid3_calc_new_t_ipi(hctx);
418                         ccid3_calc_new_delta(hctx);
419                         timeval_add_usecs(&hctx->ccid3hctx_t_nom,
420                                           hctx->ccid3hctx_t_ipi);
421                 }
422                 break;
423         default:
424                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
425                        __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
426                 dump_stack();
427                 break;
428         }
429 }
430
431 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
432 {
433         const struct dccp_sock *dp = dccp_sk(sk);
434         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
435         struct ccid3_options_received *opt_recv;
436         struct dccp_tx_hist_entry *packet;
437         struct timeval now;
438         unsigned long next_tmout; 
439         u32 t_elapsed;
440         u32 pinv;
441         u32 x_recv;
442         u32 r_sample;
443
444         BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
445
446         /* we are only interested in ACKs */
447         if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
448               DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
449                 return;
450
451         opt_recv = &hctx->ccid3hctx_options_received;
452
453         t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
454         x_recv = opt_recv->ccid3or_receive_rate;
455         pinv = opt_recv->ccid3or_loss_event_rate;
456
457         switch (hctx->ccid3hctx_state) {
458         case TFRC_SSTATE_NO_SENT:
459                 /* FIXME: what to do here? */
460                 return;
461         case TFRC_SSTATE_NO_FBACK:
462         case TFRC_SSTATE_FBACK:
463                 /* Calculate new round trip sample by
464                  * R_sample = (now - t_recvdata) - t_delay */
465                 /* get t_recvdata from history */
466                 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
467                                                  DCCP_SKB_CB(skb)->dccpd_ack_seq);
468                 if (unlikely(packet == NULL)) {
469                         LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno "
470                                        "%llu(%s) does't exist in history!\n",
471                                        __FUNCTION__, dccp_role(sk), sk,
472                             (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
473                                 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
474                         return;
475                 }
476
477                 /* Update RTT */
478                 dccp_timestamp(sk, &now);
479                 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
480                 if (unlikely(r_sample <= t_elapsed))
481                         LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
482                                        "t_elapsed=%uus\n",
483                                        __FUNCTION__, r_sample, t_elapsed);
484                 else
485                         r_sample -= t_elapsed;
486
487                 /* Update RTT estimate by 
488                  * If (No feedback recv)
489                  *    R = R_sample;
490                  * Else
491                  *    R = q * R + (1 - q) * R_sample;
492                  *
493                  * q is a constant, RFC 3448 recomments 0.9
494                  */
495                 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
496                         ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
497                         hctx->ccid3hctx_rtt = r_sample;
498                 } else
499                         hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
500                                               r_sample / 10;
501
502                 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
503                                "r_sample=%us\n", dccp_role(sk), sk,
504                                hctx->ccid3hctx_rtt, r_sample);
505
506                 /* Update timeout interval */
507                 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
508                                               USEC_PER_SEC);
509
510                 /* Update receive rate */
511                 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
512
513                 /* Update loss event rate */
514                 if (pinv == ~0 || pinv == 0)
515                         hctx->ccid3hctx_p = 0;
516                 else {
517                         hctx->ccid3hctx_p = 1000000 / pinv;
518
519                         if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
520                                 hctx->ccid3hctx_p = TFRC_SMALLEST_P;
521                                 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n",
522                                                dccp_role(sk), sk);
523                         }
524                 }
525
526                 /* unschedule no feedback timer */
527                 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
528
529                 /* Update sending rate */
530                 ccid3_hc_tx_update_x(sk);
531
532                 /* Update next send time */
533                 timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
534                                   hctx->ccid3hctx_t_ipi);
535                 ccid3_calc_new_t_ipi(hctx);
536                 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
537                                   hctx->ccid3hctx_t_ipi);
538                 ccid3_calc_new_delta(hctx);
539
540                 /* remove all packets older than the one acked from history */
541                 dccp_tx_hist_purge_older(ccid3_tx_hist,
542                                          &hctx->ccid3hctx_hist, packet);
543                 /*
544                  * As we have calculated new ipi, delta, t_nom it is possible that
545                  * we now can send a packet, so wake up dccp_wait_for_ccids.
546                  */
547                 sk->sk_write_space(sk);
548
549                 /*
550                  * Schedule no feedback timer to expire in
551                  * max(4 * R, 2 * s / X)
552                  */
553                 next_tmout = max(hctx->ccid3hctx_t_rto,
554                                  2 * usecs_div(hctx->ccid3hctx_s,
555                                                hctx->ccid3hctx_x));
556                         
557                 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
558                                "expire in %lu jiffies (%luus)\n",
559                                dccp_role(sk), sk,
560                                usecs_to_jiffies(next_tmout), next_tmout); 
561
562                 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
563                                jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
564
565                 /* set idle flag */
566                 hctx->ccid3hctx_idle = 1;   
567                 break;
568         default:
569                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
570                        __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
571                 dump_stack();
572                 break;
573         }
574 }
575
576 static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
577 {
578         const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
579
580         BUG_ON(hctx == NULL);
581
582         if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
583                 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
584         return 0;
585 }
586
587 static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
588                                      unsigned char len, u16 idx,
589                                      unsigned char *value)
590 {
591         int rc = 0;
592         const struct dccp_sock *dp = dccp_sk(sk);
593         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
594         struct ccid3_options_received *opt_recv;
595
596         BUG_ON(hctx == NULL);
597
598         opt_recv = &hctx->ccid3hctx_options_received;
599
600         if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
601                 opt_recv->ccid3or_seqno              = dp->dccps_gsr;
602                 opt_recv->ccid3or_loss_event_rate    = ~0;
603                 opt_recv->ccid3or_loss_intervals_idx = 0;
604                 opt_recv->ccid3or_loss_intervals_len = 0;
605                 opt_recv->ccid3or_receive_rate       = 0;
606         }
607
608         switch (option) {
609         case TFRC_OPT_LOSS_EVENT_RATE:
610                 if (unlikely(len != 4)) {
611                         LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
612                                        "len for TFRC_OPT_LOSS_EVENT_RATE\n",
613                                        __FUNCTION__, dccp_role(sk), sk);
614                         rc = -EINVAL;
615                 } else {
616                         opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
617                         ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
618                                        dccp_role(sk), sk,
619                                        opt_recv->ccid3or_loss_event_rate);
620                 }
621                 break;
622         case TFRC_OPT_LOSS_INTERVALS:
623                 opt_recv->ccid3or_loss_intervals_idx = idx;
624                 opt_recv->ccid3or_loss_intervals_len = len;
625                 ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
626                                dccp_role(sk), sk,
627                                opt_recv->ccid3or_loss_intervals_idx,
628                                opt_recv->ccid3or_loss_intervals_len);
629                 break;
630         case TFRC_OPT_RECEIVE_RATE:
631                 if (unlikely(len != 4)) {
632                         LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
633                                        "len for TFRC_OPT_RECEIVE_RATE\n",
634                                        __FUNCTION__, dccp_role(sk), sk);
635                         rc = -EINVAL;
636                 } else {
637                         opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
638                         ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
639                                        dccp_role(sk), sk,
640                                        opt_recv->ccid3or_receive_rate);
641                 }
642                 break;
643         }
644
645         return rc;
646 }
647
648 static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
649 {
650         struct dccp_sock *dp = dccp_sk(sk);
651         struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
652
653         if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
654             dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
655                 hctx->ccid3hctx_s = dp->dccps_packet_size;
656         else
657                 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
658
659         /* Set transmission rate to 1 packet per second */
660         hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
661         hctx->ccid3hctx_t_rto = USEC_PER_SEC;
662         hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
663         INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
664
665         hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
666         hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
667         init_timer(&hctx->ccid3hctx_no_feedback_timer);
668
669         return 0;
670 }
671
672 static void ccid3_hc_tx_exit(struct sock *sk)
673 {
674         struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
675
676         BUG_ON(hctx == NULL);
677
678         ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
679         sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
680
681         /* Empty packet history */
682         dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
683 }
684
685 /*
686  * RX Half Connection methods
687  */
688
689 /* TFRC receiver states */
690 enum ccid3_hc_rx_states {
691         TFRC_RSTATE_NO_DATA = 1,
692         TFRC_RSTATE_DATA,
693         TFRC_RSTATE_TERM    = 127,
694 };
695
696 #ifdef CCID3_DEBUG
697 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
698 {
699         static char *ccid3_rx_state_names[] = {
700         [TFRC_RSTATE_NO_DATA] = "NO_DATA",
701         [TFRC_RSTATE_DATA]    = "DATA",
702         [TFRC_RSTATE_TERM]    = "TERM",
703         };
704
705         return ccid3_rx_state_names[state];
706 }
707 #endif
708
709 static void ccid3_hc_rx_set_state(struct sock *sk,
710                                   enum ccid3_hc_rx_states state)
711 {
712         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
713         enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
714
715         ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
716                        dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
717                        ccid3_rx_state_name(state));
718         WARN_ON(state == oldstate);
719         hcrx->ccid3hcrx_state = state;
720 }
721
722 static void ccid3_hc_rx_send_feedback(struct sock *sk)
723 {
724         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
725         struct dccp_sock *dp = dccp_sk(sk);
726         struct dccp_rx_hist_entry *packet;
727         struct timeval now;
728
729         ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
730
731         dccp_timestamp(sk, &now);
732
733         switch (hcrx->ccid3hcrx_state) {
734         case TFRC_RSTATE_NO_DATA:
735                 hcrx->ccid3hcrx_x_recv = 0;
736                 break;
737         case TFRC_RSTATE_DATA: {
738                 const u32 delta = timeval_delta(&now,
739                                         &hcrx->ccid3hcrx_tstamp_last_feedback);
740                 hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
741                                                    delta);
742         }
743                 break;
744         default:
745                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
746                        __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
747                 dump_stack();
748                 return;
749         }
750
751         packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
752         if (unlikely(packet == NULL)) {
753                 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet "
754                                "in history!\n",
755                                __FUNCTION__, dccp_role(sk), sk);
756                 return;
757         }
758
759         hcrx->ccid3hcrx_tstamp_last_feedback = now;
760         hcrx->ccid3hcrx_last_counter         = packet->dccphrx_ccval;
761         hcrx->ccid3hcrx_seqno_last_counter   = packet->dccphrx_seqno;
762         hcrx->ccid3hcrx_bytes_recv           = 0;
763
764         /* Convert to multiples of 10us */
765         hcrx->ccid3hcrx_elapsed_time =
766                         timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
767         if (hcrx->ccid3hcrx_p == 0)
768                 hcrx->ccid3hcrx_pinv = ~0;
769         else
770                 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
771         dp->dccps_hc_rx_insert_options = 1;
772         dccp_send_ack(sk);
773 }
774
775 static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
776 {
777         const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
778         __be32 x_recv, pinv;
779
780         BUG_ON(hcrx == NULL);
781
782         if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
783                 return 0;
784
785         DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
786
787         if (dccp_packet_without_ack(skb))
788                 return 0;
789
790         x_recv = htonl(hcrx->ccid3hcrx_x_recv);
791         pinv   = htonl(hcrx->ccid3hcrx_pinv);
792
793         if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
794              dccp_insert_option_elapsed_time(sk, skb,
795                                              hcrx->ccid3hcrx_elapsed_time)) ||
796             dccp_insert_option_timestamp(sk, skb) ||
797             dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
798                                &pinv, sizeof(pinv)) ||
799             dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
800                                &x_recv, sizeof(x_recv)))
801                 return -1;
802
803         return 0;
804 }
805
806 /* calculate first loss interval
807  *
808  * returns estimated loss interval in usecs */
809
810 static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
811 {
812         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
813         struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
814         u32 rtt, delta, x_recv, fval, p, tmp2;
815         struct timeval tstamp = { 0, };
816         int interval = 0;
817         int win_count = 0;
818         int step = 0;
819         u64 tmp1;
820
821         list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
822                                  dccphrx_node) {
823                 if (dccp_rx_hist_entry_data_packet(entry)) {
824                         tail = entry;
825
826                         switch (step) {
827                         case 0:
828                                 tstamp    = entry->dccphrx_tstamp;
829                                 win_count = entry->dccphrx_ccval;
830                                 step = 1;
831                                 break;
832                         case 1:
833                                 interval = win_count - entry->dccphrx_ccval;
834                                 if (interval < 0)
835                                         interval += TFRC_WIN_COUNT_LIMIT;
836                                 if (interval > 4)
837                                         goto found;
838                                 break;
839                         }
840                 }
841         }
842
843         if (unlikely(step == 0)) {
844                 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history "
845                                "contains no data packets!\n",
846                                __FUNCTION__, dccp_role(sk), sk);
847                 return ~0;
848         }
849
850         if (unlikely(interval == 0)) {
851                 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a "
852                                "win_count interval > 0. Defaulting to 1\n",
853                                __FUNCTION__, dccp_role(sk), sk);
854                 interval = 1;
855         }
856 found:
857         rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
858         ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
859                        dccp_role(sk), sk, rtt);
860         if (rtt == 0)
861                 rtt = 1;
862
863         dccp_timestamp(sk, &tstamp);
864         delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
865         x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
866
867         tmp1 = (u64)x_recv * (u64)rtt;
868         do_div(tmp1,10000000);
869         tmp2 = (u32)tmp1;
870         fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
871         /* do not alter order above or you will get overflow on 32 bit */
872         p = tfrc_calc_x_reverse_lookup(fval);
873         ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
874                        "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
875
876         if (p == 0)
877                 return ~0;
878         else
879                 return 1000000 / p; 
880 }
881
882 static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
883 {
884         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
885
886         if (seq_loss != DCCP_MAX_SEQNO + 1 &&
887             list_empty(&hcrx->ccid3hcrx_li_hist)) {
888                 struct dccp_li_hist_entry *li_tail;
889
890                 li_tail = dccp_li_hist_interval_new(ccid3_li_hist,
891                                                     &hcrx->ccid3hcrx_li_hist,
892                                                     seq_loss, win_loss);
893                 if (li_tail == NULL)
894                         return;
895                 li_tail->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
896         } else
897                     LIMIT_NETDEBUG(KERN_WARNING "%s: FIXME: find end of "
898                                    "interval\n", __FUNCTION__);
899 }
900
901 static void ccid3_hc_rx_detect_loss(struct sock *sk)
902 {
903         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
904         u8 win_loss;
905         const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
906                                                       &hcrx->ccid3hcrx_li_hist,
907                                                       &win_loss);
908
909         ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
910 }
911
912 static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
913 {
914         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
915         const struct dccp_options_received *opt_recv;
916         struct dccp_rx_hist_entry *packet;
917         struct timeval now;
918         u8 win_count;
919         u32 p_prev, r_sample, t_elapsed;
920         int ins;
921
922         BUG_ON(hcrx == NULL ||
923                !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
924                  hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
925
926         opt_recv = &dccp_sk(sk)->dccps_options_received;
927
928         switch (DCCP_SKB_CB(skb)->dccpd_type) {
929         case DCCP_PKT_ACK:
930                 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
931                         return;
932         case DCCP_PKT_DATAACK:
933                 if (opt_recv->dccpor_timestamp_echo == 0)
934                         break;
935                 p_prev = hcrx->ccid3hcrx_rtt;
936                 dccp_timestamp(sk, &now);
937                 timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
938                 r_sample = timeval_usecs(&now);
939                 t_elapsed = opt_recv->dccpor_elapsed_time * 10;
940
941                 if (unlikely(r_sample <= t_elapsed))
942                         LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
943                                        "t_elapsed=%uus\n",
944                                        __FUNCTION__, r_sample, t_elapsed);
945                 else
946                         r_sample -= t_elapsed;
947
948                 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
949                         hcrx->ccid3hcrx_rtt = r_sample;
950                 else
951                         hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
952                                               r_sample / 10;
953
954                 if (p_prev != hcrx->ccid3hcrx_rtt)
955                         ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
956                                        dccp_role(sk), hcrx->ccid3hcrx_rtt,
957                                        opt_recv->dccpor_elapsed_time);
958                 break;
959         case DCCP_PKT_DATA:
960                 break;
961         default: /* We're not interested in other packet types, move along */
962                 return;
963         }
964
965         packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
966                                         skb, SLAB_ATOMIC);
967         if (unlikely(packet == NULL)) {
968                 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to "
969                                 "add rx packet to history, consider it lost!\n",
970                                __FUNCTION__, dccp_role(sk), sk);
971                 return;
972         }
973
974         win_count = packet->dccphrx_ccval;
975
976         ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
977                                       &hcrx->ccid3hcrx_li_hist, packet);
978
979         if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
980                 return;
981
982         switch (hcrx->ccid3hcrx_state) {
983         case TFRC_RSTATE_NO_DATA:
984                 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
985                                "feedback\n",
986                                dccp_role(sk), sk,
987                                dccp_state_name(sk->sk_state), skb);
988                 ccid3_hc_rx_send_feedback(sk);
989                 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
990                 return;
991         case TFRC_RSTATE_DATA:
992                 hcrx->ccid3hcrx_bytes_recv += skb->len -
993                                               dccp_hdr(skb)->dccph_doff * 4;
994                 if (ins != 0)
995                         break;
996
997                 dccp_timestamp(sk, &now);
998                 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
999                     hcrx->ccid3hcrx_rtt) {
1000                         hcrx->ccid3hcrx_tstamp_last_ack = now;
1001                         ccid3_hc_rx_send_feedback(sk);
1002                 }
1003                 return;
1004         default:
1005                 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1006                        __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1007                 dump_stack();
1008                 return;
1009         }
1010
1011         /* Dealing with packet loss */
1012         ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
1013                        dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1014
1015         ccid3_hc_rx_detect_loss(sk);
1016         p_prev = hcrx->ccid3hcrx_p;
1017         
1018         /* Calculate loss event rate */
1019         if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
1020                 u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
1021
1022                 /* Scaling up by 1000000 as fixed decimal */
1023                 if (i_mean != 0)
1024                         hcrx->ccid3hcrx_p = 1000000 / i_mean;
1025         }
1026
1027         if (hcrx->ccid3hcrx_p > p_prev) {
1028                 ccid3_hc_rx_send_feedback(sk);
1029                 return;
1030         }
1031 }
1032
1033 static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1034 {
1035         struct dccp_sock *dp = dccp_sk(sk);
1036         struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1037
1038         ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1039
1040         if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
1041             dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
1042                 hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1043         else
1044                 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
1045
1046         hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
1047         INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1048         INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1049         dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1050         hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
1051         hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1052         return 0;
1053 }
1054
1055 static void ccid3_hc_rx_exit(struct sock *sk)
1056 {
1057         struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1058
1059         BUG_ON(hcrx == NULL);
1060
1061         ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
1062
1063         /* Empty packet history */
1064         dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1065
1066         /* Empty loss interval history */
1067         dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
1068 }
1069
1070 static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
1071 {
1072         const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1073
1074         /* Listen socks doesn't have a private CCID block */
1075         if (sk->sk_state == DCCP_LISTEN)
1076                 return;
1077
1078         BUG_ON(hcrx == NULL);
1079
1080         info->tcpi_ca_state     = hcrx->ccid3hcrx_state;
1081         info->tcpi_options      |= TCPI_OPT_TIMESTAMPS;
1082         info->tcpi_rcv_rtt      = hcrx->ccid3hcrx_rtt;
1083 }
1084
1085 static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
1086 {
1087         const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
1088
1089         /* Listen socks doesn't have a private CCID block */
1090         if (sk->sk_state == DCCP_LISTEN)
1091                 return;
1092
1093         BUG_ON(hctx == NULL);
1094
1095         info->tcpi_rto = hctx->ccid3hctx_t_rto;
1096         info->tcpi_rtt = hctx->ccid3hctx_rtt;
1097 }
1098
1099 static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
1100                                   u32 __user *optval, int __user *optlen)
1101 {
1102         const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1103         const void *val;
1104         
1105         /* Listen socks doesn't have a private CCID block */
1106         if (sk->sk_state == DCCP_LISTEN)
1107                 return -EINVAL;
1108
1109         switch (optname) {
1110         case DCCP_SOCKOPT_CCID_RX_INFO:
1111                 if (len < sizeof(hcrx->ccid3hcrx_tfrc))
1112                         return -EINVAL;
1113                 len = sizeof(hcrx->ccid3hcrx_tfrc);
1114                 val = &hcrx->ccid3hcrx_tfrc;
1115                 break;
1116         default:
1117                 return -ENOPROTOOPT;
1118         }
1119
1120         if (put_user(len, optlen) || copy_to_user(optval, val, len))
1121                 return -EFAULT;
1122
1123         return 0;
1124 }
1125
1126 static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
1127                                   u32 __user *optval, int __user *optlen)
1128 {
1129         const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
1130         const void *val;
1131         
1132         /* Listen socks doesn't have a private CCID block */
1133         if (sk->sk_state == DCCP_LISTEN)
1134                 return -EINVAL;
1135
1136         switch (optname) {
1137         case DCCP_SOCKOPT_CCID_TX_INFO:
1138                 if (len < sizeof(hctx->ccid3hctx_tfrc))
1139                         return -EINVAL;
1140                 len = sizeof(hctx->ccid3hctx_tfrc);
1141                 val = &hctx->ccid3hctx_tfrc;
1142                 break;
1143         default:
1144                 return -ENOPROTOOPT;
1145         }
1146
1147         if (put_user(len, optlen) || copy_to_user(optval, val, len))
1148                 return -EFAULT;
1149
1150         return 0;
1151 }
1152
1153 static struct ccid_operations ccid3 = {
1154         .ccid_id                   = 3,
1155         .ccid_name                 = "ccid3",
1156         .ccid_owner                = THIS_MODULE,
1157         .ccid_hc_tx_obj_size       = sizeof(struct ccid3_hc_tx_sock),
1158         .ccid_hc_tx_init           = ccid3_hc_tx_init,
1159         .ccid_hc_tx_exit           = ccid3_hc_tx_exit,
1160         .ccid_hc_tx_send_packet    = ccid3_hc_tx_send_packet,
1161         .ccid_hc_tx_packet_sent    = ccid3_hc_tx_packet_sent,
1162         .ccid_hc_tx_packet_recv    = ccid3_hc_tx_packet_recv,
1163         .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
1164         .ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
1165         .ccid_hc_rx_obj_size       = sizeof(struct ccid3_hc_rx_sock),
1166         .ccid_hc_rx_init           = ccid3_hc_rx_init,
1167         .ccid_hc_rx_exit           = ccid3_hc_rx_exit,
1168         .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
1169         .ccid_hc_rx_packet_recv    = ccid3_hc_rx_packet_recv,
1170         .ccid_hc_rx_get_info       = ccid3_hc_rx_get_info,
1171         .ccid_hc_tx_get_info       = ccid3_hc_tx_get_info,
1172         .ccid_hc_rx_getsockopt     = ccid3_hc_rx_getsockopt,
1173         .ccid_hc_tx_getsockopt     = ccid3_hc_tx_getsockopt,
1174 };
1175  
1176 module_param(ccid3_debug, int, 0444);
1177 MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
1178
1179 static __init int ccid3_module_init(void)
1180 {
1181         int rc = -ENOBUFS;
1182
1183         ccid3_rx_hist = dccp_rx_hist_new("ccid3");
1184         if (ccid3_rx_hist == NULL)
1185                 goto out;
1186
1187         ccid3_tx_hist = dccp_tx_hist_new("ccid3");
1188         if (ccid3_tx_hist == NULL)
1189                 goto out_free_rx;
1190
1191         ccid3_li_hist = dccp_li_hist_new("ccid3");
1192         if (ccid3_li_hist == NULL)
1193                 goto out_free_tx;
1194
1195         rc = ccid_register(&ccid3);
1196         if (rc != 0) 
1197                 goto out_free_loss_interval_history;
1198 out:
1199         return rc;
1200
1201 out_free_loss_interval_history:
1202         dccp_li_hist_delete(ccid3_li_hist);
1203         ccid3_li_hist = NULL;
1204 out_free_tx:
1205         dccp_tx_hist_delete(ccid3_tx_hist);
1206         ccid3_tx_hist = NULL;
1207 out_free_rx:
1208         dccp_rx_hist_delete(ccid3_rx_hist);
1209         ccid3_rx_hist = NULL;
1210         goto out;
1211 }
1212 module_init(ccid3_module_init);
1213
1214 static __exit void ccid3_module_exit(void)
1215 {
1216         ccid_unregister(&ccid3);
1217
1218         if (ccid3_tx_hist != NULL) {
1219                 dccp_tx_hist_delete(ccid3_tx_hist);
1220                 ccid3_tx_hist = NULL;
1221         }
1222         if (ccid3_rx_hist != NULL) {
1223                 dccp_rx_hist_delete(ccid3_rx_hist);
1224                 ccid3_rx_hist = NULL;
1225         }
1226         if (ccid3_li_hist != NULL) {
1227                 dccp_li_hist_delete(ccid3_li_hist);
1228                 ccid3_li_hist = NULL;
1229         }
1230 }
1231 module_exit(ccid3_module_exit);
1232
1233 MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz>, "
1234               "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
1235 MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
1236 MODULE_LICENSE("GPL");
1237 MODULE_ALIAS("net-dccp-ccid-3");