3

What is the correct way to set the buffer (ie., SO_RCVBUF, SO_SNDBUF) size of an accept()'d socket under Linux?

The obvious answer would be to call setsockopt() on the newly created socket, however the tcp man page states:

On individual connections, the socket buffer size must be set prior to the listen(2) or connect(2) calls in order to have it take effect. See socket(7) for more information.

That makes sense as the buffer is likely allocated upon creation and therefor I'll have to rely on the inheritance semantics of the listening socket by setting it's buffer size, except the man page (nor that of socket) makes any mention of inheritance and actually states:

On Linux, the new socket returned by accept() does not inherit file status flags such as O_NONBLOCK and O_ASYNC from the listening socket. This behavior differs from the canonical BSD sockets implementation. Portable programs should not rely on inheritance or noninheritance of file status flags and always explicitly set all required flags on the socket returned from accept()

It's not clear what "file status flags" refer to and whether or not it's inclusive of socket options and while having read a few related stackoverflow questions I'm none the wiser.

Community
  • 1
  • 1
Emjayen
  • 113
  • 1
  • 8
  • I don't think "flags" includes the socket buffer sizes. In any case what you really need to do is test it. For that you can run `ss -aie` to see the buffer sizes and much more--for both the listening socket and the accepted ones. – John Zwinck Sep 29 '16 at 13:39
  • @JohnZwinck No, I wouldn't assume so either however that's the closest reference to details of socket inheritance I could find. – Emjayen Sep 29 '16 at 13:54
  • `It's not clear what "file status flags" refer to` It is very clear: the accept() system call actually allocates (creates) a filedescriptor, which inherits (some of) its attributes from the listen() socket. Most of the inheriting refers to the IP stack (which came first, at least: initiated all these events) , some of it does not. – wildplasser Sep 29 '16 at 23:26
  • 'File status flags' means things beginning with O_ that are booleans. – user207421 Sep 29 '16 at 23:39

1 Answers1

3

That first quotation only applies to the receive buffer, and the real reason is so that a window scale can be negotiated during the connect handshake if it is >= 64k. The answer is indeed to set it on the listening socket, from where it will inherited by all accepted sockets, and no, it isn't a file status flag.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • This is a great answer that helped us diagnose a severe performance issue. The kernel behaviour was really weird when we set the buffer sizes on the socket after accepting the connection. Technically it worked, reading back the buffer size suggested the change was applied. Yet it caused abysmal performance when buf size was less than 64k. – Piotr Kołaczkowski Mar 08 '23 at 11:19