diff options
Diffstat (limited to 'net/dccp/options.c')
-rw-r--r-- | net/dccp/options.c | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/net/dccp/options.c b/net/dccp/options.c index cd3061813009..5adeeed5e0d2 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -340,6 +340,7 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time) | |||
340 | return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; | 340 | return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; |
341 | } | 341 | } |
342 | 342 | ||
343 | /* FIXME: This function is currently not used anywhere */ | ||
343 | int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) | 344 | int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) |
344 | { | 345 | { |
345 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | 346 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); |
@@ -424,6 +425,67 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp, | |||
424 | return 0; | 425 | return 0; |
425 | } | 426 | } |
426 | 427 | ||
428 | static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | ||
429 | { | ||
430 | struct dccp_sock *dp = dccp_sk(sk); | ||
431 | struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; | ||
432 | const u16 buflen = dccp_ackvec_buflen(av); | ||
433 | /* Figure out how many options do we need to represent the ackvec */ | ||
434 | const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN); | ||
435 | u16 len = buflen + 2 * nr_opts; | ||
436 | u8 i, nonce = 0; | ||
437 | const unsigned char *tail, *from; | ||
438 | unsigned char *to; | ||
439 | |||
440 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) | ||
441 | return -1; | ||
442 | |||
443 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; | ||
444 | |||
445 | to = skb_push(skb, len); | ||
446 | len = buflen; | ||
447 | from = av->av_buf + av->av_buf_head; | ||
448 | tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; | ||
449 | |||
450 | for (i = 0; i < nr_opts; ++i) { | ||
451 | int copylen = len; | ||
452 | |||
453 | if (len > DCCP_SINGLE_OPT_MAXLEN) | ||
454 | copylen = DCCP_SINGLE_OPT_MAXLEN; | ||
455 | |||
456 | /* | ||
457 | * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via | ||
458 | * its type; ack_nonce is the sum of all individual buf_nonce's. | ||
459 | */ | ||
460 | nonce ^= av->av_buf_nonce[i]; | ||
461 | |||
462 | *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i]; | ||
463 | *to++ = copylen + 2; | ||
464 | |||
465 | /* Check if buf_head wraps */ | ||
466 | if (from + copylen > tail) { | ||
467 | const u16 tailsize = tail - from; | ||
468 | |||
469 | memcpy(to, from, tailsize); | ||
470 | to += tailsize; | ||
471 | len -= tailsize; | ||
472 | copylen -= tailsize; | ||
473 | from = av->av_buf; | ||
474 | } | ||
475 | |||
476 | memcpy(to, from, copylen); | ||
477 | from += copylen; | ||
478 | to += copylen; | ||
479 | len -= copylen; | ||
480 | } | ||
481 | /* | ||
482 | * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. | ||
483 | */ | ||
484 | if (dccp_ackvec_update_records(av, DCCP_SKB_CB(skb)->dccpd_seq, nonce)) | ||
485 | return -ENOBUFS; | ||
486 | return 0; | ||
487 | } | ||
488 | |||
427 | /** | 489 | /** |
428 | * dccp_insert_option_mandatory - Mandatory option (5.8.2) | 490 | * dccp_insert_option_mandatory - Mandatory option (5.8.2) |
429 | * Note that since we are using skb_push, this function needs to be called | 491 | * Note that since we are using skb_push, this function needs to be called |
@@ -519,8 +581,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb) | |||
519 | if (dccp_insert_option_timestamp(skb)) | 581 | if (dccp_insert_option_timestamp(skb)) |
520 | return -1; | 582 | return -1; |
521 | 583 | ||
522 | } else if (dp->dccps_hc_rx_ackvec != NULL && | 584 | } else if (dccp_ackvec_pending(sk) && |
523 | dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && | ||
524 | dccp_insert_option_ackvec(sk, skb)) { | 585 | dccp_insert_option_ackvec(sk, skb)) { |
525 | return -1; | 586 | return -1; |
526 | } | 587 | } |