aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/input.c30
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
527unable_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
514static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 538static 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;