aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_minisocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r--net/ipv4/tcp_minisocks.c140
1 files changed, 69 insertions, 71 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 204c42162660..f976fc57892c 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -609,7 +609,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
609 tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) { 609 tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) {
610 /* Out of window: send ACK and drop. */ 610 /* Out of window: send ACK and drop. */
611 if (!(flg & TCP_FLAG_RST)) 611 if (!(flg & TCP_FLAG_RST))
612 req->rsk_ops->send_ack(skb, req); 612 req->rsk_ops->send_ack(sk, skb, req);
613 if (paws_reject) 613 if (paws_reject)
614 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); 614 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
615 return NULL; 615 return NULL;
@@ -618,89 +618,87 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
618 /* In sequence, PAWS is OK. */ 618 /* In sequence, PAWS is OK. */
619 619
620 if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_isn + 1)) 620 if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_isn + 1))
621 req->ts_recent = tmp_opt.rcv_tsval; 621 req->ts_recent = tmp_opt.rcv_tsval;
622 622
623 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { 623 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
624 /* Truncate SYN, it is out of window starting 624 /* Truncate SYN, it is out of window starting
625 at tcp_rsk(req)->rcv_isn + 1. */ 625 at tcp_rsk(req)->rcv_isn + 1. */
626 flg &= ~TCP_FLAG_SYN; 626 flg &= ~TCP_FLAG_SYN;
627 } 627 }
628 628
629 /* RFC793: "second check the RST bit" and 629 /* RFC793: "second check the RST bit" and
630 * "fourth, check the SYN bit" 630 * "fourth, check the SYN bit"
631 */ 631 */
632 if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { 632 if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
633 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS); 633 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
634 goto embryonic_reset; 634 goto embryonic_reset;
635 } 635 }
636 636
637 /* ACK sequence verified above, just make sure ACK is 637 /* ACK sequence verified above, just make sure ACK is
638 * set. If ACK not set, just silently drop the packet. 638 * set. If ACK not set, just silently drop the packet.
639 */ 639 */
640 if (!(flg & TCP_FLAG_ACK)) 640 if (!(flg & TCP_FLAG_ACK))
641 return NULL; 641 return NULL;
642
643 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
644 if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
645 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
646 inet_rsk(req)->acked = 1;
647 return NULL;
648 }
649 642
650 /* OK, ACK is valid, create big socket and 643 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
651 * feed this segment to it. It will repeat all 644 if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
652 * the tests. THIS SEGMENT MUST MOVE SOCKET TO 645 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
653 * ESTABLISHED STATE. If it will be dropped after 646 inet_rsk(req)->acked = 1;
654 * socket is created, wait for troubles. 647 return NULL;
655 */ 648 }
656 child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, 649
657 req, NULL); 650 /* OK, ACK is valid, create big socket and
658 if (child == NULL) 651 * feed this segment to it. It will repeat all
659 goto listen_overflow; 652 * the tests. THIS SEGMENT MUST MOVE SOCKET TO
653 * ESTABLISHED STATE. If it will be dropped after
654 * socket is created, wait for troubles.
655 */
656 child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
657 if (child == NULL)
658 goto listen_overflow;
660#ifdef CONFIG_TCP_MD5SIG 659#ifdef CONFIG_TCP_MD5SIG
661 else { 660 else {
662 /* Copy over the MD5 key from the original socket */ 661 /* Copy over the MD5 key from the original socket */
663 struct tcp_md5sig_key *key; 662 struct tcp_md5sig_key *key;
664 struct tcp_sock *tp = tcp_sk(sk); 663 struct tcp_sock *tp = tcp_sk(sk);
665 key = tp->af_specific->md5_lookup(sk, child); 664 key = tp->af_specific->md5_lookup(sk, child);
666 if (key != NULL) { 665 if (key != NULL) {
667 /* 666 /*
668 * We're using one, so create a matching key on the 667 * We're using one, so create a matching key on the
669 * newsk structure. If we fail to get memory then we 668 * newsk structure. If we fail to get memory then we
670 * end up not copying the key across. Shucks. 669 * end up not copying the key across. Shucks.
671 */ 670 */
672 char *newkey = kmemdup(key->key, key->keylen, 671 char *newkey = kmemdup(key->key, key->keylen,
673 GFP_ATOMIC); 672 GFP_ATOMIC);
674 if (newkey) { 673 if (newkey) {
675 if (!tcp_alloc_md5sig_pool()) 674 if (!tcp_alloc_md5sig_pool())
676 BUG(); 675 BUG();
677 tp->af_specific->md5_add(child, child, 676 tp->af_specific->md5_add(child, child, newkey,
678 newkey, 677 key->keylen);
679 key->keylen);
680 }
681 } 678 }
682 } 679 }
680 }
683#endif 681#endif
684 682
685 inet_csk_reqsk_queue_unlink(sk, req, prev); 683 inet_csk_reqsk_queue_unlink(sk, req, prev);
686 inet_csk_reqsk_queue_removed(sk, req); 684 inet_csk_reqsk_queue_removed(sk, req);
687 685
688 inet_csk_reqsk_queue_add(sk, req, child); 686 inet_csk_reqsk_queue_add(sk, req, child);
689 return child; 687 return child;
690 688
691 listen_overflow: 689listen_overflow:
692 if (!sysctl_tcp_abort_on_overflow) { 690 if (!sysctl_tcp_abort_on_overflow) {
693 inet_rsk(req)->acked = 1; 691 inet_rsk(req)->acked = 1;
694 return NULL; 692 return NULL;
695 } 693 }
696 694
697 embryonic_reset: 695embryonic_reset:
698 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); 696 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
699 if (!(flg & TCP_FLAG_RST)) 697 if (!(flg & TCP_FLAG_RST))
700 req->rsk_ops->send_reset(sk, skb); 698 req->rsk_ops->send_reset(sk, skb);
701 699
702 inet_csk_reqsk_queue_drop(sk, req, prev); 700 inet_csk_reqsk_queue_drop(sk, req, prev);
703 return NULL; 701 return NULL;
704} 702}
705 703
706/* 704/*