aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 383ce237640f..f181b78f2385 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -183,7 +183,8 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
183 */ 183 */
184void tcp_select_initial_window(int __space, __u32 mss, 184void tcp_select_initial_window(int __space, __u32 mss,
185 __u32 *rcv_wnd, __u32 *window_clamp, 185 __u32 *rcv_wnd, __u32 *window_clamp,
186 int wscale_ok, __u8 *rcv_wscale) 186 int wscale_ok, __u8 *rcv_wscale,
187 __u32 init_rcv_wnd)
187{ 188{
188 unsigned int space = (__space < 0 ? 0 : __space); 189 unsigned int space = (__space < 0 ? 0 : __space);
189 190
@@ -232,7 +233,13 @@ void tcp_select_initial_window(int __space, __u32 mss,
232 init_cwnd = 2; 233 init_cwnd = 2;
233 else if (mss > 1460) 234 else if (mss > 1460)
234 init_cwnd = 3; 235 init_cwnd = 3;
235 if (*rcv_wnd > init_cwnd * mss) 236 /* when initializing use the value from init_rcv_wnd
237 * rather than the default from above
238 */
239 if (init_rcv_wnd &&
240 (*rcv_wnd > init_rcv_wnd * mss))
241 *rcv_wnd = init_rcv_wnd * mss;
242 else if (*rcv_wnd > init_cwnd * mss)
236 *rcv_wnd = init_cwnd * mss; 243 *rcv_wnd = init_cwnd * mss;
237 } 244 }
238 245
@@ -1794,11 +1801,6 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
1794void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, 1801void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
1795 int nonagle) 1802 int nonagle)
1796{ 1803{
1797 struct sk_buff *skb = tcp_send_head(sk);
1798
1799 if (!skb)
1800 return;
1801
1802 /* If we are closed, the bytes will have to remain here. 1804 /* If we are closed, the bytes will have to remain here.
1803 * In time closedown will finish, we empty the write queue and 1805 * In time closedown will finish, we empty the write queue and
1804 * all will be happy. 1806 * all will be happy.
@@ -2393,13 +2395,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2393 struct tcp_extend_values *xvp = tcp_xv(rvp); 2395 struct tcp_extend_values *xvp = tcp_xv(rvp);
2394 struct inet_request_sock *ireq = inet_rsk(req); 2396 struct inet_request_sock *ireq = inet_rsk(req);
2395 struct tcp_sock *tp = tcp_sk(sk); 2397 struct tcp_sock *tp = tcp_sk(sk);
2398 const struct tcp_cookie_values *cvp = tp->cookie_values;
2396 struct tcphdr *th; 2399 struct tcphdr *th;
2397 struct sk_buff *skb; 2400 struct sk_buff *skb;
2398 struct tcp_md5sig_key *md5; 2401 struct tcp_md5sig_key *md5;
2399 int tcp_header_size; 2402 int tcp_header_size;
2400 int mss; 2403 int mss;
2404 int s_data_desired = 0;
2401 2405
2402 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); 2406 if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
2407 s_data_desired = cvp->s_data_desired;
2408 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC);
2403 if (skb == NULL) 2409 if (skb == NULL)
2404 return NULL; 2410 return NULL;
2405 2411
@@ -2422,7 +2428,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2422 &req->rcv_wnd, 2428 &req->rcv_wnd,
2423 &req->window_clamp, 2429 &req->window_clamp,
2424 ireq->wscale_ok, 2430 ireq->wscale_ok,
2425 &rcv_wscale); 2431 &rcv_wscale,
2432 dst_metric(dst, RTAX_INITRWND));
2426 ireq->rcv_wscale = rcv_wscale; 2433 ireq->rcv_wscale = rcv_wscale;
2427 } 2434 }
2428 2435
@@ -2454,16 +2461,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2454 TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); 2461 TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
2455 2462
2456 if (OPTION_COOKIE_EXTENSION & opts.options) { 2463 if (OPTION_COOKIE_EXTENSION & opts.options) {
2457 const struct tcp_cookie_values *cvp = tp->cookie_values; 2464 if (s_data_desired) {
2458 2465 u8 *buf = skb_put(skb, s_data_desired);
2459 if (cvp != NULL &&
2460 cvp->s_data_constant &&
2461 cvp->s_data_desired > 0) {
2462 u8 *buf = skb_put(skb, cvp->s_data_desired);
2463 2466
2464 /* copy data directly from the listening socket. */ 2467 /* copy data directly from the listening socket. */
2465 memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); 2468 memcpy(buf, cvp->s_data_payload, s_data_desired);
2466 TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; 2469 TCP_SKB_CB(skb)->end_seq += s_data_desired;
2467 } 2470 }
2468 2471
2469 if (opts.hash_size > 0) { 2472 if (opts.hash_size > 0) {
@@ -2549,7 +2552,8 @@ static void tcp_connect_init(struct sock *sk)
2549 &tp->rcv_wnd, 2552 &tp->rcv_wnd,
2550 &tp->window_clamp, 2553 &tp->window_clamp,
2551 sysctl_tcp_window_scaling, 2554 sysctl_tcp_window_scaling,
2552 &rcv_wscale); 2555 &rcv_wscale,
2556 dst_metric(dst, RTAX_INITRWND));
2553 2557
2554 tp->rx_opt.rcv_wscale = rcv_wscale; 2558 tp->rx_opt.rcv_wscale = rcv_wscale;
2555 tp->rcv_ssthresh = tp->rcv_wnd; 2559 tp->rcv_ssthresh = tp->rcv_wnd;