Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / net / dccp / options.c
1 /*
2  *  net/dccp/options.c
3  *
4  *  An implementation of the DCCP protocol
5  *  Copyright (c) 2005 Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
6  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
7  *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
8  *
9  *      This program is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU General Public License
11  *      as published by the Free Software Foundation; either version
12  *      2 of the License, or (at your option) any later version.
13  */
14 #include <linux/dccp.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/skbuff.h>
19
20 #include "ackvec.h"
21 #include "ccid.h"
22 #include "dccp.h"
23 #include "feat.h"
24
25 int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
26 int sysctl_dccp_feat_rx_ccid          = DCCPF_INITIAL_CCID;
27 int sysctl_dccp_feat_tx_ccid          = DCCPF_INITIAL_CCID;
28 int sysctl_dccp_feat_ack_ratio        = DCCPF_INITIAL_ACK_RATIO;
29 int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
30 int sysctl_dccp_feat_send_ndp_count  = DCCPF_INITIAL_SEND_NDP_COUNT;
31
32 static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
33 {
34         u32 value = 0;
35
36         if (len > 3)
37                 value += *bf++ << 24;
38         if (len > 2)
39                 value += *bf++ << 16;
40         if (len > 1)
41                 value += *bf++ << 8;
42         if (len > 0)
43                 value += *bf;
44
45         return value;
46 }
47
48 int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
49 {
50         struct dccp_sock *dp = dccp_sk(sk);
51         const struct dccp_hdr *dh = dccp_hdr(skb);
52         const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
53         u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
54         unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
55         unsigned char *opt_ptr = options;
56         const unsigned char *opt_end = (unsigned char *)dh +
57                                         (dh->dccph_doff * 4);
58         struct dccp_options_received *opt_recv = &dp->dccps_options_received;
59         unsigned char opt, len;
60         unsigned char *value;
61         u32 elapsed_time;
62         int rc;
63         int mandatory = 0;
64
65         memset(opt_recv, 0, sizeof(*opt_recv));
66
67         opt = len = 0;
68         while (opt_ptr != opt_end) {
69                 opt   = *opt_ptr++;
70                 len   = 0;
71                 value = NULL;
72
73                 /* Check if this isn't a single byte option */
74                 if (opt > DCCPO_MAX_RESERVED) {
75                         if (opt_ptr == opt_end)
76                                 goto out_invalid_option;
77
78                         len = *opt_ptr++;
79                         if (len < 3)
80                                 goto out_invalid_option;
81                         /*
82                          * Remove the type and len fields, leaving
83                          * just the value size
84                          */
85                         len     -= 2;
86                         value   = opt_ptr;
87                         opt_ptr += len;
88
89                         if (opt_ptr > opt_end)
90                                 goto out_invalid_option;
91                 }
92
93                 switch (opt) {
94                 case DCCPO_PADDING:
95                         break;
96                 case DCCPO_MANDATORY:
97                         if (mandatory)
98                                 goto out_invalid_option;
99                         if (pkt_type != DCCP_PKT_DATA)
100                                 mandatory = 1;
101                         break;
102                 case DCCPO_NDP_COUNT:
103                         if (len > 3)
104                                 goto out_invalid_option;
105
106                         opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
107                         dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk),
108                                       opt_recv->dccpor_ndp);
109                         break;
110                 case DCCPO_CHANGE_L:
111                         /* fall through */
112                 case DCCPO_CHANGE_R:
113                         if (len < 2)
114                                 goto out_invalid_option;
115                         rc = dccp_feat_change_recv(sk, opt, *value, value + 1,
116                                                    len - 1);
117                         /*
118                          * When there is a change error, change_recv is
119                          * responsible for dealing with it.  i.e. reply with an
120                          * empty confirm.
121                          * If the change was mandatory, then we need to die.
122                          */
123                         if (rc && mandatory)
124                                 goto out_invalid_option;
125                         break;
126                 case DCCPO_CONFIRM_L:
127                         /* fall through */
128                 case DCCPO_CONFIRM_R:
129                         if (len < 2)
130                                 goto out_invalid_option;
131                         if (dccp_feat_confirm_recv(sk, opt, *value,
132                                                    value + 1, len - 1))
133                                 goto out_invalid_option;
134                         break;
135                 case DCCPO_ACK_VECTOR_0:
136                 case DCCPO_ACK_VECTOR_1:
137                         if (pkt_type == DCCP_PKT_DATA)
138                                 break;
139
140                         if (dccp_msk(sk)->dccpms_send_ack_vector &&
141                             dccp_ackvec_parse(sk, skb, &ackno, opt, value, len))
142                                 goto out_invalid_option;
143                         break;
144                 case DCCPO_TIMESTAMP:
145                         if (len != 4)
146                                 goto out_invalid_option;
147
148                         opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value);
149
150                         dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
151                         dp->dccps_timestamp_time = ktime_get_real();
152
153                         dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
154                                       dccp_role(sk), opt_recv->dccpor_timestamp,
155                                       (unsigned long long)
156                                       DCCP_SKB_CB(skb)->dccpd_ack_seq);
157                         break;
158                 case DCCPO_TIMESTAMP_ECHO:
159                         if (len != 4 && len != 6 && len != 8)
160                                 goto out_invalid_option;
161
162                         opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value);
163
164                         dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
165                                       "ackno=%llu", dccp_role(sk),
166                                       opt_recv->dccpor_timestamp_echo,
167                                       len + 2,
168                                       (unsigned long long)
169                                       DCCP_SKB_CB(skb)->dccpd_ack_seq);
170
171
172                         if (len == 4) {
173                                 dccp_pr_debug_cat("\n");
174                                 break;
175                         }
176
177                         if (len == 6)
178                                 elapsed_time = ntohs(*(__be16 *)(value + 4));
179                         else
180                                 elapsed_time = ntohl(*(__be32 *)(value + 4));
181
182                         dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
183
184                         /* Give precedence to the biggest ELAPSED_TIME */
185                         if (elapsed_time > opt_recv->dccpor_elapsed_time)
186                                 opt_recv->dccpor_elapsed_time = elapsed_time;
187                         break;
188                 case DCCPO_ELAPSED_TIME:
189                         if (len != 2 && len != 4)
190                                 goto out_invalid_option;
191
192                         if (pkt_type == DCCP_PKT_DATA)
193                                 continue;
194
195                         if (len == 2)
196                                 elapsed_time = ntohs(*(__be16 *)value);
197                         else
198                                 elapsed_time = ntohl(*(__be32 *)value);
199
200                         if (elapsed_time > opt_recv->dccpor_elapsed_time)
201                                 opt_recv->dccpor_elapsed_time = elapsed_time;
202
203                         dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
204                                       dccp_role(sk), elapsed_time);
205                         break;
206                         /*
207                          * From RFC 4340, sec. 10.3:
208                          *
209                          *      Option numbers 128 through 191 are for
210                          *      options sent from the HC-Sender to the
211                          *      HC-Receiver; option numbers 192 through 255
212                          *      are for options sent from the HC-Receiver to
213                          *      the HC-Sender.
214                          */
215                 case 128 ... 191: {
216                         const u16 idx = value - options;
217
218                         if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
219                                                      opt, len, idx,
220                                                      value) != 0)
221                                 goto out_invalid_option;
222                 }
223                         break;
224                 case 192 ... 255: {
225                         const u16 idx = value - options;
226
227                         if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
228                                                      opt, len, idx,
229                                                      value) != 0)
230                                 goto out_invalid_option;
231                 }
232                         break;
233                 default:
234                         DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
235                                   "implemented, ignoring", sk, opt, len);
236                         break;
237                 }
238
239                 if (opt != DCCPO_MANDATORY)
240                         mandatory = 0;
241         }
242
243         /* mandatory was the last byte in option list -> reset connection */
244         if (mandatory)
245                 goto out_invalid_option;
246
247         return 0;
248
249 out_invalid_option:
250         DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
251         DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
252         DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len);
253         return -1;
254 }
255
256 EXPORT_SYMBOL_GPL(dccp_parse_options);
257
258 static void dccp_encode_value_var(const u32 value, unsigned char *to,
259                                   const unsigned int len)
260 {
261         if (len > 3)
262                 *to++ = (value & 0xFF000000) >> 24;
263         if (len > 2)
264                 *to++ = (value & 0xFF0000) >> 16;
265         if (len > 1)
266                 *to++ = (value & 0xFF00) >> 8;
267         if (len > 0)
268                 *to++ = (value & 0xFF);
269 }
270
271 static inline int dccp_ndp_len(const int ndp)
272 {
273         return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
274 }
275
276 int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
277                         const unsigned char option,
278                         const void *value, const unsigned char len)
279 {
280         unsigned char *to;
281
282         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
283                 return -1;
284
285         DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
286
287         to    = skb_push(skb, len + 2);
288         *to++ = option;
289         *to++ = len + 2;
290
291         memcpy(to, value, len);
292         return 0;
293 }
294
295 EXPORT_SYMBOL_GPL(dccp_insert_option);
296
297 static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
298 {
299         struct dccp_sock *dp = dccp_sk(sk);
300         int ndp = dp->dccps_ndp_count;
301
302         if (dccp_non_data_packet(skb))
303                 ++dp->dccps_ndp_count;
304         else
305                 dp->dccps_ndp_count = 0;
306
307         if (ndp > 0) {
308                 unsigned char *ptr;
309                 const int ndp_len = dccp_ndp_len(ndp);
310                 const int len = ndp_len + 2;
311
312                 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
313                         return -1;
314
315                 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
316
317                 ptr = skb_push(skb, len);
318                 *ptr++ = DCCPO_NDP_COUNT;
319                 *ptr++ = len;
320                 dccp_encode_value_var(ndp, ptr, ndp_len);
321         }
322
323         return 0;
324 }
325
326 static inline int dccp_elapsed_time_len(const u32 elapsed_time)
327 {
328         return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
329 }
330
331 int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb,
332                                     u32 elapsed_time)
333 {
334         const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
335         const int len = 2 + elapsed_time_len;
336         unsigned char *to;
337
338         if (elapsed_time_len == 0)
339                 return 0;
340
341         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
342                 return -1;
343
344         DCCP_SKB_CB(skb)->dccpd_opt_len += len;
345
346         to    = skb_push(skb, len);
347         *to++ = DCCPO_ELAPSED_TIME;
348         *to++ = len;
349
350         if (elapsed_time_len == 2) {
351                 const __be16 var16 = htons((u16)elapsed_time);
352                 memcpy(to, &var16, 2);
353         } else {
354                 const __be32 var32 = htonl(elapsed_time);
355                 memcpy(to, &var32, 4);
356         }
357
358         return 0;
359 }
360
361 EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
362
363 int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
364 {
365         __be32 now = htonl(dccp_timestamp());
366         /* yes this will overflow but that is the point as we want a
367          * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
368
369         return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
370 }
371
372 EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
373
374 static int dccp_insert_option_timestamp_echo(struct sock *sk,
375                                              struct sk_buff *skb)
376 {
377         struct dccp_sock *dp = dccp_sk(sk);
378         __be32 tstamp_echo;
379         int len, elapsed_time_len;
380         unsigned char *to;
381         const suseconds_t delta = ktime_us_delta(ktime_get_real(),
382                                                  dp->dccps_timestamp_time);
383         u32 elapsed_time = delta / 10;
384         elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
385         len = 6 + elapsed_time_len;
386
387         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
388                 return -1;
389
390         DCCP_SKB_CB(skb)->dccpd_opt_len += len;
391
392         to    = skb_push(skb, len);
393         *to++ = DCCPO_TIMESTAMP_ECHO;
394         *to++ = len;
395
396         tstamp_echo = htonl(dp->dccps_timestamp_echo);
397         memcpy(to, &tstamp_echo, 4);
398         to += 4;
399
400         if (elapsed_time_len == 2) {
401                 const __be16 var16 = htons((u16)elapsed_time);
402                 memcpy(to, &var16, 2);
403         } else if (elapsed_time_len == 4) {
404                 const __be32 var32 = htonl(elapsed_time);
405                 memcpy(to, &var32, 4);
406         }
407
408         dp->dccps_timestamp_echo = 0;
409         dp->dccps_timestamp_time = ktime_set(0, 0);
410         return 0;
411 }
412
413 static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
414                                 u8 *val, u8 len)
415 {
416         u8 *to;
417
418         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 3 > DCCP_MAX_OPT_LEN) {
419                 DCCP_WARN("packet too small for feature %d option!\n", feat);
420                 return -1;
421         }
422
423         DCCP_SKB_CB(skb)->dccpd_opt_len += len + 3;
424
425         to    = skb_push(skb, len + 3);
426         *to++ = type;
427         *to++ = len + 3;
428         *to++ = feat;
429
430         if (len)
431                 memcpy(to, val, len);
432
433         dccp_pr_debug("%s(%s (%d), ...), length %d\n",
434                       dccp_feat_typename(type),
435                       dccp_feat_name(feat), feat, len);
436         return 0;
437 }
438
439 static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
440 {
441         struct dccp_sock *dp = dccp_sk(sk);
442         struct dccp_minisock *dmsk = dccp_msk(sk);
443         struct dccp_opt_pend *opt, *next;
444         int change = 0;
445
446         /* confirm any options [NN opts] */
447         list_for_each_entry_safe(opt, next, &dmsk->dccpms_conf, dccpop_node) {
448                 dccp_insert_feat_opt(skb, opt->dccpop_type,
449                                      opt->dccpop_feat, opt->dccpop_val,
450                                      opt->dccpop_len);
451                 /* fear empty confirms */
452                 if (opt->dccpop_val)
453                         kfree(opt->dccpop_val);
454                 kfree(opt);
455         }
456         INIT_LIST_HEAD(&dmsk->dccpms_conf);
457
458         /* see which features we need to send */
459         list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
460                 /* see if we need to send any confirm */
461                 if (opt->dccpop_sc) {
462                         dccp_insert_feat_opt(skb, opt->dccpop_type + 1,
463                                              opt->dccpop_feat,
464                                              opt->dccpop_sc->dccpoc_val,
465                                              opt->dccpop_sc->dccpoc_len);
466
467                         BUG_ON(!opt->dccpop_sc->dccpoc_val);
468                         kfree(opt->dccpop_sc->dccpoc_val);
469                         kfree(opt->dccpop_sc);
470                         opt->dccpop_sc = NULL;
471                 }
472
473                 /* any option not confirmed, re-send it */
474                 if (!opt->dccpop_conf) {
475                         dccp_insert_feat_opt(skb, opt->dccpop_type,
476                                              opt->dccpop_feat, opt->dccpop_val,
477                                              opt->dccpop_len);
478                         change++;
479                 }
480         }
481
482         /* Retransmit timer.
483          * If this is the master listening sock, we don't set a timer on it.  It
484          * should be fine because if the dude doesn't receive our RESPONSE
485          * [which will contain the CHANGE] he will send another REQUEST which
486          * will "retrnasmit" the change.
487          */
488         if (change && dp->dccps_role != DCCP_ROLE_LISTEN) {
489                 dccp_pr_debug("reset feat negotiation timer %p\n", sk);
490
491                 /* XXX don't reset the timer on re-transmissions.  I.e. reset it
492                  * only when sending new stuff i guess.  Currently the timer
493                  * never backs off because on re-transmission it just resets it!
494                  */
495                 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
496                                           inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
497         }
498
499         return 0;
500 }
501
502 int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
503 {
504         struct dccp_sock *dp = dccp_sk(sk);
505         struct dccp_minisock *dmsk = dccp_msk(sk);
506
507         DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
508
509         if (dmsk->dccpms_send_ndp_count &&
510             dccp_insert_option_ndp(sk, skb))
511                 return -1;
512
513         if (!dccp_packet_without_ack(skb)) {
514                 if (dmsk->dccpms_send_ack_vector &&
515                     dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
516                     dccp_insert_option_ackvec(sk, skb))
517                         return -1;
518
519                 if (dp->dccps_timestamp_echo != 0 &&
520                     dccp_insert_option_timestamp_echo(sk, skb))
521                         return -1;
522         }
523
524         if (dp->dccps_hc_rx_insert_options) {
525                 if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
526                         return -1;
527                 dp->dccps_hc_rx_insert_options = 0;
528         }
529
530         /* Feature negotiation */
531         /* Data packets can't do feat negotiation */
532         if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA &&
533             DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATAACK &&
534             dccp_insert_options_feat(sk, skb))
535                 return -1;
536
537         /*
538          * Obtain RTT sample from Request/Response exchange.
539          * This is currently used in CCID 3 initialisation.
540          */
541         if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST &&
542             dccp_insert_option_timestamp(sk, skb))
543                 return -1;
544
545         /* XXX: insert other options when appropriate */
546
547         if (DCCP_SKB_CB(skb)->dccpd_opt_len != 0) {
548                 /* The length of all options has to be a multiple of 4 */
549                 int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
550
551                 if (padding != 0) {
552                         padding = 4 - padding;
553                         memset(skb_push(skb, padding), 0, padding);
554                         DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
555                 }
556         }
557
558         return 0;
559 }