129 |
130 |
130 opt_recv->dccpor_ndp = dccp_decode_value_var(value, len); |
131 opt_recv->dccpor_ndp = dccp_decode_value_var(value, len); |
131 dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk), |
132 dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk), |
132 (unsigned long long)opt_recv->dccpor_ndp); |
133 (unsigned long long)opt_recv->dccpor_ndp); |
133 break; |
134 break; |
134 case DCCPO_CHANGE_L: |
135 case DCCPO_CHANGE_L ... DCCPO_CONFIRM_R: |
135 /* fall through */ |
136 if (pkt_type == DCCP_PKT_DATA) /* RFC 4340, 6 */ |
136 case DCCPO_CHANGE_R: |
|
137 if (pkt_type == DCCP_PKT_DATA) |
|
138 break; |
137 break; |
139 if (len < 2) |
138 rc = dccp_feat_parse_options(sk, dreq, mandatory, opt, |
140 goto out_invalid_option; |
139 *value, value + 1, len - 1); |
141 rc = dccp_feat_change_recv(sk, opt, *value, value + 1, |
140 if (rc) |
142 len - 1); |
141 goto out_featneg_failed; |
143 /* |
|
144 * When there is a change error, change_recv is |
|
145 * responsible for dealing with it. i.e. reply with an |
|
146 * empty confirm. |
|
147 * If the change was mandatory, then we need to die. |
|
148 */ |
|
149 if (rc && mandatory) |
|
150 goto out_invalid_option; |
|
151 break; |
|
152 case DCCPO_CONFIRM_L: |
|
153 /* fall through */ |
|
154 case DCCPO_CONFIRM_R: |
|
155 if (pkt_type == DCCP_PKT_DATA) |
|
156 break; |
|
157 if (len < 2) /* FIXME this disallows empty confirm */ |
|
158 goto out_invalid_option; |
|
159 if (dccp_feat_confirm_recv(sk, opt, *value, |
|
160 value + 1, len - 1)) |
|
161 goto out_invalid_option; |
|
162 break; |
142 break; |
163 case DCCPO_ACK_VECTOR_0: |
143 case DCCPO_ACK_VECTOR_0: |
164 case DCCPO_ACK_VECTOR_1: |
144 case DCCPO_ACK_VECTOR_1: |
165 if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ |
145 if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ |
166 break; |
146 break; |
167 |
147 if (dp->dccps_hc_rx_ackvec != NULL && |
168 if (dccp_msk(sk)->dccpms_send_ack_vector && |
|
169 dccp_ackvec_parse(sk, skb, &ackno, opt, value, len)) |
148 dccp_ackvec_parse(sk, skb, &ackno, opt, value, len)) |
170 goto out_invalid_option; |
149 goto out_invalid_option; |
171 break; |
150 break; |
172 case DCCPO_TIMESTAMP: |
151 case DCCPO_TIMESTAMP: |
173 if (len != 4) |
152 if (len != 4) |
287 /* RFC 4340, 5.8: ignore option and all remaining option space */ |
266 /* RFC 4340, 5.8: ignore option and all remaining option space */ |
288 return 0; |
267 return 0; |
289 |
268 |
290 out_invalid_option: |
269 out_invalid_option: |
291 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT); |
270 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT); |
292 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR; |
271 rc = DCCP_RESET_CODE_OPTION_ERROR; |
293 DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len); |
272 out_featneg_failed: |
|
273 DCCP_WARN("DCCP(%p): Option %d (len=%d) error=%u\n", sk, opt, len, rc); |
|
274 DCCP_SKB_CB(skb)->dccpd_reset_code = rc; |
294 DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt; |
275 DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt; |
295 DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0; |
276 DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0; |
296 DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0; |
277 DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0; |
297 return -1; |
278 return -1; |
298 } |
279 } |
299 |
280 |
300 EXPORT_SYMBOL_GPL(dccp_parse_options); |
281 EXPORT_SYMBOL_GPL(dccp_parse_options); |
301 |
282 |
302 static void dccp_encode_value_var(const u32 value, unsigned char *to, |
283 void dccp_encode_value_var(const u64 value, u8 *to, const u8 len) |
303 const unsigned int len) |
284 { |
304 { |
285 if (len >= DCCP_OPTVAL_MAXLEN) |
|
286 *to++ = (value & 0xFF0000000000ull) >> 40; |
|
287 if (len > 4) |
|
288 *to++ = (value & 0xFF00000000ull) >> 32; |
305 if (len > 3) |
289 if (len > 3) |
306 *to++ = (value & 0xFF000000) >> 24; |
290 *to++ = (value & 0xFF000000) >> 24; |
307 if (len > 2) |
291 if (len > 2) |
308 *to++ = (value & 0xFF0000) >> 16; |
292 *to++ = (value & 0xFF0000) >> 16; |
309 if (len > 1) |
293 if (len > 1) |
459 } |
443 } |
460 |
444 |
461 return 0; |
445 return 0; |
462 } |
446 } |
463 |
447 |
464 static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat, |
448 /** |
465 u8 *val, u8 len) |
449 * dccp_insert_option_mandatory - Mandatory option (5.8.2) |
466 { |
450 * Note that since we are using skb_push, this function needs to be called |
467 u8 *to; |
451 * _after_ inserting the option it is supposed to influence (stack order). |
468 |
452 */ |
469 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 3 > DCCP_MAX_OPT_LEN) { |
453 int dccp_insert_option_mandatory(struct sk_buff *skb) |
|
454 { |
|
455 if (DCCP_SKB_CB(skb)->dccpd_opt_len >= DCCP_MAX_OPT_LEN) |
|
456 return -1; |
|
457 |
|
458 DCCP_SKB_CB(skb)->dccpd_opt_len++; |
|
459 *skb_push(skb, 1) = DCCPO_MANDATORY; |
|
460 return 0; |
|
461 } |
|
462 |
|
463 /** |
|
464 * dccp_insert_fn_opt - Insert single Feature-Negotiation option into @skb |
|
465 * @type: %DCCPO_CHANGE_L, %DCCPO_CHANGE_R, %DCCPO_CONFIRM_L, %DCCPO_CONFIRM_R |
|
466 * @feat: one out of %dccp_feature_numbers |
|
467 * @val: NN value or SP array (preferred element first) to copy |
|
468 * @len: true length of @val in bytes (excluding first element repetition) |
|
469 * @repeat_first: whether to copy the first element of @val twice |
|
470 * The last argument is used to construct Confirm options, where the preferred |
|
471 * value and the preference list appear separately (RFC 4340, 6.3.1). Preference |
|
472 * lists are kept such that the preferred entry is always first, so we only need |
|
473 * to copy twice, and avoid the overhead of cloning into a bigger array. |
|
474 */ |
|
475 int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat, |
|
476 u8 *val, u8 len, bool repeat_first) |
|
477 { |
|
478 u8 tot_len, *to; |
|
479 |
|
480 /* take the `Feature' field and possible repetition into account */ |
|
481 if (len > (DCCP_SINGLE_OPT_MAXLEN - 2)) { |
|
482 DCCP_WARN("length %u for feature %u too large\n", len, feat); |
|
483 return -1; |
|
484 } |
|
485 |
|
486 if (unlikely(val == NULL || len == 0)) |
|
487 len = repeat_first = 0; |
|
488 tot_len = 3 + repeat_first + len; |
|
489 |
|
490 if (DCCP_SKB_CB(skb)->dccpd_opt_len + tot_len > DCCP_MAX_OPT_LEN) { |
470 DCCP_WARN("packet too small for feature %d option!\n", feat); |
491 DCCP_WARN("packet too small for feature %d option!\n", feat); |
471 return -1; |
492 return -1; |
472 } |
493 } |
473 |
494 DCCP_SKB_CB(skb)->dccpd_opt_len += tot_len; |
474 DCCP_SKB_CB(skb)->dccpd_opt_len += len + 3; |
495 |
475 |
496 to = skb_push(skb, tot_len); |
476 to = skb_push(skb, len + 3); |
|
477 *to++ = type; |
497 *to++ = type; |
478 *to++ = len + 3; |
498 *to++ = tot_len; |
479 *to++ = feat; |
499 *to++ = feat; |
480 |
500 |
|
501 if (repeat_first) |
|
502 *to++ = *val; |
481 if (len) |
503 if (len) |
482 memcpy(to, val, len); |
504 memcpy(to, val, len); |
483 |
505 |
484 dccp_pr_debug("%s(%s (%d), ...), length %d\n", |
506 dccp_pr_debug("%s(%s (%d), ...), length %d\n", |
485 dccp_feat_typename(type), |
507 dccp_feat_typename(type), |
486 dccp_feat_name(feat), feat, len); |
508 dccp_feat_name(feat), feat, len); |
487 return 0; |
|
488 } |
|
489 |
|
490 static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb) |
|
491 { |
|
492 struct dccp_sock *dp = dccp_sk(sk); |
|
493 struct dccp_minisock *dmsk = dccp_msk(sk); |
|
494 struct dccp_opt_pend *opt, *next; |
|
495 int change = 0; |
|
496 |
|
497 /* confirm any options [NN opts] */ |
|
498 list_for_each_entry_safe(opt, next, &dmsk->dccpms_conf, dccpop_node) { |
|
499 dccp_insert_feat_opt(skb, opt->dccpop_type, |
|
500 opt->dccpop_feat, opt->dccpop_val, |
|
501 opt->dccpop_len); |
|
502 /* fear empty confirms */ |
|
503 if (opt->dccpop_val) |
|
504 kfree(opt->dccpop_val); |
|
505 kfree(opt); |
|
506 } |
|
507 INIT_LIST_HEAD(&dmsk->dccpms_conf); |
|
508 |
|
509 /* see which features we need to send */ |
|
510 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) { |
|
511 /* see if we need to send any confirm */ |
|
512 if (opt->dccpop_sc) { |
|
513 dccp_insert_feat_opt(skb, opt->dccpop_type + 1, |
|
514 opt->dccpop_feat, |
|
515 opt->dccpop_sc->dccpoc_val, |
|
516 opt->dccpop_sc->dccpoc_len); |
|
517 |
|
518 BUG_ON(!opt->dccpop_sc->dccpoc_val); |
|
519 kfree(opt->dccpop_sc->dccpoc_val); |
|
520 kfree(opt->dccpop_sc); |
|
521 opt->dccpop_sc = NULL; |
|
522 } |
|
523 |
|
524 /* any option not confirmed, re-send it */ |
|
525 if (!opt->dccpop_conf) { |
|
526 dccp_insert_feat_opt(skb, opt->dccpop_type, |
|
527 opt->dccpop_feat, opt->dccpop_val, |
|
528 opt->dccpop_len); |
|
529 change++; |
|
530 } |
|
531 } |
|
532 |
|
533 /* Retransmit timer. |
|
534 * If this is the master listening sock, we don't set a timer on it. It |
|
535 * should be fine because if the dude doesn't receive our RESPONSE |
|
536 * [which will contain the CHANGE] he will send another REQUEST which |
|
537 * will "retrnasmit" the change. |
|
538 */ |
|
539 if (change && dp->dccps_role != DCCP_ROLE_LISTEN) { |
|
540 dccp_pr_debug("reset feat negotiation timer %p\n", sk); |
|
541 |
|
542 /* XXX don't reset the timer on re-transmissions. I.e. reset it |
|
543 * only when sending new stuff i guess. Currently the timer |
|
544 * never backs off because on re-transmission it just resets it! |
|
545 */ |
|
546 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
|
547 inet_csk(sk)->icsk_rto, DCCP_RTO_MAX); |
|
548 } |
|
549 |
|
550 return 0; |
509 return 0; |
551 } |
510 } |
552 |
511 |
553 /* The length of all options needs to be a multiple of 4 (5.8) */ |
512 /* The length of all options needs to be a multiple of 4 (5.8) */ |
554 static void dccp_insert_option_padding(struct sk_buff *skb) |
513 static void dccp_insert_option_padding(struct sk_buff *skb) |
563 } |
522 } |
564 |
523 |
565 int dccp_insert_options(struct sock *sk, struct sk_buff *skb) |
524 int dccp_insert_options(struct sock *sk, struct sk_buff *skb) |
566 { |
525 { |
567 struct dccp_sock *dp = dccp_sk(sk); |
526 struct dccp_sock *dp = dccp_sk(sk); |
568 struct dccp_minisock *dmsk = dccp_msk(sk); |
|
569 |
527 |
570 DCCP_SKB_CB(skb)->dccpd_opt_len = 0; |
528 DCCP_SKB_CB(skb)->dccpd_opt_len = 0; |
571 |
529 |
572 if (dmsk->dccpms_send_ndp_count && |
530 if (dp->dccps_send_ndp_count && dccp_insert_option_ndp(sk, skb)) |
573 dccp_insert_option_ndp(sk, skb)) |
531 return -1; |
574 return -1; |
532 |
575 |
533 if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) { |
576 if (!dccp_packet_without_ack(skb)) { |
534 |
577 if (dmsk->dccpms_send_ack_vector && |
535 /* Feature Negotiation */ |
578 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && |
536 if (dccp_feat_insert_opts(dp, NULL, skb)) |
579 dccp_insert_option_ackvec(sk, skb)) |
|
580 return -1; |
537 return -1; |
|
538 |
|
539 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST) { |
|
540 /* |
|
541 * Obtain RTT sample from Request/Response exchange. |
|
542 * This is currently used in CCID 3 initialisation. |
|
543 */ |
|
544 if (dccp_insert_option_timestamp(sk, skb)) |
|
545 return -1; |
|
546 |
|
547 } else if (dp->dccps_hc_rx_ackvec != NULL && |
|
548 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && |
|
549 dccp_insert_option_ackvec(sk, skb)) { |
|
550 return -1; |
|
551 } |
581 } |
552 } |
582 |
553 |
583 if (dp->dccps_hc_rx_insert_options) { |
554 if (dp->dccps_hc_rx_insert_options) { |
584 if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb)) |
555 if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb)) |
585 return -1; |
556 return -1; |
586 dp->dccps_hc_rx_insert_options = 0; |
557 dp->dccps_hc_rx_insert_options = 0; |
587 } |
558 } |
588 |
559 |
589 /* Feature negotiation */ |
|
590 /* Data packets can't do feat negotiation */ |
|
591 if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA && |
|
592 DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATAACK && |
|
593 dccp_insert_options_feat(sk, skb)) |
|
594 return -1; |
|
595 |
|
596 /* |
|
597 * Obtain RTT sample from Request/Response exchange. |
|
598 * This is currently used in CCID 3 initialisation. |
|
599 */ |
|
600 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST && |
|
601 dccp_insert_option_timestamp(sk, skb)) |
|
602 return -1; |
|
603 |
|
604 if (dp->dccps_timestamp_echo != 0 && |
560 if (dp->dccps_timestamp_echo != 0 && |
605 dccp_insert_option_timestamp_echo(dp, NULL, skb)) |
561 dccp_insert_option_timestamp_echo(dp, NULL, skb)) |
606 return -1; |
562 return -1; |
607 |
563 |
608 dccp_insert_option_padding(skb); |
564 dccp_insert_option_padding(skb); |