* setsockopt(..,SO_RCVBUF,..) sets wrong value
@ 2001-08-02 10:34 Manfred Bartz
2001-08-02 13:12 ` David S. Miller
0 siblings, 1 reply; 5+ messages in thread
From: Manfred Bartz @ 2001-08-02 10:34 UTC (permalink / raw)
To: linux-kernel
When I do a setsockopt(..,SO_RCVBUF,..) and then read the value back
with getsockopt(), the reported value is exactly twice of what I set.
Running the same code on Solaris and on DEC UNIX reports back the
exact size I set.
Looking at the code it seems that the *2 should not be there:
>From /usr/src/linux/net/core/sock.c:
int sock_setsockopt(...
case SO_SNDBUF:
sk->sndbuf = max(val*2,SOCK_MIN_SNDBUF);
case SO_RCVBUF:
/* FIXME: is this lower bound the right one? */
sk->rcvbuf = max(val*2,SOCK_MIN_RCVBUF);
break;
--
Manfred Bartz
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: setsockopt(..,SO_RCVBUF,..) sets wrong value
2001-08-02 10:34 setsockopt(..,SO_RCVBUF,..) sets wrong value Manfred Bartz
@ 2001-08-02 13:12 ` David S. Miller
0 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2001-08-02 13:12 UTC (permalink / raw)
To: Manfred Bartz; +Cc: linux-kernel
Manfred Bartz writes:
> When I do a setsockopt(..,SO_RCVBUF,..) and then read the value back
> with getsockopt(), the reported value is exactly twice of what I set.
That's correct. Please search the list archives to learn why things
behave this way and why they are not going to change.
I wish that this long winded, and often occuring thread not occur
again.
Later,
David S. Miller
davem@redhat.com
^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <no.id>]
* Re: setsockopt(..,SO_RCVBUF,..) sets wrong value
[not found] <no.id>
@ 2001-08-02 14:26 ` Alan Cox
0 siblings, 0 replies; 5+ messages in thread
From: Alan Cox @ 2001-08-02 14:26 UTC (permalink / raw)
To: Manfred Bartz; +Cc: linux-kernel
> When I do a setsockopt(..,SO_RCVBUF,..) and then read the value back
> with getsockopt(), the reported value is exactly twice of what I set.
> Running the same code on Solaris and on DEC UNIX reports back the
> exact size I set.
> Looking at the code it seems that the *2 should not be there:
You are making assumptions not guaranteed in POSIX or SuS. In the Linux case
we deliberately allow more than requested as our memory accounting behaviour
for buffers is very different to BSD
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: setsockopt(..,SO_RCVBUF,..) sets wrong value
@ 2001-08-02 14:38 Andries.Brouwer
2001-08-02 15:59 ` Richard B. Johnson
0 siblings, 1 reply; 5+ messages in thread
From: Andries.Brouwer @ 2001-08-02 14:38 UTC (permalink / raw)
To: alan, davem, mbartz, torvalds; +Cc: linux-kernel
From: "David S. Miller" <davem@redhat.com>
Manfred Bartz writes:
> When I do a setsockopt(..,SO_RCVBUF,..) and then read the value back
> with getsockopt(), the reported value is exactly twice of what I set
That's correct. Please search the list archives to learn why things
behave this way and why they are not going to change.
I wish that this long winded, and often occurring thread not occur
again.
Hmm. There are two aspects to this: explaining why "*2" is done,
and the fact that getsockopt() reports something other than
what was given to setsockopt().
The best way to prevent questions about the "*2" is to document it.
Below some text by Andi Kleen.
--- ../linux-2.4.7/linux/net/core/sock.c Sat Jul 28 17:08:47 2001
+++ linux/net/core/sock.c Thu Aug 2 16:23:53 2001
@@ -232,6 +232,8 @@
val = sysctl_wmem_max;
sk->userlocks |= SOCK_SNDBUF_LOCK;
+
+ /* For the "*2", see SO_RCVBUF below. */
sk->sndbuf = max(val*2,SOCK_MIN_SNDBUF);
/*
@@ -251,7 +253,18 @@
val = sysctl_rmem_max;
sk->userlocks |= SOCK_RCVBUF_LOCK;
- /* FIXME: is this lower bound the right one? */
+
+ /* People regularly wonder whether the "*2" here
+ is correct. Linux reserves half of the socket
+ buffer for metadata (skbuff headers etc.)
+ BSD doesn't do that. Most programs using
+ SO_SNDBUF/SO_RCVBUF didn't expect this, because
+ traditional BSD does not do metadata accounting,
+ and on Linux they ended up with too small effective
+ buffers. To fix this Linux always doubles the
+ buffer internally to stay compatible.
+ See also socket(7). */
+
sk->rcvbuf = max(val*2,SOCK_MIN_RCVBUF);
break;
Of course everybody will regard a system broken that has a getfoo()
that does not return what was given to setfoo().
No documentation will change that.
Andries
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: setsockopt(..,SO_RCVBUF,..) sets wrong value
2001-08-02 14:38 Andries.Brouwer
@ 2001-08-02 15:59 ` Richard B. Johnson
0 siblings, 0 replies; 5+ messages in thread
From: Richard B. Johnson @ 2001-08-02 15:59 UTC (permalink / raw)
To: Andries.Brouwer; +Cc: alan, davem, mbartz, torvalds, linux-kernel
On Thu, 2 Aug 2001 Andries.Brouwer@cwi.nl wrote:
[SNIPPED...]
Then shouldn't it return exactly the value that was set?
Whatever the kernel does internally with the value is of no
concern to the caller at the API. It could multiply it by the
phase-of-the-moon if necessary.
When an API says "set_foo(123)", it must be able to do
"val = get_foo()" and retrieve the same value. If not, it's
broken.
Instead of writing more documentation to explain an obvious bug
at the API, it should simply be fixed.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
I was going to compile a list of innovations that could be
attributed to Microsoft. Once I realized that Ctrl-Alt-Del
was handled in the BIOS, I found that there aren't any.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-08-02 16:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-08-02 10:34 setsockopt(..,SO_RCVBUF,..) sets wrong value Manfred Bartz
2001-08-02 13:12 ` David S. Miller
[not found] <no.id>
2001-08-02 14:26 ` Alan Cox
-- strict thread matches above, loose matches on Subject: below --
2001-08-02 14:38 Andries.Brouwer
2001-08-02 15:59 ` Richard B. Johnson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox