Red Hat Bugzilla – Bug 170694
querying SO_SNDBUF/SO_RCVBUF reports double the amount the buffers were assigned
Last modified: 2014-06-18 04:28:32 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4
Description of problem:
when I set the socket send/receive buffer size with setsockopt(...) I expect to be able to read back the same value I set using getsockopt(...). Hoever, I always read twice the amount I assigned.
size = 2500
setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, 4)
size2 = 0
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size2, ...)
size2 == 5000
The same thing occures with SO_RCVBUF.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
Compile and run the attached code.
run the following python commands:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2500)
Actual Results: the last python call return 5000
Expected Results: It sould have returned 2500 (It does this on Irix and Solaris)
Created attachment 119944 [details]
C code to demonstrate the problem
This has nothing to do with glibc, the glibc [gs]etsockopt wrappers just result
in the corresponding kernel syscall and nothing else.
The offending lines of code in the 188.8.131.52 kernel source are:
setsockopt() is multiplying the input values by 2 and getsockopt() is directly
returning the value set by setsockopt().
Any ideas on how to determine whether the correct behavior is to have
getsockopt() return it's value / 2, or have setsockopt() store the input value
directly without multiplying by 2?
2.6.14-1.1637_FC4 has been released as an update for FC4.
Please retest with this update, as a large amount of code has been changed in
this release, which may have fixed your problem.
I updated my kernel to 2.6.14-1.1637_FC4. I used the python test above with the
same inaccurate results.
This behaviour is intended, Linux reserves half of te socket buffer for
metadata. BSD doesn't do that, therefore in order to have compatibility
with traditional BSD the value gets doubled.
The value returned by getsockopt is the actual value being in use. Due to
maximum and minimum values for buffer values the doubling cannot be undone.
Please read up on various mailing list archives on this topic and why it
is solved the way it is.