1

I read some stuff about TCP window scaling and BDP(not quite clear), and I can't figure out what exactly cause sender's TCP realization to set non-zero WS and could the user-mode client program affect it somehow? I think that logically it cannot be based on some data transferring because it happens on SYN-SYN+ACK TCP stage.

Can someone explain from programming point of view, how can user-mode client code affect on TCP window scale option (e.g. before connect() call)? And how TCP stack knows when to set WS to non-zero?

Sorry if obvious.

red0ct
  • 4,840
  • 3
  • 17
  • 44
narotello
  • 419
  • 2
  • 14
  • Also see [TCP receiving window size higher than net.core.rmem_max](https://stackoverflow.com/q/31546835/608639). – jww Nov 13 '19 at 03:08

1 Answers1

2

The TCP window scaling index rcv_wscale (f.e. while sending SYN or SYN-ACK) is calculated inside Linux kernel based on socket's receive buffer in function tcp_select_initial_window():

/* If no clamp set the clamp to the max possible scaled window */
if (*window_clamp == 0)
    (*window_clamp) = (65535 << 14);
space = min(*window_clamp, space);

/* Quantize space offering to a multiple of mss if possible. */
if (space > mss)
    space = (space / mss) * mss;
//...
(*rcv_wscale) = 0;
if (wscale_ok) {
    /* Set window scaling on max possible window
     * See RFC1323 for an explanation of the limit to 14
     */
    space = max_t(u32, space, sysctl_tcp_rmem[2]);
    space = max_t(u32, space, sysctl_rmem_max);
    space = min_t(u32, space, *window_clamp);
    while (space > 65535 && (*rcv_wscale) < 14) {
        space >>= 1;
        (*rcv_wscale)++;
    }
}

Here space is taken from the tcp_full_space() based on sk_rcvbuf.

Knowing that you can affect this calculation via changing size of receive buffer:

int buflen = 12345;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &buflen, sizeof int) < 0)
    perror("setsockopt():");
//...

This can give you zero scaling (WS=0 or wscale 0).

P.S. keep in mind that at server side it should be done on listening socket, because you can't affect it after TCP-handshake.

red0ct
  • 4,840
  • 3
  • 17
  • 44