diff options
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 68 |
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; |