]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/tcp_minisocks.c
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[~andy/linux] / net / ipv4 / tcp_minisocks.c
index f35f2dfb64017cc3fedd3cd29d0682c14dcaf5ba..0f01788272595397cdc8c440f89d595bb6bed0dc 100644 (file)
@@ -93,15 +93,15 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
                           const struct tcphdr *th)
 {
        struct tcp_options_received tmp_opt;
-       const u8 *hash_location;
        struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
        bool paws_reject = false;
 
        tmp_opt.saw_tstamp = 0;
        if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) {
-               tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);
+               tcp_parse_options(skb, &tmp_opt, 0, NULL);
 
                if (tmp_opt.saw_tstamp) {
+                       tmp_opt.rcv_tsecr       -= tcptw->tw_ts_offset;
                        tmp_opt.ts_recent       = tcptw->tw_ts_recent;
                        tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
                        paws_reject = tcp_paws_reject(&tmp_opt, th->rst);
@@ -288,6 +288,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                tcptw->tw_rcv_wnd       = tcp_receive_window(tp);
                tcptw->tw_ts_recent     = tp->rx_opt.ts_recent;
                tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
+               tcptw->tw_ts_offset     = tp->tsoffset;
 
 #if IS_ENABLED(CONFIG_IPV6)
                if (tw->tw_family == PF_INET6) {
@@ -386,32 +387,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                struct tcp_request_sock *treq = tcp_rsk(req);
                struct inet_connection_sock *newicsk = inet_csk(newsk);
                struct tcp_sock *newtp = tcp_sk(newsk);
-               struct tcp_sock *oldtp = tcp_sk(sk);
-               struct tcp_cookie_values *oldcvp = oldtp->cookie_values;
-
-               /* TCP Cookie Transactions require space for the cookie pair,
-                * as it differs for each connection.  There is no need to
-                * copy any s_data_payload stored at the original socket.
-                * Failure will prevent resuming the connection.
-                *
-                * Presumed copied, in order of appearance:
-                *      cookie_in_always, cookie_out_never
-                */
-               if (oldcvp != NULL) {
-                       struct tcp_cookie_values *newcvp =
-                               kzalloc(sizeof(*newtp->cookie_values),
-                                       GFP_ATOMIC);
-
-                       if (newcvp != NULL) {
-                               kref_init(&newcvp->kref);
-                               newcvp->cookie_desired =
-                                               oldcvp->cookie_desired;
-                               newtp->cookie_values = newcvp;
-                       } else {
-                               /* Not Yet Implemented */
-                               newtp->cookie_values = NULL;
-                       }
-               }
 
                /* Now setup tcp_sock */
                newtp->pred_flags = 0;
@@ -420,8 +395,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                newtp->rcv_nxt = treq->rcv_isn + 1;
 
                newtp->snd_sml = newtp->snd_una =
-               newtp->snd_nxt = newtp->snd_up =
-                       treq->snt_isn + 1 + tcp_s_data_size(oldtp);
+               newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1;
 
                tcp_prequeue_init(newtp);
                INIT_LIST_HEAD(&newtp->tsq_node);
@@ -438,6 +412,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                newtp->fackets_out = 0;
                newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
                tcp_enable_early_retrans(newtp);
+               newtp->tlp_high_seq = 0;
 
                /* So many TCP implementations out there (incorrectly) count the
                 * initial SYN frame in their delayed-ACK and congestion control
@@ -446,10 +421,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                 */
                newtp->snd_cwnd = TCP_INIT_CWND;
                newtp->snd_cwnd_cnt = 0;
-               newtp->bytes_acked = 0;
-
-               newtp->frto_counter = 0;
-               newtp->frto_highmark = 0;
 
                if (newicsk->icsk_ca_ops != &tcp_init_congestion_ops &&
                    !try_module_get(newicsk->icsk_ca_ops->owner))
@@ -458,8 +429,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                tcp_set_ca_state(newsk, TCP_CA_Open);
                tcp_init_xmit_timers(newsk);
                skb_queue_head_init(&newtp->out_of_order_queue);
-               newtp->write_seq = newtp->pushed_seq =
-                       treq->snt_isn + 1 + tcp_s_data_size(oldtp);
+               newtp->write_seq = newtp->pushed_seq = treq->snt_isn + 1;
 
                newtp->rx_opt.saw_tstamp = 0;
 
@@ -500,6 +470,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                        newtp->rx_opt.ts_recent_stamp = 0;
                        newtp->tcp_header_len = sizeof(struct tcphdr);
                }
+               newtp->tsoffset = 0;
 #ifdef CONFIG_TCP_MD5SIG
                newtp->md5sig_info = NULL;      /*XXX*/
                if (newtp->af_specific->md5_lookup(sk, newsk))
@@ -535,7 +506,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
                           bool fastopen)
 {
        struct tcp_options_received tmp_opt;
-       const u8 *hash_location;
        struct sock *child;
        const struct tcphdr *th = tcp_hdr(skb);
        __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
@@ -545,7 +515,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
 
        tmp_opt.saw_tstamp = 0;
        if (th->doff > (sizeof(struct tcphdr)>>2)) {
-               tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);
+               tcp_parse_options(skb, &tmp_opt, 0, NULL);
 
                if (tmp_opt.saw_tstamp) {
                        tmp_opt.ts_recent = req->ts_recent;
@@ -581,8 +551,13 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
                 *
                 * Note that even if there is new data in the SYN packet
                 * they will be thrown away too.
+                *
+                * Reset timer after retransmitting SYNACK, similar to
+                * the idea of fast retransmit in recovery.
                 */
-               inet_rtx_syn_ack(sk, req);
+               if (!inet_rtx_syn_ack(sk, req))
+                       req->expires = min(TCP_TIMEOUT_INIT << req->num_timeout,
+                                          TCP_RTO_MAX) + jiffies;
                return NULL;
        }
 
@@ -645,7 +620,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
         */
        if ((flg & TCP_FLAG_ACK) && !fastopen &&
            (TCP_SKB_CB(skb)->ack_seq !=
-            tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk))))
+            tcp_rsk(req)->snt_isn + 1))
                return sk;
 
        /* Also, it would be not so bad idea to check rcv_tsecr, which