diff options
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index 3070015edc75..0672b7e1763e 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -421,8 +421,13 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
421 | goto out_invalid_packet; | 421 | goto out_invalid_packet; |
422 | } | 422 | } |
423 | 423 | ||
424 | /* | ||
425 | * If option processing (Step 8) failed, return 1 here so that | ||
426 | * dccp_v4_do_rcv() sends a Reset. The Reset code depends on | ||
427 | * the option type and is set in dccp_parse_options(). | ||
428 | */ | ||
424 | if (dccp_parse_options(sk, NULL, skb)) | 429 | if (dccp_parse_options(sk, NULL, skb)) |
425 | goto out_invalid_packet; | 430 | return 1; |
426 | 431 | ||
427 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ | 432 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ |
428 | if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) | 433 | if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) |
@@ -475,6 +480,15 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
475 | */ | 480 | */ |
476 | dccp_set_state(sk, DCCP_PARTOPEN); | 481 | dccp_set_state(sk, DCCP_PARTOPEN); |
477 | 482 | ||
483 | /* | ||
484 | * If feature negotiation was successful, activate features now; | ||
485 | * an activation failure means that this host could not activate | ||
486 | * one ore more features (e.g. insufficient memory), which would | ||
487 | * leave at least one feature in an undefined state. | ||
488 | */ | ||
489 | if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) | ||
490 | goto unable_to_proceed; | ||
491 | |||
478 | /* Make sure socket is routed, for correct metrics. */ | 492 | /* Make sure socket is routed, for correct metrics. */ |
479 | icsk->icsk_af_ops->rebuild_header(sk); | 493 | icsk->icsk_af_ops->rebuild_header(sk); |
480 | 494 | ||
@@ -509,6 +523,16 @@ out_invalid_packet: | |||
509 | /* dccp_v4_do_rcv will send a reset */ | 523 | /* dccp_v4_do_rcv will send a reset */ |
510 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; | 524 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
511 | return 1; | 525 | return 1; |
526 | |||
527 | unable_to_proceed: | ||
528 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; | ||
529 | /* | ||
530 | * We mark this socket as no longer usable, so that the loop in | ||
531 | * dccp_sendmsg() terminates and the application gets notified. | ||
532 | */ | ||
533 | dccp_set_state(sk, DCCP_CLOSED); | ||
534 | sk->sk_err = ECOMM; | ||
535 | return 1; | ||
512 | } | 536 | } |
513 | 537 | ||
514 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | 538 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, |
@@ -600,7 +624,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
600 | return 1; | 624 | return 1; |
601 | } | 625 | } |
602 | 626 | ||
603 | if (sk->sk_state != DCCP_REQUESTING) { | 627 | if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { |
604 | if (dccp_check_seqno(sk, skb)) | 628 | if (dccp_check_seqno(sk, skb)) |
605 | goto discard; | 629 | goto discard; |
606 | 630 | ||
@@ -665,8 +689,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
665 | return 1; | 689 | return 1; |
666 | 690 | ||
667 | case DCCP_REQUESTING: | 691 | case DCCP_REQUESTING: |
668 | /* FIXME: do congestion control initialization */ | ||
669 | |||
670 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); | 692 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); |
671 | if (queued >= 0) | 693 | if (queued >= 0) |
672 | return queued; | 694 | return queued; |