Skip to content

bpo-12887 and bpo-14345: Document the availability and uses of the SO_ constants. Document SOL_SOCKET #3072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

ammaraskar
Copy link
Member

@ammaraskar ammaraskar commented Aug 11, 2017

The main thing I'm looking for feedback on is how to present information on the main OSs these options are available on. My current approach is to visualize it in a table that looks like this:

so_table

The alternative is to document it with each constant which looks like this:

setfib

However I think this starts to get very repetitive and doesn't look nearly as nice as the table. It does have the advantage that you don't have to scroll back up to the table to see if a certain option is available on your OS, you can see the availability as you read the documentation for the option. (I've commented those out until I make a decision on which approach is better, table or inline)

I've added fairly brief descriptions of each constant, they're ordered in the order they appear in https://github.com/python/cpython/blob/master/Modules/socketmodule.c
The descriptions have been written by consulting man pages and experimentation and any feedback on improving them would be appreciated.

Some of them have vary scant documentation online such as SO_PASSSEC so I've opted to keep those super brief. Hopefully they can be improved over time by the people who added them or otherwise.

https://bugs.python.org/issue12887


When a socket is set to linger. A call to :meth:`socket.close` or
:meth:`socket.shutdown` will not return until all queued messages
for the socket have been successfully sent or the linger timeout
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First sentence does not make sense. Perhaps you should have a comma (,) instead of the full stop (.)?

.. data:: SO_DONTROUTE

Indicates that packets sent through this socket should be routed
through the interface its bound to.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s or it is


SO_RCVLOWAT sets the minimum number of bytes that must be present in
the socket's internal receive buffer before they are passed on to able
read call. SO_SNDLOWAT similiary sets the minimum bytes before data is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand “passed on to able read call”. Perhaps do you mean something like “before the socket becomes readable” or “before they are returned by a read”?

Spelling: similarly

SO_SNDLOWAT is read-only on Linux and SO_RCVLOWAT is read-only on
Linux versions below 2.4.

Both these values default to 1.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Posix, the SNDLOWAT default depends on the implementation and protocol.

SO_SNDTIMEO

Specifies the amount of time send and receive calls for this socket willl
block before timing out. The default timeout of zero means that operations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra l in will.

Is it worth clarifying that these timeouts (which raise EAGAIN etc) are independent of the settimeout mechanism (which raises socket.timeout for non-zero timeouts)?

When bound, only packets received from that particular device are
processsed by the socket.

.. versionadded:: 3.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra s in processed.

According to my patch at https://bugs.python.org/issue27409 this was only added in 3.3 (or did I make a mistake?). See also https://hg.python.org/cpython/rev/6159311f0f44.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I came to the 3.1 number by going to https://github.com/python/cpython/blob/master/Modules/socketmodule.c

Clicking the blame button and checking the tag in the commit. The tag says 3.1 but it looks like that is incorrect, since the README at the time says: This is Python version 3.3 alpha 0


Passing ``SO_DOMAIN`` to :meth:`socket.getsockopt` allows for the retrival
of the ``family`` value as defined in the :func:`socket.socket` function.
``SO_PROTOCOL`` returns the ``proto`` value. Both these options are read only.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it can return the real protocol, e.g. IPPROTO_TCP, even when proto is zero.

``SO_PROTOCOL`` returns the ``proto`` value. Both these options are read only.

The value returned for the ``family`` is an integer and not one of the
friendly constants above like :const:`AF_INET`. In order to get a constant
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The integer value normally does equal one of those enumeration members; it is just that the integer object is never an enumeration member.

SO_PEERCRED

Allows for the passing of SCM credentials over unix sockets.
See the end of :func:`socket.recvmsg` for details.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not familiar with either API, but it seems this only applies to PASSCRED, and PEERCRED returns credentials straight away.

There seems to be something missing with the reference to recvmsg. The end of that entry covers Python versions, platforms, and before that, receiving file descriptors with SCM_RIGHTS. But as I understand it, when using PASSCRED you would look for SCM_CREDENTIALS messages, with a different data structure. The first couple of paragraphs, about receiving anciliary messages in general, are more relevant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not familiar with this API either, I'm just going to add an easily searchable keyword of ancillary message and point to recvmsg


.. versionadded:: 3.6

.. Availability: Linux >= 2.6.13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this come from? What I found was SO_PASSSEC added to Linux 2.6.18 (https://repo.or.cz/linux-2.6-linus.git/commitdiff/877ce7c), and SO_PEERSEC to 2.6.2 (schwabe/tglx-history@da6e57a).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aah that's my mistake. I think 2.6.2 is the right number to include here. I came up with 2.6.13 because I was looking at the blame for sock.c here: https://github.com/torvalds/linux/blame/add459aa1afe05472abc96f6a29aefd0c84e73d6/net/core/sock.c

I scrolled to

case SO_PEERSEC:
    return security_socket_getpeersec_stream(sock, optval, optlen, len);

and saw "Linux-2.6.12-rc2" in the commit message. But it looks like that was a big commit for when Linux switched from bitkeeper to git.

But if we look at the commit that adds

case SO_PASSSEC:
    v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0;
    break;

the commit message says "[AF_UNIX]: Datagram getpeersec" and we can find the same commit in the 2.6.2 changelogs here: https://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.2

So I think its safe to say both of these options are available on >= 2.6.2

@Mariatta Mariatta added needs backport to 3.6 docs Documentation in the Doc dir labels Aug 22, 2017
@pitrou
Copy link
Member

pitrou commented Aug 24, 2017

Hi @ammaraskar! I appreciate the level of work you've put into this. On the other hand, I wonder about the maintenance cost of updating this each time an OS gains support for one those options.
(also, the OS list by far not exhaustive, for example we would certainly want to add an OS X column -- or is it "macOS" these days?)

My personal take would be that people who use the (rather low-level) socket module should know how to check man pages and/or the MSDN documentation for the presence and meaning of specific options. Higher-level alternatives are the various networking frameworks (blocking or non-blocking) and the existing implementations of applicative protocols such as http.

Not sure what others think about this.

@ammaraskar
Copy link
Member Author

On the other hand, I wonder about the maintenance cost of updating this each time an OS gains support for one those options.

I think this will be far and in between, the core socket options are usually a fairly stable OS level API. With the current ones documented, it should hopefully encourage maintainers to document newly added ones and then check their availability accordingly.

As far as an OS gaining support, I think that will be fairly rare but in that case having the documentation being slightly outdated wouldn't be the worst of situations.

There is some older discussion about this on the bpo thread.

My personal take would be that people who use the (rather low-level) socket module should know how to check man pages and/or the MSDN documentation for the presence and meaning of specific options.

I agree, however there is no real documentation on what constants python exposes from the underlying socket library. At the very minimum I think documenting the list of options and brief descriptions of them would be a good idea. Short of doing dir(socket) there is no way to examine what is available.

@matrixise
Copy link
Member

Hi,

@pitrou you are right about the list of the options, we have to check in the official documentation (man pages or MSDN site) but this table with some references can be useful for the beginners, and also for the maintainer, because we can check if an option is directly supported by Python or not.

@ammaraskar
Maybe you could add "This list is incomplete exhaustive and you should to read the documentation of your operating system" and also, add a column for macOS.
But don't forget that we support some operating systems.

@ammaraskar
Copy link
Member Author

At the very least, I think adding documentation for the list of options that socketmodule exports and getsockopt/setsockopt would be useful. I agree that the compatibility table is a bit of a pain to maintain.

@matrixise
Copy link
Member

@ammaraskar How did you find the entries for your table. I propose another solution, for the most used entries, we could keep them in the tables. Add a small paragraph with the link to the official documentation of macOS, Windows and for the man pages for POSIX systems.

@ammaraskar
Copy link
Member Author

I pretty much just went down the list here:

#ifdef SOCK_RAW

Then I looked them up in the man page here for Linux: http://man7.org/linux/man-pages/man7/socket.7.html

FreeBSD here: https://www.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2&apropos=0&manpath=FreeBSD+7.0-RELEASE

and finally Windows here: https://docs.microsoft.com/en-us/windows/desktop/WinSock/sol-socket-socket-options

The availabilities took a bit more digging up but that was the basic idea.

@vstinner
Copy link
Member

I removed the " needs backport to 3.6" label, the 3.6 branch no longer accept bugfixes (only security fixes are accepted): https://devguide.python.org/#status-of-python-branches

@JulienPalard
Copy link
Member

At the very least, I think adding documentation for the list of options that socketmodule exports and getsockopt/setsockopt would be useful. I agree that the compatibility table is a bit of a pain to maintain.

I agree. In one hand I like the table (not having to search the info for an OS you don't know is nice), but it's probably too much work to maintain. Let's just start by documenting the exposed options. @ammaraskar can you remove the compatibility list and fix the previous reviews about?

@csabella
Copy link
Contributor

csabella commented Feb 4, 2020

@ammaraskar, please address the review comments.

@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Feb 21, 2022
@JelleZijlstra
Copy link
Member

Closing as it's been more than two years since changes were requested. Feel free to reopen or submit a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting changes docs Documentation in the Doc dir stale Stale PR or inactive for long period of time.
Projects
None yet
Development

Successfully merging this pull request may close these issues.