This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author tamentis
Recipients tamentis
Date 2014-12-29.13:31:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1419859867.69.0.91970081595.issue23127@psf.upfronthosting.co.za>
In-reply-to
Content
Since I can't re-open issue 3372, I'm opening a new issue.  socket.setsockopt() still sets an optlen of '4' in the setsockopt() system call for options IP_MULTICAST_TTL and IP_MULTICAST_LOOP.  On OpenBSD, this causes the kernel to hit an error condition and set errno 22 when these options are set:

    socket.error: (22, 'Invalid argument')

According to both FreeBSD and OpenBSD manual pages (see e.g. http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man4/ip.4), these fields are in fact both 8 bit unsigned, and the manuals suggest the following:

    u_char ttl;	/* range: 0 to 255, default = 1 */ 
    setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

The following updated patch for branch "2.7" passes a shorter "optlen" for certain Multicast options, it was tested on OpenBSD, Linux and OSX and was initially proposed by niallo:

diff -r 88de50c1696b Modules/socketmodule.c
--- a/Modules/socketmodule.c    Sun Dec 28 18:51:25 2014 +0200
+++ b/Modules/socketmodule.c    Mon Dec 29 08:27:24 2014 -0500
@@ -1879,26 +1879,29 @@
 static PyObject *
 sock_setsockopt(PySocketSockObject *s, PyObject *args)
 {
     int level;
     int optname;
     int res;
     char *buf;
     int buflen;
     int flag;
 
     if (PyArg_ParseTuple(args, "iii:setsockopt",
                          &level, &optname, &flag)) {
+        buflen = sizeof flag;
+        /* Multicast options take shorter arguments */
+        if (optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP)
+            buflen = sizeof(u_char);
         buf = (char *) &flag;
-        buflen = sizeof flag;
     }
     else {
         PyErr_Clear();
         if (!PyArg_ParseTuple(args, "iis#:setsockopt",
                               &level, &optname, &buf, &buflen))
             return NULL;
     }
     res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen);
     if (res < 0)
         return s->errorhandler();
     Py_INCREF(Py_None);
     return Py_None;
History
Date User Action Args
2014-12-29 13:31:07tamentissetrecipients: + tamentis
2014-12-29 13:31:07tamentissetmessageid: <1419859867.69.0.91970081595.issue23127@psf.upfronthosting.co.za>
2014-12-29 13:31:07tamentislinkissue23127 messages
2014-12-29 13:31:06tamentiscreate