Re: setsockopt(..,SO_RCVBUF,..) sets wrong value

Andries.Brouwer@cwi.nl
Thu, 2 Aug 2001 14:38:43 GMT


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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/