Setting TCP receive window in C and working with tcpdump in Linux
I am running a Linux box running 2.6.9-55.ELsmp, x86_64.
I am trying to set the TCP receive window by using the setsockopt() function using C. I try the following:
rwnd = 1024; setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rwnd, sizeof(rwnd));
The code segment above is in a client program that receives data from a server. When I kick off the program to receive and observe tcpdump output, I observe window negotiation like so:
11:34:40.257755 IP clientReceiver.42464 > serverSender.8991: S 1742042788:1742042788(0) win 5840 <mss 1460,sackOK,timestamp 1688222886 0,nop,wscale 2>
We see that the client program is in fact negotiating a window different from what I have set in the client program. However, from how I can interpret Steven's text ("TCP/IP Illustrated, Volume 1") Section 20.4, I believe you effect what he refers to in the second block quote in Section 20.4 using the setsockopt() call I use (see above).
I'd like to understand where I have gone wrong.
Perhaps my interpretation of what Stevens is saying is incorrect. In that case, could you point me to the correct way of setting the receive buffer size? As a proof of my confusion, I refer the Linux TCP sockets man page at http://linux.die.net/man/7/tcp (see comment on SO_RCFBUF).
What am I missing in this story? How do I control the receive buffer size (and have it show in the tcpdump output)? Please note that I allude to here a setting of the socket option SO_RCFBUF--I understand that's what shows up in the window negotiation in the SYN.
Any input is appreciated.
You need to also use TCP_WINDOW_CLAMP
rcvbuf = 2048; setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)& rcvbuf, sizeof(rcvbuf)); clamp = 1024; setsockopt(sock, SOL_SOCKET, TCP_WINDOW_CLAMP, (char *)& clamp, sizeof(clamp));
Note the rcvbuf is twice the clamp, it could be more. You can let it autotune, the window clamp will still work. This isn't portable.
The receive buffer size can be reduced only before you connect the socket - you can increase it at any time. What order are you calling sockopt() in relative to connect()?
For TCP, the rwnd value is to be passed during recv.
recv(sock, buf, rwnd, 0);
This shall receive 1024 bytes.