diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 40 |
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 | */ |
| 184 | void tcp_select_initial_window(int __space, __u32 mss, | 184 | void 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, | |||
| 1794 | void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, | 1801 | void __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; |
