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>
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.
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>
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
;
32 void dccp_minisock_init(struct dccp_minisock
*dmsk
)
34 dmsk
->dccpms_sequence_window
= sysctl_dccp_feat_sequence_window
;
35 dmsk
->dccpms_rx_ccid
= sysctl_dccp_feat_rx_ccid
;
36 dmsk
->dccpms_tx_ccid
= sysctl_dccp_feat_tx_ccid
;
37 dmsk
->dccpms_ack_ratio
= sysctl_dccp_feat_ack_ratio
;
38 dmsk
->dccpms_send_ack_vector
= sysctl_dccp_feat_send_ack_vector
;
39 dmsk
->dccpms_send_ndp_count
= sysctl_dccp_feat_send_ndp_count
;
42 static u32
dccp_decode_value_var(const unsigned char *bf
, const u8 len
)
58 int dccp_parse_options(struct sock
*sk
, struct sk_buff
*skb
)
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
+
68 struct dccp_options_received
*opt_recv
= &dp
->dccps_options_received
;
69 unsigned char opt
, len
;
75 memset(opt_recv
, 0, sizeof(*opt_recv
));
78 while (opt_ptr
!= opt_end
) {
83 /* Check if this isn't a single byte option */
84 if (opt
> DCCPO_MAX_RESERVED
) {
85 if (opt_ptr
== opt_end
)
86 goto out_invalid_option
;
90 goto out_invalid_option
;
92 * Remove the type and len fields, leaving
99 if (opt_ptr
> opt_end
)
100 goto out_invalid_option
;
106 case DCCPO_MANDATORY
:
108 goto out_invalid_option
;
109 if (pkt_type
!= DCCP_PKT_DATA
)
112 case DCCPO_NDP_COUNT
:
114 goto out_invalid_option
;
116 opt_recv
->dccpor_ndp
= dccp_decode_value_var(value
, len
);
117 dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk
),
118 opt_recv
->dccpor_ndp
);
124 goto out_invalid_option
;
125 rc
= dccp_feat_change_recv(sk
, opt
, *value
, value
+ 1,
128 * When there is a change error, change_recv is
129 * responsible for dealing with it. i.e. reply with an
131 * If the change was mandatory, then we need to die.
134 goto out_invalid_option
;
136 case DCCPO_CONFIRM_L
:
138 case DCCPO_CONFIRM_R
:
140 goto out_invalid_option
;
141 if (dccp_feat_confirm_recv(sk
, opt
, *value
,
143 goto out_invalid_option
;
145 case DCCPO_ACK_VECTOR_0
:
146 case DCCPO_ACK_VECTOR_1
:
147 if (pkt_type
== DCCP_PKT_DATA
)
150 if (dccp_msk(sk
)->dccpms_send_ack_vector
&&
151 dccp_ackvec_parse(sk
, skb
, &ackno
, opt
, value
, len
))
152 goto out_invalid_option
;
154 case DCCPO_TIMESTAMP
:
156 goto out_invalid_option
;
158 opt_recv
->dccpor_timestamp
= ntohl(*(__be32
*)value
);
160 dp
->dccps_timestamp_echo
= opt_recv
->dccpor_timestamp
;
161 dccp_timestamp(sk
, &dp
->dccps_timestamp_time
);
163 dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
164 dccp_role(sk
), opt_recv
->dccpor_timestamp
,
166 DCCP_SKB_CB(skb
)->dccpd_ack_seq
);
168 case DCCPO_TIMESTAMP_ECHO
:
169 if (len
!= 4 && len
!= 6 && len
!= 8)
170 goto out_invalid_option
;
172 opt_recv
->dccpor_timestamp_echo
= ntohl(*(__be32
*)value
);
174 dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
175 "ackno=%llu, ", dccp_role(sk
),
176 opt_recv
->dccpor_timestamp_echo
,
179 DCCP_SKB_CB(skb
)->dccpd_ack_seq
);
186 elapsed_time
= ntohs(*(__be16
*)(value
+ 4));
188 elapsed_time
= ntohl(*(__be32
*)(value
+ 4));
190 /* Give precedence to the biggest ELAPSED_TIME */
191 if (elapsed_time
> opt_recv
->dccpor_elapsed_time
)
192 opt_recv
->dccpor_elapsed_time
= elapsed_time
;
194 case DCCPO_ELAPSED_TIME
:
195 if (len
!= 2 && len
!= 4)
196 goto out_invalid_option
;
198 if (pkt_type
== DCCP_PKT_DATA
)
202 elapsed_time
= ntohs(*(__be16
*)value
);
204 elapsed_time
= ntohl(*(__be32
*)value
);
206 if (elapsed_time
> opt_recv
->dccpor_elapsed_time
)
207 opt_recv
->dccpor_elapsed_time
= elapsed_time
;
209 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
210 dccp_role(sk
), elapsed_time
);
213 * From RFC 4340, sec. 10.3:
215 * Option numbers 128 through 191 are for
216 * options sent from the HC-Sender to the
217 * HC-Receiver; option numbers 192 through 255
218 * are for options sent from the HC-Receiver to
222 const u16 idx
= value
- options
;
224 if (ccid_hc_rx_parse_options(dp
->dccps_hc_rx_ccid
, sk
,
227 goto out_invalid_option
;
231 const u16 idx
= value
- options
;
233 if (ccid_hc_tx_parse_options(dp
->dccps_hc_tx_ccid
, sk
,
236 goto out_invalid_option
;
240 DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
241 "implemented, ignoring", sk
, opt
, len
);
245 if (opt
!= DCCPO_MANDATORY
)
249 /* mandatory was the last byte in option list -> reset connection */
251 goto out_invalid_option
;
256 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT
);
257 DCCP_SKB_CB(skb
)->dccpd_reset_code
= DCCP_RESET_CODE_OPTION_ERROR
;
258 DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk
, opt
, len
);
262 EXPORT_SYMBOL_GPL(dccp_parse_options
);
264 static void dccp_encode_value_var(const u32 value
, unsigned char *to
,
265 const unsigned int len
)
268 *to
++ = (value
& 0xFF000000) >> 24;
270 *to
++ = (value
& 0xFF0000) >> 16;
272 *to
++ = (value
& 0xFF00) >> 8;
274 *to
++ = (value
& 0xFF);
277 static inline int dccp_ndp_len(const int ndp
)
279 return likely(ndp
<= 0xFF) ? 1 : ndp
<= 0xFFFF ? 2 : 3;
282 int dccp_insert_option(struct sock
*sk
, struct sk_buff
*skb
,
283 const unsigned char option
,
284 const void *value
, const unsigned char len
)
288 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
+ len
+ 2 > DCCP_MAX_OPT_LEN
)
291 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= len
+ 2;
293 to
= skb_push(skb
, len
+ 2);
297 memcpy(to
, value
, len
);
301 EXPORT_SYMBOL_GPL(dccp_insert_option
);
303 static int dccp_insert_option_ndp(struct sock
*sk
, struct sk_buff
*skb
)
305 struct dccp_sock
*dp
= dccp_sk(sk
);
306 int ndp
= dp
->dccps_ndp_count
;
308 if (dccp_non_data_packet(skb
))
309 ++dp
->dccps_ndp_count
;
311 dp
->dccps_ndp_count
= 0;
315 const int ndp_len
= dccp_ndp_len(ndp
);
316 const int len
= ndp_len
+ 2;
318 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
+ len
> DCCP_MAX_OPT_LEN
)
321 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= len
;
323 ptr
= skb_push(skb
, len
);
324 *ptr
++ = DCCPO_NDP_COUNT
;
326 dccp_encode_value_var(ndp
, ptr
, ndp_len
);
332 static inline int dccp_elapsed_time_len(const u32 elapsed_time
)
334 return elapsed_time
== 0 ? 0 : elapsed_time
<= 0xFFFF ? 2 : 4;
337 int dccp_insert_option_elapsed_time(struct sock
*sk
, struct sk_buff
*skb
,
340 const int elapsed_time_len
= dccp_elapsed_time_len(elapsed_time
);
341 const int len
= 2 + elapsed_time_len
;
344 if (elapsed_time_len
== 0)
347 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
+ len
> DCCP_MAX_OPT_LEN
)
350 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= len
;
352 to
= skb_push(skb
, len
);
353 *to
++ = DCCPO_ELAPSED_TIME
;
356 if (elapsed_time_len
== 2) {
357 const __be16 var16
= htons((u16
)elapsed_time
);
358 memcpy(to
, &var16
, 2);
360 const __be32 var32
= htonl(elapsed_time
);
361 memcpy(to
, &var32
, 4);
367 EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time
);
369 void dccp_timestamp(const struct sock
*sk
, struct timeval
*tv
)
371 const struct dccp_sock
*dp
= dccp_sk(sk
);
374 tv
->tv_sec
-= dp
->dccps_epoch
.tv_sec
;
375 tv
->tv_usec
-= dp
->dccps_epoch
.tv_usec
;
377 while (tv
->tv_usec
< 0) {
379 tv
->tv_usec
+= USEC_PER_SEC
;
383 EXPORT_SYMBOL_GPL(dccp_timestamp
);
385 int dccp_insert_option_timestamp(struct sock
*sk
, struct sk_buff
*skb
)
390 dccp_timestamp(sk
, &tv
);
391 now
= htonl(timeval_usecs(&tv
) / 10);
392 /* yes this will overflow but that is the point as we want a
393 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
395 return dccp_insert_option(sk
, skb
, DCCPO_TIMESTAMP
, &now
, sizeof(now
));
398 EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp
);
400 static int dccp_insert_option_timestamp_echo(struct sock
*sk
,
403 struct dccp_sock
*dp
= dccp_sk(sk
);
407 int len
, elapsed_time_len
;
410 dccp_timestamp(sk
, &now
);
411 elapsed_time
= timeval_delta(&now
, &dp
->dccps_timestamp_time
) / 10;
412 elapsed_time_len
= dccp_elapsed_time_len(elapsed_time
);
413 len
= 6 + elapsed_time_len
;
415 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
+ len
> DCCP_MAX_OPT_LEN
)
418 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= len
;
420 to
= skb_push(skb
, len
);
421 *to
++ = DCCPO_TIMESTAMP_ECHO
;
424 tstamp_echo
= htonl(dp
->dccps_timestamp_echo
);
425 memcpy(to
, &tstamp_echo
, 4);
428 if (elapsed_time_len
== 2) {
429 const __be16 var16
= htons((u16
)elapsed_time
);
430 memcpy(to
, &var16
, 2);
431 } else if (elapsed_time_len
== 4) {
432 const __be32 var32
= htonl(elapsed_time
);
433 memcpy(to
, &var32
, 4);
436 dp
->dccps_timestamp_echo
= 0;
437 dp
->dccps_timestamp_time
.tv_sec
= 0;
438 dp
->dccps_timestamp_time
.tv_usec
= 0;
442 static int dccp_insert_feat_opt(struct sk_buff
*skb
, u8 type
, u8 feat
,
447 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
+ len
+ 3 > DCCP_MAX_OPT_LEN
) {
448 DCCP_WARN("packet too small for feature %d option!\n", feat
);
452 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= len
+ 3;
454 to
= skb_push(skb
, len
+ 3);
460 memcpy(to
, val
, len
);
462 dccp_pr_debug("%s(%s (%d), ...), length %d\n",
463 dccp_feat_typename(type
),
464 dccp_feat_name(feat
), feat
, len
);
468 static int dccp_insert_options_feat(struct sock
*sk
, struct sk_buff
*skb
)
470 struct dccp_sock
*dp
= dccp_sk(sk
);
471 struct dccp_minisock
*dmsk
= dccp_msk(sk
);
472 struct dccp_opt_pend
*opt
, *next
;
475 /* confirm any options [NN opts] */
476 list_for_each_entry_safe(opt
, next
, &dmsk
->dccpms_conf
, dccpop_node
) {
477 dccp_insert_feat_opt(skb
, opt
->dccpop_type
,
478 opt
->dccpop_feat
, opt
->dccpop_val
,
480 /* fear empty confirms */
482 kfree(opt
->dccpop_val
);
485 INIT_LIST_HEAD(&dmsk
->dccpms_conf
);
487 /* see which features we need to send */
488 list_for_each_entry(opt
, &dmsk
->dccpms_pending
, dccpop_node
) {
489 /* see if we need to send any confirm */
490 if (opt
->dccpop_sc
) {
491 dccp_insert_feat_opt(skb
, opt
->dccpop_type
+ 1,
493 opt
->dccpop_sc
->dccpoc_val
,
494 opt
->dccpop_sc
->dccpoc_len
);
496 BUG_ON(!opt
->dccpop_sc
->dccpoc_val
);
497 kfree(opt
->dccpop_sc
->dccpoc_val
);
498 kfree(opt
->dccpop_sc
);
499 opt
->dccpop_sc
= NULL
;
502 /* any option not confirmed, re-send it */
503 if (!opt
->dccpop_conf
) {
504 dccp_insert_feat_opt(skb
, opt
->dccpop_type
,
505 opt
->dccpop_feat
, opt
->dccpop_val
,
512 * If this is the master listening sock, we don't set a timer on it. It
513 * should be fine because if the dude doesn't receive our RESPONSE
514 * [which will contain the CHANGE] he will send another REQUEST which
515 * will "retrnasmit" the change.
517 if (change
&& dp
->dccps_role
!= DCCP_ROLE_LISTEN
) {
518 dccp_pr_debug("reset feat negotiation timer %p\n", sk
);
520 /* XXX don't reset the timer on re-transmissions. I.e. reset it
521 * only when sending new stuff i guess. Currently the timer
522 * never backs off because on re-transmission it just resets it!
524 inet_csk_reset_xmit_timer(sk
, ICSK_TIME_RETRANS
,
525 inet_csk(sk
)->icsk_rto
, DCCP_RTO_MAX
);
531 int dccp_insert_options(struct sock
*sk
, struct sk_buff
*skb
)
533 struct dccp_sock
*dp
= dccp_sk(sk
);
534 struct dccp_minisock
*dmsk
= dccp_msk(sk
);
536 DCCP_SKB_CB(skb
)->dccpd_opt_len
= 0;
538 if (dmsk
->dccpms_send_ndp_count
&&
539 dccp_insert_option_ndp(sk
, skb
))
542 if (!dccp_packet_without_ack(skb
)) {
543 if (dmsk
->dccpms_send_ack_vector
&&
544 dccp_ackvec_pending(dp
->dccps_hc_rx_ackvec
) &&
545 dccp_insert_option_ackvec(sk
, skb
))
548 if (dp
->dccps_timestamp_echo
!= 0 &&
549 dccp_insert_option_timestamp_echo(sk
, skb
))
553 if (dp
->dccps_hc_rx_insert_options
) {
554 if (ccid_hc_rx_insert_options(dp
->dccps_hc_rx_ccid
, sk
, skb
))
556 dp
->dccps_hc_rx_insert_options
= 0;
559 /* Feature negotiation */
560 /* Data packets can't do feat negotiation */
561 if (DCCP_SKB_CB(skb
)->dccpd_type
!= DCCP_PKT_DATA
&&
562 DCCP_SKB_CB(skb
)->dccpd_type
!= DCCP_PKT_DATAACK
&&
563 dccp_insert_options_feat(sk
, skb
))
566 /* XXX: insert other options when appropriate */
568 if (DCCP_SKB_CB(skb
)->dccpd_opt_len
!= 0) {
569 /* The length of all options has to be a multiple of 4 */
570 int padding
= DCCP_SKB_CB(skb
)->dccpd_opt_len
% 4;
573 padding
= 4 - padding
;
574 memset(skb_push(skb
, padding
), 0, padding
);
575 DCCP_SKB_CB(skb
)->dccpd_opt_len
+= padding
;