public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 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
[parent not found: <no.id>]
* 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

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