dccp: Integrate feature-negotiation insertion code
[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 <asm/unaligned.h>
18 #include <linux/kernel.h>
19 #include <linux/skbuff.h>
20
21 #include "ackvec.h"
22 #include "ccid.h"
23 #include "dccp.h"
24 #include "feat.h"
25
26 int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
27 int sysctl_dccp_feat_rx_ccid          = DCCPF_INITIAL_CCID;
28 int sysctl_dccp_feat_tx_ccid          = DCCPF_INITIAL_CCID;
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 u64 dccp_decode_value_var(const u8 *bf, const u8 len)
33 {
34         u64 value = 0;
35
36         if (len >= DCCP_OPTVAL_MAXLEN)
37                 value += ((u64)*bf++) << 40;
38         if (len > 4)
39                 value += ((u64)*bf++) << 32;
40         if (len > 3)
41                 value += ((u64)*bf++) << 24;
42         if (len > 2)
43                 value += ((u64)*bf++) << 16;
44         if (len > 1)
45                 value += ((u64)*bf++) << 8;
46         if (len > 0)
47                 value += *bf;
48
49         return value;
50 }
51
52 /**
53  * dccp_parse_options  -  Parse DCCP options present in @skb
54  * @sk: client|server|listening dccp socket (when @dreq != NULL)
55  * @dreq: request socket to use during connection setup, or NULL
56  */
57 int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
58                        struct sk_buff *skb)
59 {
60         struct dccp_sock *dp = dccp_sk(sk);
61         const struct dccp_hdr *dh = dccp_hdr(skb);
62         const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
63         u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
64         unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
65         unsigned char *opt_ptr = options;
66         const unsigned char *opt_end = (unsigned char *)dh +
67                                         (dh->dccph_doff * 4);
68         struct dccp_options_received *opt_recv = &dp->dccps_options_received;
69         unsigned char opt, len;
70         unsigned char *uninitialized_var(value);
71         u32 elapsed_time;
72         __be32 opt_val;
73         int rc;
74         int mandatory = 0;
75
76         memset(opt_recv, 0, sizeof(*opt_recv));
77
78         opt = len = 0;
79         while (opt_ptr != opt_end) {
80                 opt   = *opt_ptr++;
81                 len   = 0;
82                 value = NULL;
83
84                 /* Check if this isn't a single byte option */
85                 if (opt > DCCPO_MAX_RESERVED) {
86                         if (opt_ptr == opt_end)
87                                 goto out_nonsensical_length;
88
89                         len = *opt_ptr++;
90                         if (len < 2)
91                                 goto out_nonsensical_length;
92                         /*
93                          * Remove the type and len fields, leaving
94                          * just the value size
95                          */
96                         len     -= 2;
97                         value   = opt_ptr;
98                         opt_ptr += len;
99
100                         if (opt_ptr > opt_end)
101                                 goto out_nonsensical_length;
102                 }
103
104                 /*
105                  * CCID-Specific Options (from RFC 4340, sec. 10.3):
106                  *
107                  * Option numbers 128 through 191 are for options sent from the
108                  * HC-Sender to the HC-Receiver; option numbers 192 through 255
109                  * are for options sent from the HC-Receiver to the HC-Sender.
110                  *
111                  * CCID-specific options are ignored during connection setup, as
112                  * negotiation may still be in progress (see RFC 4340, 10.3).
113                  * The same applies to Ack Vectors, as these depend on the CCID.
114                  *
115                  */
116                 if (dreq != NULL && (opt >= 128 ||
117                     opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
118                         goto ignore_option;
119
120                 switch (opt) {
121                 case DCCPO_PADDING:
122                         break;
123                 case DCCPO_MANDATORY:
124                         if (mandatory)
125                                 goto out_invalid_option;
126                         if (pkt_type != DCCP_PKT_DATA)
127                                 mandatory = 1;
128                         break;
129                 case DCCPO_NDP_COUNT:
130                         if (len > 6)
131                                 goto out_invalid_option;
132
133                         opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
134                         dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk),
135                                       (unsigned long long)opt_recv->dccpor_ndp);
136                         break;
137                 case DCCPO_CHANGE_L:
138                         /* fall through */
139                 case DCCPO_CHANGE_R:
140                         if (pkt_type == DCCP_PKT_DATA)
141                                 break;
142                         if (len < 2)
143                                 goto out_invalid_option;
144                         rc = dccp_feat_change_recv(sk, opt, *value, value + 1,
145                                                    len - 1);
146                         /*
147                          * When there is a change error, change_recv is
148                          * responsible for dealing with it.  i.e. reply with an
149                          * empty confirm.
150                          * If the change was mandatory, then we need to die.
151                          */
152                         if (rc && mandatory)
153                                 goto out_invalid_option;
154                         break;
155                 case DCCPO_CONFIRM_L:
156                         /* fall through */
157                 case DCCPO_CONFIRM_R:
158                         if (pkt_type == DCCP_PKT_DATA)
159                                 break;
160                         if (len < 2)    /* FIXME this disallows empty confirm */
161                                 goto out_invalid_option;
162                         if (dccp_feat_confirm_recv(sk, opt, *value,
163                                                    value + 1, len - 1))
164                                 goto out_invalid_option;
165                         break;
166                 case DCCPO_ACK_VECTOR_0:
167                 case DCCPO_ACK_VECTOR_1:
168                         if (dccp_packet_without_ack(skb))   /* RFC 4340, 11.4 */
169                                 break;
170
171                         if (dccp_msk(sk)->dccpms_send_ack_vector &&
172                             dccp_ackvec_parse(sk, skb, &ackno, opt, value, len))
173                                 goto out_invalid_option;
174                         break;
175                 case DCCPO_TIMESTAMP:
176                         if (len != 4)
177                                 goto out_invalid_option;
178                         /*
179                          * RFC 4340 13.1: "The precise time corresponding to
180                          * Timestamp Value zero is not specified". We use
181                          * zero to indicate absence of a meaningful timestamp.
182                          */
183                         opt_val = get_unaligned((__be32 *)value);
184                         if (unlikely(opt_val == 0)) {
185                                 DCCP_WARN("Timestamp with zero value\n");
186                                 break;
187                         }
188
189                         if (dreq != NULL) {
190                                 dreq->dreq_timestamp_echo = ntohl(opt_val);
191                                 dreq->dreq_timestamp_time = dccp_timestamp();
192                         } else {
193                                 opt_recv->dccpor_timestamp =
194                                         dp->dccps_timestamp_echo = ntohl(opt_val);
195                                 dp->dccps_timestamp_time = dccp_timestamp();
196                         }
197                         dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
198                                       dccp_role(sk), ntohl(opt_val),
199                                       (unsigned long long)
200                                       DCCP_SKB_CB(skb)->dccpd_ack_seq);
201                         break;
202                 case DCCPO_TIMESTAMP_ECHO:
203                         if (len != 4 && len != 6 && len != 8)
204                                 goto out_invalid_option;
205
206                         opt_val = get_unaligned((__be32 *)value);
207                         opt_recv->dccpor_timestamp_echo = ntohl(opt_val);
208
209                         dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
210                                       "ackno=%llu", dccp_role(sk),
211                                       opt_recv->dccpor_timestamp_echo,
212                                       len + 2,
213                                       (unsigned long long)
214                                       DCCP_SKB_CB(skb)->dccpd_ack_seq);
215
216                         value += 4;
217
218                         if (len == 4) {         /* no elapsed time included */
219                                 dccp_pr_debug_cat("\n");
220                                 break;
221                         }
222
223                         if (len == 6) {         /* 2-byte elapsed time */
224                                 __be16 opt_val2 = get_unaligned((__be16 *)value);
225                                 elapsed_time = ntohs(opt_val2);
226                         } else {                /* 4-byte elapsed time */
227                                 opt_val = get_unaligned((__be32 *)value);
228                                 elapsed_time = ntohl(opt_val);
229                         }
230
231                         dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
232
233                         /* Give precedence to the biggest ELAPSED_TIME */
234                         if (elapsed_time > opt_recv->dccpor_elapsed_time)
235                                 opt_recv->dccpor_elapsed_time = elapsed_time;
236                         break;
237                 case DCCPO_ELAPSED_TIME:
238                         if (dccp_packet_without_ack(skb))   /* RFC 4340, 13.2 */
239                                 break;
240
241                         if (len == 2) {
242                                 __be16 opt_val2 = get_unaligned((__be16 *)value);
243                                 elapsed_time = ntohs(opt_val2);
244                         } else if (len == 4) {
245                                 opt_val = get_unaligned((__be32 *)value);
246                                 elapsed_time = ntohl(opt_val);
247                         } else {
248                                 goto out_invalid_option;
249                         }
250
251                         if (elapsed_time > opt_recv->dccpor_elapsed_time)
252                                 opt_recv->dccpor_elapsed_time = elapsed_time;
253
254                         dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
255                                       dccp_role(sk), elapsed_time);
256                         break;
257                 case 128 ... 191: {
258                         const u16 idx = value - options;
259
260                         if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
261                                                      opt, len, idx,
262                                                      value) != 0)
263                                 goto out_invalid_option;
264                 }
265                         break;
266                 case 192 ... 255: {
267                         const u16 idx = value - options;
268
269                         if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
270                                                      opt, len, idx,
271                                                      value) != 0)
272                                 goto out_invalid_option;
273                 }
274                         break;
275                 default:
276                         DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
277                                   "implemented, ignoring", sk, opt, len);
278                         break;
279                 }
280 ignore_option:
281                 if (opt != DCCPO_MANDATORY)
282                         mandatory = 0;
283         }
284
285         /* mandatory was the last byte in option list -> reset connection */
286         if (mandatory)
287                 goto out_invalid_option;
288
289 out_nonsensical_length:
290         /* RFC 4340, 5.8: ignore option and all remaining option space */
291         return 0;
292
293 out_invalid_option:
294         DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
295         DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
296         DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len);
297         DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt;
298         DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0;
299         DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0;
300         return -1;
301 }
302
303 EXPORT_SYMBOL_GPL(dccp_parse_options);
304
305 void dccp_encode_value_var(const u64 value, u8 *to, const u8 len)
306 {
307         if (len >= DCCP_OPTVAL_MAXLEN)
308                 *to++ = (value & 0xFF0000000000ull) >> 40;
309         if (len > 4)
310                 *to++ = (value & 0xFF00000000ull) >> 32;
311         if (len > 3)
312                 *to++ = (value & 0xFF000000) >> 24;
313         if (len > 2)
314                 *to++ = (value & 0xFF0000) >> 16;
315         if (len > 1)
316                 *to++ = (value & 0xFF00) >> 8;
317         if (len > 0)
318                 *to++ = (value & 0xFF);
319 }
320
321 static inline u8 dccp_ndp_len(const u64 ndp)
322 {
323         if (likely(ndp <= 0xFF))
324                 return 1;
325         return likely(ndp <= USHORT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6);
326 }
327
328 int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
329                         const unsigned char option,
330                         const void *value, const unsigned char len)
331 {
332         unsigned char *to;
333
334         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
335                 return -1;
336
337         DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
338
339         to    = skb_push(skb, len + 2);
340         *to++ = option;
341         *to++ = len + 2;
342
343         memcpy(to, value, len);
344         return 0;
345 }
346
347 EXPORT_SYMBOL_GPL(dccp_insert_option);
348
349 static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
350 {
351         struct dccp_sock *dp = dccp_sk(sk);
352         u64 ndp = dp->dccps_ndp_count;
353
354         if (dccp_non_data_packet(skb))
355                 ++dp->dccps_ndp_count;
356         else
357                 dp->dccps_ndp_count = 0;
358
359         if (ndp > 0) {
360                 unsigned char *ptr;
361                 const int ndp_len = dccp_ndp_len(ndp);
362                 const int len = ndp_len + 2;
363
364                 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
365                         return -1;
366
367                 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
368
369                 ptr = skb_push(skb, len);
370                 *ptr++ = DCCPO_NDP_COUNT;
371                 *ptr++ = len;
372                 dccp_encode_value_var(ndp, ptr, ndp_len);
373         }
374
375         return 0;
376 }
377
378 static inline int dccp_elapsed_time_len(const u32 elapsed_time)
379 {
380         return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
381 }
382
383 int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb,
384                                     u32 elapsed_time)
385 {
386         const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
387         const int len = 2 + elapsed_time_len;
388         unsigned char *to;
389
390         if (elapsed_time_len == 0)
391                 return 0;
392
393         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
394                 return -1;
395
396         DCCP_SKB_CB(skb)->dccpd_opt_len += len;
397
398         to    = skb_push(skb, len);
399         *to++ = DCCPO_ELAPSED_TIME;
400         *to++ = len;
401
402         if (elapsed_time_len == 2) {
403                 const __be16 var16 = htons((u16)elapsed_time);
404                 memcpy(to, &var16, 2);
405         } else {
406                 const __be32 var32 = htonl(elapsed_time);
407                 memcpy(to, &var32, 4);
408         }
409
410         return 0;
411 }
412
413 EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
414
415 int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
416 {
417         __be32 now = htonl(dccp_timestamp());
418         /* yes this will overflow but that is the point as we want a
419          * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
420
421         return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
422 }
423
424 EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
425
426 static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
427                                              struct dccp_request_sock *dreq,
428                                              struct sk_buff *skb)
429 {
430         __be32 tstamp_echo;
431         unsigned char *to;
432         u32 elapsed_time, elapsed_time_len, len;
433
434         if (dreq != NULL) {
435                 elapsed_time = dccp_timestamp() - dreq->dreq_timestamp_time;
436                 tstamp_echo  = htonl(dreq->dreq_timestamp_echo);
437                 dreq->dreq_timestamp_echo = 0;
438         } else {
439                 elapsed_time = dccp_timestamp() - dp->dccps_timestamp_time;
440                 tstamp_echo  = htonl(dp->dccps_timestamp_echo);
441                 dp->dccps_timestamp_echo = 0;
442         }
443
444         elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
445         len = 6 + elapsed_time_len;
446
447         if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
448                 return -1;
449
450         DCCP_SKB_CB(skb)->dccpd_opt_len += len;
451
452         to    = skb_push(skb, len);
453         *to++ = DCCPO_TIMESTAMP_ECHO;
454         *to++ = len;
455
456         memcpy(to, &tstamp_echo, 4);
457         to += 4;
458
459         if (elapsed_time_len == 2) {
460                 const __be16 var16 = htons((u16)elapsed_time);
461                 memcpy(to, &var16, 2);
462         } else if (elapsed_time_len == 4) {
463                 const __be32 var32 = htonl(elapsed_time);
464                 memcpy(to, &var32, 4);
465         }
466
467         return 0;
468 }
469
470 /**
471  * dccp_insert_option_mandatory  -  Mandatory option (5.8.2)
472  * Note that since we are using skb_push, this function needs to be called
473  * _after_ inserting the option it is supposed to influence (stack order).
474  */
475 int dccp_insert_option_mandatory(struct sk_buff *skb)
476 {
477         if (DCCP_SKB_CB(skb)->dccpd_opt_len >= DCCP_MAX_OPT_LEN)
478                 return -1;
479
480         DCCP_SKB_CB(skb)->dccpd_opt_len++;
481         *skb_push(skb, 1) = DCCPO_MANDATORY;
482         return 0;
483 }
484
485 /**
486  * dccp_insert_fn_opt  -  Insert single Feature-Negotiation option into @skb
487  * @type: %DCCPO_CHANGE_L, %DCCPO_CHANGE_R, %DCCPO_CONFIRM_L, %DCCPO_CONFIRM_R
488  * @feat: one out of %dccp_feature_numbers
489  * @val: NN value or SP array (preferred element first) to copy
490  * @len: true length of @val in bytes (excluding first element repetition)
491  * @repeat_first: whether to copy the first element of @val twice
492  * The last argument is used to construct Confirm options, where the preferred
493  * value and the preference list appear separately (RFC 4340, 6.3.1). Preference
494  * lists are kept such that the preferred entry is always first, so we only need
495  * to copy twice, and avoid the overhead of cloning into a bigger array.
496  */
497 int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat,
498                        u8 *val, u8 len, bool repeat_first)
499 {
500         u8 tot_len, *to;
501
502         /* take the `Feature' field and possible repetition into account */
503         if (len > (DCCP_SINGLE_OPT_MAXLEN - 2)) {
504                 DCCP_WARN("length %u for feature %u too large\n", len, feat);
505                 return -1;
506         }
507
508         if (unlikely(val == NULL || len == 0))
509                 len = repeat_first = 0;
510         tot_len = 3 + repeat_first + len;
511
512         if (DCCP_SKB_CB(skb)->dccpd_opt_len + tot_len > DCCP_MAX_OPT_LEN) {
513                 DCCP_WARN("packet too small for feature %d option!\n", feat);
514                 return -1;
515         }
516         DCCP_SKB_CB(skb)->dccpd_opt_len += tot_len;
517
518         to    = skb_push(skb, tot_len);
519         *to++ = type;
520         *to++ = tot_len;
521         *to++ = feat;
522
523         if (repeat_first)
524                 *to++ = *val;
525         if (len)
526                 memcpy(to, val, len);
527
528         dccp_pr_debug("%s(%s (%d), ...), length %d\n",
529                       dccp_feat_typename(type),
530                       dccp_feat_name(feat), feat, len);
531         return 0;
532 }
533
534 /* The length of all options needs to be a multiple of 4 (5.8) */
535 static void dccp_insert_option_padding(struct sk_buff *skb)
536 {
537         int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
538
539         if (padding != 0) {
540                 padding = 4 - padding;
541                 memset(skb_push(skb, padding), 0, padding);
542                 DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
543         }
544 }
545
546 int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
547 {
548         struct dccp_sock *dp = dccp_sk(sk);
549         struct dccp_minisock *dmsk = dccp_msk(sk);
550
551         DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
552
553         if (dmsk->dccpms_send_ndp_count &&
554             dccp_insert_option_ndp(sk, skb))
555                 return -1;
556
557         if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {
558
559                 /* Feature Negotiation */
560                 if (dccp_feat_insert_opts(dp, NULL, skb))
561                         return -1;
562
563                 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST) {
564                         /*
565                          * Obtain RTT sample from Request/Response exchange.
566                          * This is currently used in CCID 3 initialisation.
567                          */
568                         if (dccp_insert_option_timestamp(sk, skb))
569                                 return -1;
570
571                 } else if (dmsk->dccpms_send_ack_vector &&
572                            dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
573                            dccp_insert_option_ackvec(sk, skb)) {
574                                 return -1;
575                 }
576         }
577
578         if (dp->dccps_hc_rx_insert_options) {
579                 if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
580                         return -1;
581                 dp->dccps_hc_rx_insert_options = 0;
582         }
583
584         if (dp->dccps_timestamp_echo != 0 &&
585             dccp_insert_option_timestamp_echo(dp, NULL, skb))
586                 return -1;
587
588         dccp_insert_option_padding(skb);
589         return 0;
590 }
591
592 int dccp_insert_options_rsk(struct dccp_request_sock *dreq, struct sk_buff *skb)
593 {
594         DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
595
596         if (dccp_feat_insert_opts(NULL, dreq, skb))
597                 return -1;
598
599         if (dreq->dreq_timestamp_echo != 0 &&
600             dccp_insert_option_timestamp_echo(NULL, dreq, skb))
601                 return -1;
602
603         dccp_insert_option_padding(skb);
604         return 0;
605 }