Bug 170694 - querying SO_SNDBUF/SO_RCVBUF reports double the amount the buffers were assigned
querying SO_SNDBUF/SO_RCVBUF reports double the amount the buffers were assigned
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: kernel (Show other bugs)
4
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Thomas Graf
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2005-10-13 16:02 EDT by Lloyd
Modified: 2014-06-18 04:28 EDT (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-12-09 09:14:19 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
C code to demonstrate the problem (1.25 KB, text/plain)
2005-10-13 16:04 EDT, Lloyd
no flags Details

  None (edit)
Description Lloyd 2005-10-13 16:02:12 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):
glibc-2.3.5-10.src.rpm

How reproducible:
Always

Steps to Reproduce:
Compile and run the attached code.

OR

run the following python commands:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2500)
s.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)


  

Actual Results:  the last python call return 5000

Expected Results:  It sould have returned 2500 (It does this on Irix and Solaris)

Additional info:
Comment 1 Lloyd 2005-10-13 16:04:59 EDT
Created attachment 119944 [details]
C code to demonstrate the problem
Comment 2 Jakub Jelinek 2005-10-13 17:26:23 EDT
This has nothing to do with glibc, the glibc [gs]etsockopt wrappers just result
in the corresponding kernel syscall and nothing else.
Comment 3 Lloyd 2005-10-13 18:31:05 EDT
The offending lines of code in the 2.6.13.4 kernel source are:

setsockopt(SO_SNDBUF):
net/core/sock.c:268

setsockopt(SO_RCVBUF):
net/core/sock.c:291

getsockopt(SO_SNDBUF):
net/core/sock.c:491

getsockopt(SO_RCVBUF):
net/core/sock.c:495

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?
Comment 4 Dave Jones 2005-11-10 14:55:47 EST
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.

Thank you.
Comment 5 Lloyd 2005-11-30 10:55:39 EST
I updated my kernel to 2.6.14-1.1637_FC4.  I used the python test above with the
same inaccurate results.
Comment 6 Thomas Graf 2005-12-09 09:14:19 EST
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.

Note You need to log in before you can comment on or make changes to this bug.