diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ackvec.c | 14 | ||||
-rw-r--r-- | net/dccp/ccid.h | 18 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 37 | ||||
-rw-r--r-- | net/dccp/dccp.h | 8 | ||||
-rw-r--r-- | net/dccp/options.c | 109 | ||||
-rw-r--r-- | net/dccp/output.c | 18 |
6 files changed, 102 insertions, 102 deletions
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 5c76e81658cf..b5981e5f6b00 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c | |||
@@ -81,15 +81,16 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | |||
81 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) | 81 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) |
82 | return -1; | 82 | return -1; |
83 | 83 | ||
84 | avr = dccp_ackvec_record_new(); | ||
85 | if (avr == NULL) | ||
86 | return -1; | ||
87 | |||
88 | dccp_timestamp(sk, &now); | 84 | dccp_timestamp(sk, &now); |
89 | elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10; | 85 | elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10; |
90 | 86 | ||
91 | if (elapsed_time != 0) | 87 | if (elapsed_time != 0 && |
92 | dccp_insert_option_elapsed_time(sk, skb, elapsed_time); | 88 | dccp_insert_option_elapsed_time(sk, skb, elapsed_time)) |
89 | return -1; | ||
90 | |||
91 | avr = dccp_ackvec_record_new(); | ||
92 | if (avr == NULL) | ||
93 | return -1; | ||
93 | 94 | ||
94 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; | 95 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; |
95 | 96 | ||
@@ -310,7 +311,6 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | |||
310 | av->dccpav_buf_ackno = ackno; | 311 | av->dccpav_buf_ackno = ackno; |
311 | dccp_timestamp(sk, &av->dccpav_time); | 312 | dccp_timestamp(sk, &av->dccpav_time); |
312 | out: | 313 | out: |
313 | dccp_pr_debug(""); | ||
314 | return 0; | 314 | return 0; |
315 | 315 | ||
316 | out_duplicate: | 316 | out_duplicate: |
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 3dec50d49731..f7eb6c613414 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
@@ -41,9 +41,9 @@ struct ccid_operations { | |||
41 | unsigned char option, | 41 | unsigned char option, |
42 | unsigned char len, u16 idx, | 42 | unsigned char len, u16 idx, |
43 | unsigned char* value); | 43 | unsigned char* value); |
44 | void (*ccid_hc_rx_insert_options)(struct sock *sk, | 44 | int (*ccid_hc_rx_insert_options)(struct sock *sk, |
45 | struct sk_buff *skb); | 45 | struct sk_buff *skb); |
46 | void (*ccid_hc_tx_insert_options)(struct sock *sk, | 46 | int (*ccid_hc_tx_insert_options)(struct sock *sk, |
47 | struct sk_buff *skb); | 47 | struct sk_buff *skb); |
48 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, | 48 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, |
49 | struct sk_buff *skb); | 49 | struct sk_buff *skb); |
@@ -146,18 +146,20 @@ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, | |||
146 | return rc; | 146 | return rc; |
147 | } | 147 | } |
148 | 148 | ||
149 | static inline void ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk, | 149 | static inline int ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk, |
150 | struct sk_buff *skb) | 150 | struct sk_buff *skb) |
151 | { | 151 | { |
152 | if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL) | 152 | if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL) |
153 | ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb); | 153 | return ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb); |
154 | return 0; | ||
154 | } | 155 | } |
155 | 156 | ||
156 | static inline void ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, | 157 | static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, |
157 | struct sk_buff *skb) | 158 | struct sk_buff *skb) |
158 | { | 159 | { |
159 | if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL) | 160 | if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL) |
160 | ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb); | 161 | return ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb); |
162 | return 0; | ||
161 | } | 163 | } |
162 | 164 | ||
163 | static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk, | 165 | static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk, |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index ff426a900999..b4a51d0355a5 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -574,16 +574,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
574 | } | 574 | } |
575 | } | 575 | } |
576 | 576 | ||
577 | static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) | 577 | static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) |
578 | { | 578 | { |
579 | const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 579 | const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
580 | 580 | ||
581 | BUG_ON(hctx == NULL); | 581 | BUG_ON(hctx == NULL); |
582 | 582 | ||
583 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) | 583 | if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN) |
584 | return; | 584 | DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; |
585 | 585 | return 0; | |
586 | DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; | ||
587 | } | 586 | } |
588 | 587 | ||
589 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | 588 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, |
@@ -774,7 +773,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk) | |||
774 | dccp_send_ack(sk); | 773 | dccp_send_ack(sk); |
775 | } | 774 | } |
776 | 775 | ||
777 | static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) | 776 | static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) |
778 | { | 777 | { |
779 | const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 778 | const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
780 | __be32 x_recv, pinv; | 779 | __be32 x_recv, pinv; |
@@ -782,23 +781,27 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) | |||
782 | BUG_ON(hcrx == NULL); | 781 | BUG_ON(hcrx == NULL); |
783 | 782 | ||
784 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) | 783 | if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) |
785 | return; | 784 | return 0; |
786 | 785 | ||
787 | DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; | 786 | DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; |
788 | 787 | ||
789 | if (dccp_packet_without_ack(skb)) | 788 | if (dccp_packet_without_ack(skb)) |
790 | return; | 789 | return 0; |
791 | 790 | ||
792 | if (hcrx->ccid3hcrx_elapsed_time != 0) | ||
793 | dccp_insert_option_elapsed_time(sk, skb, | ||
794 | hcrx->ccid3hcrx_elapsed_time); | ||
795 | dccp_insert_option_timestamp(sk, skb); | ||
796 | x_recv = htonl(hcrx->ccid3hcrx_x_recv); | 791 | x_recv = htonl(hcrx->ccid3hcrx_x_recv); |
797 | pinv = htonl(hcrx->ccid3hcrx_pinv); | 792 | pinv = htonl(hcrx->ccid3hcrx_pinv); |
798 | dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, | 793 | |
799 | &pinv, sizeof(pinv)); | 794 | if ((hcrx->ccid3hcrx_elapsed_time != 0 && |
800 | dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, | 795 | dccp_insert_option_elapsed_time(sk, skb, |
801 | &x_recv, sizeof(x_recv)); | 796 | hcrx->ccid3hcrx_elapsed_time)) || |
797 | dccp_insert_option_timestamp(sk, skb) || | ||
798 | dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, | ||
799 | &pinv, sizeof(pinv)) || | ||
800 | dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, | ||
801 | &x_recv, sizeof(x_recv))) | ||
802 | return -1; | ||
803 | |||
804 | return 0; | ||
802 | } | 805 | } |
803 | 806 | ||
804 | /* calculate first loss interval | 807 | /* calculate first loss interval |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 7f5be0822f3a..34e70fb89d4a 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -326,13 +326,13 @@ static inline int dccp_ack_pending(const struct sock *sk) | |||
326 | inet_csk_ack_scheduled(sk); | 326 | inet_csk_ack_scheduled(sk); |
327 | } | 327 | } |
328 | 328 | ||
329 | extern void dccp_insert_options(struct sock *sk, struct sk_buff *skb); | 329 | extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb); |
330 | extern void dccp_insert_option_elapsed_time(struct sock *sk, | 330 | extern int dccp_insert_option_elapsed_time(struct sock *sk, |
331 | struct sk_buff *skb, | 331 | struct sk_buff *skb, |
332 | u32 elapsed_time); | 332 | u32 elapsed_time); |
333 | extern void dccp_insert_option_timestamp(struct sock *sk, | 333 | extern int dccp_insert_option_timestamp(struct sock *sk, |
334 | struct sk_buff *skb); | 334 | struct sk_buff *skb); |
335 | extern void dccp_insert_option(struct sock *sk, struct sk_buff *skb, | 335 | extern int dccp_insert_option(struct sock *sk, struct sk_buff *skb, |
336 | unsigned char option, | 336 | unsigned char option, |
337 | const void *value, unsigned char len); | 337 | const void *value, unsigned char len); |
338 | 338 | ||
diff --git a/net/dccp/options.c b/net/dccp/options.c index 0161a18e739a..da1676016484 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -283,17 +283,14 @@ static inline int dccp_ndp_len(const int ndp) | |||
283 | return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3; | 283 | return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3; |
284 | } | 284 | } |
285 | 285 | ||
286 | void dccp_insert_option(struct sock *sk, struct sk_buff *skb, | 286 | int dccp_insert_option(struct sock *sk, struct sk_buff *skb, |
287 | const unsigned char option, | 287 | const unsigned char option, |
288 | const void *value, const unsigned char len) | 288 | const void *value, const unsigned char len) |
289 | { | 289 | { |
290 | unsigned char *to; | 290 | unsigned char *to; |
291 | 291 | ||
292 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) { | 292 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) |
293 | LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " | 293 | return -1; |
294 | "%d option!\n", option); | ||
295 | return; | ||
296 | } | ||
297 | 294 | ||
298 | DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2; | 295 | DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2; |
299 | 296 | ||
@@ -302,11 +299,12 @@ void dccp_insert_option(struct sock *sk, struct sk_buff *skb, | |||
302 | *to++ = len + 2; | 299 | *to++ = len + 2; |
303 | 300 | ||
304 | memcpy(to, value, len); | 301 | memcpy(to, value, len); |
302 | return 0; | ||
305 | } | 303 | } |
306 | 304 | ||
307 | EXPORT_SYMBOL_GPL(dccp_insert_option); | 305 | EXPORT_SYMBOL_GPL(dccp_insert_option); |
308 | 306 | ||
309 | static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb) | 307 | static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb) |
310 | { | 308 | { |
311 | struct dccp_sock *dp = dccp_sk(sk); | 309 | struct dccp_sock *dp = dccp_sk(sk); |
312 | int ndp = dp->dccps_ndp_count; | 310 | int ndp = dp->dccps_ndp_count; |
@@ -322,7 +320,7 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb) | |||
322 | const int len = ndp_len + 2; | 320 | const int len = ndp_len + 2; |
323 | 321 | ||
324 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) | 322 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) |
325 | return; | 323 | return -1; |
326 | 324 | ||
327 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; | 325 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; |
328 | 326 | ||
@@ -331,6 +329,8 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb) | |||
331 | *ptr++ = len; | 329 | *ptr++ = len; |
332 | dccp_encode_value_var(ndp, ptr, ndp_len); | 330 | dccp_encode_value_var(ndp, ptr, ndp_len); |
333 | } | 331 | } |
332 | |||
333 | return 0; | ||
334 | } | 334 | } |
335 | 335 | ||
336 | static inline int dccp_elapsed_time_len(const u32 elapsed_time) | 336 | static inline int dccp_elapsed_time_len(const u32 elapsed_time) |
@@ -338,27 +338,18 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time) | |||
338 | return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; | 338 | return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; |
339 | } | 339 | } |
340 | 340 | ||
341 | void dccp_insert_option_elapsed_time(struct sock *sk, | 341 | int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb, |
342 | struct sk_buff *skb, | 342 | u32 elapsed_time) |
343 | u32 elapsed_time) | ||
344 | { | 343 | { |
345 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
346 | struct dccp_sock *dp = dccp_sk(sk); | ||
347 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
348 | "CLIENT TX opt: " : "server TX opt: "; | ||
349 | #endif | ||
350 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | 344 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); |
351 | const int len = 2 + elapsed_time_len; | 345 | const int len = 2 + elapsed_time_len; |
352 | unsigned char *to; | 346 | unsigned char *to; |
353 | 347 | ||
354 | if (elapsed_time_len == 0) | 348 | if (elapsed_time_len == 0) |
355 | return; | 349 | return 0; |
356 | 350 | ||
357 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { | 351 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) |
358 | LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to " | 352 | return -1; |
359 | "insert elapsed time!\n"); | ||
360 | return; | ||
361 | } | ||
362 | 353 | ||
363 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; | 354 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; |
364 | 355 | ||
@@ -374,10 +365,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk, | |||
374 | memcpy(to, &var32, 4); | 365 | memcpy(to, &var32, 4); |
375 | } | 366 | } |
376 | 367 | ||
377 | dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n", | 368 | return 0; |
378 | debug_prefix, elapsed_time, | ||
379 | len, | ||
380 | (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq); | ||
381 | } | 369 | } |
382 | 370 | ||
383 | EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); | 371 | EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); |
@@ -398,7 +386,7 @@ void dccp_timestamp(const struct sock *sk, struct timeval *tv) | |||
398 | 386 | ||
399 | EXPORT_SYMBOL_GPL(dccp_timestamp); | 387 | EXPORT_SYMBOL_GPL(dccp_timestamp); |
400 | 388 | ||
401 | void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) | 389 | int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) |
402 | { | 390 | { |
403 | struct timeval tv; | 391 | struct timeval tv; |
404 | __be32 now; | 392 | __be32 now; |
@@ -408,19 +396,15 @@ void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) | |||
408 | /* yes this will overflow but that is the point as we want a | 396 | /* yes this will overflow but that is the point as we want a |
409 | * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ | 397 | * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ |
410 | 398 | ||
411 | dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now)); | 399 | return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now)); |
412 | } | 400 | } |
413 | 401 | ||
414 | EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp); | 402 | EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp); |
415 | 403 | ||
416 | static void dccp_insert_option_timestamp_echo(struct sock *sk, | 404 | static int dccp_insert_option_timestamp_echo(struct sock *sk, |
417 | struct sk_buff *skb) | 405 | struct sk_buff *skb) |
418 | { | 406 | { |
419 | struct dccp_sock *dp = dccp_sk(sk); | 407 | struct dccp_sock *dp = dccp_sk(sk); |
420 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
421 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
422 | "CLIENT TX opt: " : "server TX opt: "; | ||
423 | #endif | ||
424 | struct timeval now; | 408 | struct timeval now; |
425 | __be32 tstamp_echo; | 409 | __be32 tstamp_echo; |
426 | u32 elapsed_time; | 410 | u32 elapsed_time; |
@@ -432,11 +416,8 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
432 | elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | 416 | elapsed_time_len = dccp_elapsed_time_len(elapsed_time); |
433 | len = 6 + elapsed_time_len; | 417 | len = 6 + elapsed_time_len; |
434 | 418 | ||
435 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { | 419 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) |
436 | LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " | 420 | return -1; |
437 | "timestamp echo!\n"); | ||
438 | return; | ||
439 | } | ||
440 | 421 | ||
441 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; | 422 | DCCP_SKB_CB(skb)->dccpd_opt_len += len; |
442 | 423 | ||
@@ -456,14 +437,10 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
456 | memcpy(to, &var32, 4); | 437 | memcpy(to, &var32, 4); |
457 | } | 438 | } |
458 | 439 | ||
459 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n", | ||
460 | debug_prefix, dp->dccps_timestamp_echo, | ||
461 | len, | ||
462 | (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq); | ||
463 | |||
464 | dp->dccps_timestamp_echo = 0; | 440 | dp->dccps_timestamp_echo = 0; |
465 | dp->dccps_timestamp_time.tv_sec = 0; | 441 | dp->dccps_timestamp_time.tv_sec = 0; |
466 | dp->dccps_timestamp_time.tv_usec = 0; | 442 | dp->dccps_timestamp_time.tv_usec = 0; |
443 | return 0; | ||
467 | } | 444 | } |
468 | 445 | ||
469 | static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat, | 446 | static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat, |
@@ -491,7 +468,7 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat, | |||
491 | return 0; | 468 | return 0; |
492 | } | 469 | } |
493 | 470 | ||
494 | static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb) | 471 | static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb) |
495 | { | 472 | { |
496 | struct dccp_sock *dp = dccp_sk(sk); | 473 | struct dccp_sock *dp = dccp_sk(sk); |
497 | struct dccp_opt_pend *opt, *next; | 474 | struct dccp_opt_pend *opt, *next; |
@@ -551,44 +528,48 @@ static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb) | |||
551 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 528 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
552 | inet_csk(sk)->icsk_rto, DCCP_RTO_MAX); | 529 | inet_csk(sk)->icsk_rto, DCCP_RTO_MAX); |
553 | } | 530 | } |
531 | |||
532 | return 0; | ||
554 | } | 533 | } |
555 | 534 | ||
556 | void dccp_insert_options(struct sock *sk, struct sk_buff *skb) | 535 | int dccp_insert_options(struct sock *sk, struct sk_buff *skb) |
557 | { | 536 | { |
558 | struct dccp_sock *dp = dccp_sk(sk); | 537 | struct dccp_sock *dp = dccp_sk(sk); |
559 | 538 | ||
560 | DCCP_SKB_CB(skb)->dccpd_opt_len = 0; | 539 | DCCP_SKB_CB(skb)->dccpd_opt_len = 0; |
561 | 540 | ||
562 | if (dp->dccps_options.dccpo_send_ndp_count) | 541 | if (dp->dccps_options.dccpo_send_ndp_count && |
563 | dccp_insert_option_ndp(sk, skb); | 542 | dccp_insert_option_ndp(sk, skb)) |
543 | return -1; | ||
564 | 544 | ||
565 | if (!dccp_packet_without_ack(skb)) { | 545 | if (!dccp_packet_without_ack(skb)) { |
566 | if (dp->dccps_options.dccpo_send_ack_vector && | 546 | if (dp->dccps_options.dccpo_send_ack_vector && |
567 | dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) | 547 | dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && |
568 | dccp_insert_option_ackvec(sk, skb); | 548 | dccp_insert_option_ackvec(sk, skb)) |
569 | if (dp->dccps_timestamp_echo != 0) | 549 | return -1; |
570 | dccp_insert_option_timestamp_echo(sk, skb); | 550 | |
551 | if (dp->dccps_timestamp_echo != 0 && | ||
552 | dccp_insert_option_timestamp_echo(sk, skb)) | ||
553 | return -1; | ||
571 | } | 554 | } |
572 | 555 | ||
573 | if (dp->dccps_hc_rx_insert_options) { | 556 | if (dp->dccps_hc_rx_insert_options) { |
574 | ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb); | 557 | if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb)) |
558 | return -1; | ||
575 | dp->dccps_hc_rx_insert_options = 0; | 559 | dp->dccps_hc_rx_insert_options = 0; |
576 | } | 560 | } |
577 | if (dp->dccps_hc_tx_insert_options) { | 561 | if (dp->dccps_hc_tx_insert_options) { |
578 | ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb); | 562 | if (ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb)) |
563 | return -1; | ||
579 | dp->dccps_hc_tx_insert_options = 0; | 564 | dp->dccps_hc_tx_insert_options = 0; |
580 | } | 565 | } |
581 | 566 | ||
582 | /* Feature negotiation */ | 567 | /* Feature negotiation */ |
583 | switch(DCCP_SKB_CB(skb)->dccpd_type) { | 568 | /* Data packets can't do feat negotiation */ |
584 | /* Data packets can't do feat negotiation */ | 569 | if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA && |
585 | case DCCP_PKT_DATA: | 570 | DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATAACK && |
586 | case DCCP_PKT_DATAACK: | 571 | dccp_insert_options_feat(sk, skb)) |
587 | break; | 572 | return -1; |
588 | default: | ||
589 | dccp_insert_feat(sk, skb); | ||
590 | break; | ||
591 | } | ||
592 | 573 | ||
593 | /* XXX: insert other options when appropriate */ | 574 | /* XXX: insert other options when appropriate */ |
594 | 575 | ||
@@ -602,4 +583,6 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb) | |||
602 | DCCP_SKB_CB(skb)->dccpd_opt_len += padding; | 583 | DCCP_SKB_CB(skb)->dccpd_opt_len += padding; |
603 | } | 584 | } |
604 | } | 585 | } |
586 | |||
587 | return 0; | ||
605 | } | 588 | } |
diff --git a/net/dccp/output.c b/net/dccp/output.c index 2975e3d7a48c..7409e4a3abdf 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -83,7 +83,11 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
83 | } | 83 | } |
84 | 84 | ||
85 | dcb->dccpd_seq = dp->dccps_gss; | 85 | dcb->dccpd_seq = dp->dccps_gss; |
86 | dccp_insert_options(sk, skb); | 86 | |
87 | if (dccp_insert_options(sk, skb)) { | ||
88 | kfree_skb(skb); | ||
89 | return -EPROTO; | ||
90 | } | ||
87 | 91 | ||
88 | skb->h.raw = skb_push(skb, dccp_header_size); | 92 | skb->h.raw = skb_push(skb, dccp_header_size); |
89 | dh = dccp_hdr(skb); | 93 | dh = dccp_hdr(skb); |
@@ -296,7 +300,11 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
296 | dreq = dccp_rsk(req); | 300 | dreq = dccp_rsk(req); |
297 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; | 301 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; |
298 | DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; | 302 | DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; |
299 | dccp_insert_options(sk, skb); | 303 | |
304 | if (dccp_insert_options(sk, skb)) { | ||
305 | kfree_skb(skb); | ||
306 | return NULL; | ||
307 | } | ||
300 | 308 | ||
301 | skb->h.raw = skb_push(skb, dccp_header_size); | 309 | skb->h.raw = skb_push(skb, dccp_header_size); |
302 | 310 | ||
@@ -344,7 +352,11 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | |||
344 | DCCP_SKB_CB(skb)->dccpd_reset_code = code; | 352 | DCCP_SKB_CB(skb)->dccpd_reset_code = code; |
345 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET; | 353 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET; |
346 | DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss; | 354 | DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss; |
347 | dccp_insert_options(sk, skb); | 355 | |
356 | if (dccp_insert_options(sk, skb)) { | ||
357 | kfree_skb(skb); | ||
358 | return NULL; | ||
359 | } | ||
348 | 360 | ||
349 | skb->h.raw = skb_push(skb, dccp_header_size); | 361 | skb->h.raw = skb_push(skb, dccp_header_size); |
350 | 362 | ||