aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/input.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 9a108ce17fc7..b1e38bf94456 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -603,22 +603,36 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
603 /* Caller (dccp_v4_do_rcv) will send Reset */ 603 /* Caller (dccp_v4_do_rcv) will send Reset */
604 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 604 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
605 return 1; 605 return 1;
606 } else if (sk->sk_state == DCCP_CLOSED) {
607 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
608 return 1;
606 } 609 }
607 610
608 if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { 611 /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */
609 if (dccp_check_seqno(sk, skb)) 612 if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb))
610 goto discard; 613 goto discard;
611
612 /*
613 * Step 8: Process options and mark acknowledgeable
614 */
615 if (dccp_parse_options(sk, NULL, skb))
616 return 1;
617 614
618 dccp_handle_ackvec_processing(sk, skb); 615 /*
619 dccp_deliver_input_to_ccids(sk, skb); 616 * Step 7: Check for unexpected packet types
617 * If (S.is_server and P.type == Response)
618 * or (S.is_client and P.type == Request)
619 * or (S.state == RESPOND and P.type == Data),
620 * Send Sync packet acknowledging P.seqno
621 * Drop packet and return
622 */
623 if ((dp->dccps_role != DCCP_ROLE_CLIENT &&
624 dh->dccph_type == DCCP_PKT_RESPONSE) ||
625 (dp->dccps_role == DCCP_ROLE_CLIENT &&
626 dh->dccph_type == DCCP_PKT_REQUEST) ||
627 (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) {
628 dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
629 goto discard;
620 } 630 }
621 631
632 /* Step 8: Process options */
633 if (dccp_parse_options(sk, NULL, skb))
634 return 1;
635
622 /* 636 /*
623 * Step 9: Process Reset 637 * Step 9: Process Reset
624 * If P.type == Reset, 638 * If P.type == Reset,
@@ -626,41 +640,21 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
626 * S.state := TIMEWAIT 640 * S.state := TIMEWAIT
627 * Set TIMEWAIT timer 641 * Set TIMEWAIT timer
628 * Drop packet and return 642 * Drop packet and return
629 */ 643 */
630 if (dh->dccph_type == DCCP_PKT_RESET) { 644 if (dh->dccph_type == DCCP_PKT_RESET) {
631 dccp_rcv_reset(sk, skb); 645 dccp_rcv_reset(sk, skb);
632 return 0; 646 return 0;
633 /* 647 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */
634 * Step 7: Check for unexpected packet types
635 * If (S.is_server and P.type == Response)
636 * or (S.is_client and P.type == Request)
637 * or (S.state == RESPOND and P.type == Data),
638 * Send Sync packet acknowledging P.seqno
639 * Drop packet and return
640 */
641 } else if ((dp->dccps_role != DCCP_ROLE_CLIENT &&
642 dh->dccph_type == DCCP_PKT_RESPONSE) ||
643 (dp->dccps_role == DCCP_ROLE_CLIENT &&
644 dh->dccph_type == DCCP_PKT_REQUEST) ||
645 (sk->sk_state == DCCP_RESPOND &&
646 dh->dccph_type == DCCP_PKT_DATA)) {
647 dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
648 goto discard;
649 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
650 if (dccp_rcv_closereq(sk, skb)) 648 if (dccp_rcv_closereq(sk, skb))
651 return 0; 649 return 0;
652 goto discard; 650 goto discard;
653 } else if (dh->dccph_type == DCCP_PKT_CLOSE) { 651 } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */
654 if (dccp_rcv_close(sk, skb)) 652 if (dccp_rcv_close(sk, skb))
655 return 0; 653 return 0;
656 goto discard; 654 goto discard;
657 } 655 }
658 656
659 switch (sk->sk_state) { 657 switch (sk->sk_state) {
660 case DCCP_CLOSED:
661 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
662 return 1;
663
664 case DCCP_REQUESTING: 658 case DCCP_REQUESTING:
665 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 659 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len);
666 if (queued >= 0) 660 if (queued >= 0)
@@ -669,8 +663,12 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
669 __kfree_skb(skb); 663 __kfree_skb(skb);
670 return 0; 664 return 0;
671 665
672 case DCCP_RESPOND:
673 case DCCP_PARTOPEN: 666 case DCCP_PARTOPEN:
667 /* Step 8: if using Ack Vectors, mark packet acknowledgeable */
668 dccp_handle_ackvec_processing(sk, skb);
669 dccp_deliver_input_to_ccids(sk, skb);
670 /* fall through */
671 case DCCP_RESPOND:
674 queued = dccp_rcv_respond_partopen_state_process(sk, skb, 672 queued = dccp_rcv_respond_partopen_state_process(sk, skb,
675 dh, len); 673 dh, len);
676 break; 674 break;