msg144526 - (view) |
Author: Artyom Gavrichenkov (ximaera) |
Date: 2011-09-25 17:12 |
Currently the Python implementation of socket.getsockopt allows only option name, level name and buffer size as its arguments. However, IEEE Standard 1003.1-2008 allows one further argument -- an actual buffer to modify at the kernel level. POSIX does not prohibit the kernel from reading this buffer before modification, and the contents of the buffer may be used together with option and level names to specify an exact socket option to return. In fact, this is how some applications already work, ipset (http://ipset.netfilter.org/) being a noticeable example. The patch, written against Python 3.2 and aiming at providing this functionality, is attached. It may also apply to previous Python versions, though it's not tested against anything except Python 3.2. |
|
|
msg144824 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2011-10-03 17:04 |
Hello, method:: socket.getsockopt(level, optname[, optarg]) The overloading of the third parameter is confusing: it can already be an integer value or a buffer size, I don't think that adding a third possibility is a good idea. It might be better to add another optional `buffer` argument (and ignore `buflen` if this argument is provided). Also, it would be nice to have a corresponding unit test: since I doubt this buffer argument is supported by many Unices out there, you can probably reuse a subset of what ipset does (just take care and guard it by @support.requires_linux_version() if applicable). |
|
|
msg144828 - (view) |
Author: Artyom Gavrichenkov (ximaera) |
Date: 2011-10-03 18:29 |
Hi Charles-François, I've attached an update for the previous patch. Now there's no more overloading for the third argument and socket.getsockopt accepts one more optional argument -- a buffer to use as an input to kernel. I can provide a manual sample script, with getsockopt being used this way, that depends on Linux ipset kernel module being installed and modprobe'd. However, automatic unit test is not that easy to implement. Generally ipset requires certain kernel modules to operate, and we either have to install ipset in order to run a unit test, or to implement some mock Linux kernel module purely for testing and support it against all possible kernel versions. Not to mention that such a test should be carried out by root user only. By the way, I don't really think that any POSIX-compliant UNIX out there would treat the buffer given to getsockopt in any way different from what Linux does. It is very easy to copy the buffer from user to kernel and back, and it is so inconvenient to prevent kernel from reading it prior to modification, that I bet no one has ever bothered to do this. |
|
|
msg144958 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2011-10-05 16:45 |
> I've attached an update for the previous patch. Now there's no more > overloading for the third argument and socket.getsockopt accepts one more > optional argument -- a buffer to use as an input to kernel. Remarks: """ + length. If *buffer* is absent and *buflen* is an integer, then *buflen* [...] + this buffer is returned as a bytes object. If *buflen* is absent, an integer """ There's a problem here, the first buflen part should probably be removed. Also, you might want to specify that if a custom buffer is provided, the length argument will be ignored. > By the way, I don't really think that any POSIX-compliant UNIX out there > would treat the buffer given to getsockopt in any way different from what > Linux does. It is very easy to copy the buffer from user to kernel and back, > and it is so inconvenient to prevent kernel from reading it prior to > modification, that I bet no one has ever bothered to do this. Me neither, I don't expect the syscall to return EINVAL: the goal is just to test the correct passing of the input buffer, and the length computation. If we can't test this easily within test_socket, it's ok, I guess the following should be enough: - try supplying a non-buffer argument as fourth parameter (e.g. and int), and check that you get a ValueError - supply a buffer with a size == sizeof(int) (SIZEOF_INT is defined in Lib/test/test_socket.py), and call getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 0, ): this should normally succeed, and return a buffer (check the return type) |
|
|