TCP receiving Window -- confirm Window Scaling
1. Determination of rcv_scale
The cache configuration has a great relationship with the window scale value when the last three handshakes are interacted. The window scale value is determined by the tcp option when the three handshakes are performed.
1.1 client sends syn
During the three-way handshake, the scale Size is determined based on the configured cache size. When the syn Packet and syn + ack packets are sent, the tcp_connect_init function is called when the syn packet is created, in this function, the tcp_select_initial_window function assigns a value to rcv_wscale.
- Void tcp_select_initial_window (int _ space, _ u32 mss,
- _ U32 * rcv_wnd, _ u32 * window_clamp,
- Int wscale_ OK, _ u8 * rcv_wscale,
- _ U32 init_rcv_wnd)
- {
- Unsigned int space = (_ space <0? 0: _ space );
- /* 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;
- If (sysctl_tcp_workaround_signed_windows)
- (* Rcv_wnd) = min (space, MAX_TCP_WINDOW );
- Else
- (* Rcv_wnd) = space;
- (* Rcv_wscale) = 0;
- If (wscale_ OK) {/* Here, wscale_ OK corresponds to the sysctl_tcp_window_scaling parameter. The default Kernel configuration of this parameter is 1, indicating that scale is enabled */
- Space = max_t (u32, sysctl_tcp_rmem [2], sysctl_rmem_max );
- Space = min_t (u32, space, * window_clamp );
- While (space> 65535 & (* rcv_wscale) <14) {/* if the available space is greater than the maximum value that can be expressed by win and wsacle is less than 14, add 1 to rcv_wscale, narrow down space. */
- Space >>=1;
- (* Rcv_wscale) ++;
- }
- }
- If (mss> (1 <* rcv_wscale )){
- If (! Init_rcv_wnd)/* Use default unless specified otherwise */
- Init_rcv_wnd = tcp_default_init_rwnd (mss );
- * Rcv_wnd = min (* rcv_wnd, init_rcv_wnd * mss );
- }
- /* Set the clamp no higher than max representable value */
- (* Window_clamp) = min (65535U <(* rcv_wscale), * window_clamp );
- }
1.2 configure rcv_wscale for syn_ack packets
After receiving the syn packet, the following figure shows the rcv_scale setting process for sending the syn + ack packet. It also calls the tcp_select_initial_window function for initialization.
- Static unsigned int tcp_synack_options (struct sock * sk,
- Struct request_sock * req,
- Unsigned int mss, struct sk_buff * skb,
- Struct tcp_out_options * opts,
- Const struct tcp_md5sig_key * md5,
- Struct tcp_fastopen_cookie * foc)
- {
- Struct inet_request_sock * ireq = inet_rsk (req );
- Unsigned int remaining = MAX_TCP_OPTION_SPACE;
- # Ifdef CONFIG_TCP_MD5SIG
- If (md5 ){
- Opts-> options | = OPTION_MD5;
- Remaining-= TCPOLEN_MD5SIG_ALIGNED;
- Ireq-> tstamp_ OK & =! Ireq-> sack_ OK;
- }
- # Endif
- /* We always send an MSS option .*/
- Opts-> mss = mss;
- Remaining-= TCPOLEN_MSS_ALIGNED;
- If (likely (ireq-> wscale_ OK) {// set the tcp option Information wscale
- Opts-> ws = ireq-> rcv_wscale;
- Opts-> options | = OPTION_WSCALE;
- Remaining-= TCPOLEN_WSCALE_ALIGNED;
- }
- If (likely (ireq-> tstamp_ OK )){
- Opts-> options | = OPTION_TS;
- Opts-> tsval = tcp_skb_timestamp (skb );
- Opts-> tsecr = req-> ts_recent;
- Remaining-= TCPOLEN_TSTAMP_ALIGNED;
- }
- If (likely (ireq-> sack_ OK )){
- Opts-> options | = OPTION_SACK_ADVERTISE;
- If (unlikely (! Ireq-> tstamp_ OK ))
- Remaining-= TCPOLEN_SACKPERM_ALIGNED;
- }
- If (foc! = NULL & foc-> len> = 0 ){
- U32 need = foc-> len;
- Need + = foc-> exp? TCPOLEN_EXP_FASTOPEN_BASE:
- TCPOLEN_FASTOPEN_BASE;
- Need = (need + 3 )&~ 3U;/* Align to 32 bits */
- If (remaining> = need ){
- Opts-> options | = OPTION_FAST_OPEN_COOKIE;
- Opts-> fastopen_cookie = foc;
- Remaining-= need;
- }
- }
- Return MAX_TCP_OPTION_SPACE-remaining;
- }
1.3 resolution scale options
When receiving a scale datagram with the tcp option, the process is as follows, only for syn packets: