Add support for the send/recvmsg API to the socket module. Patch by David Watson and Heiko Wundram. (Closes #6560)
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 8de84b7..75cde79 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -263,6 +263,7 @@
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
+#include <unistd.h>
 
 /* Generic socket object definitions and includes */
 #define PySocket_BUILDING_SOCKET
@@ -469,6 +470,17 @@
 #include <sys/poll.h>
 #endif
 
+/* Largest value to try to store in a socklen_t (used when handling
+   ancillary data).  POSIX requires socklen_t to hold at least
+   (2**31)-1 and recommends against storing larger values, but
+   socklen_t was originally int in the BSD interface, so to be on the
+   safe side we use the smaller of (2**31)-1 and INT_MAX. */
+#if INT_MAX > 0x7fffffff
+#define SOCKLEN_T_LIMIT 0x7fffffff
+#else
+#define SOCKLEN_T_LIMIT INT_MAX
+#endif
+
 #ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
 /* Platform can select file descriptors beyond FD_SETSIZE */
 #define IS_SELECTABLE(s) 1
@@ -1678,6 +1690,117 @@
 }
 
 
+/* Support functions for the sendmsg() and recvmsg[_into]() methods.
+   Currently, these methods are only compiled if the RFC 2292/3542
+   CMSG_LEN() macro is available.  Older systems seem to have used
+   sizeof(struct cmsghdr) + (length) where CMSG_LEN() is used now, so
+   it may be possible to define CMSG_LEN() that way if it's not
+   provided.  Some architectures might need extra padding after the
+   cmsghdr, however, and CMSG_LEN() would have to take account of
+   this. */
+#ifdef CMSG_LEN
+/* If length is in range, set *result to CMSG_LEN(length) and return
+   true; otherwise, return false. */
+static int
+get_CMSG_LEN(size_t length, size_t *result)
+{
+    size_t tmp;
+
+    if (length > (SOCKLEN_T_LIMIT - CMSG_LEN(0)))
+        return 0;
+    tmp = CMSG_LEN(length);
+    if (tmp > SOCKLEN_T_LIMIT || tmp < length)
+        return 0;
+    *result = tmp;
+    return 1;
+}
+
+#ifdef CMSG_SPACE
+/* If length is in range, set *result to CMSG_SPACE(length) and return
+   true; otherwise, return false. */
+static int
+get_CMSG_SPACE(size_t length, size_t *result)
+{
+    size_t tmp;
+
+    /* Use CMSG_SPACE(1) here in order to take account of the padding
+       necessary before *and* after the data. */
+    if (length > (SOCKLEN_T_LIMIT - CMSG_SPACE(1)))
+        return 0;
+    tmp = CMSG_SPACE(length);
+    if (tmp > SOCKLEN_T_LIMIT || tmp < length)
+        return 0;
+    *result = tmp;
+    return 1;
+}
+#endif
+
+/* Return true iff msg->msg_controllen is valid, cmsgh is a valid
+   pointer in msg->msg_control with at least "space" bytes after it,
+   and its cmsg_len member inside the buffer. */
+static int
+cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space)
+{
+    size_t cmsg_offset;
+    static const size_t cmsg_len_end = (offsetof(struct cmsghdr, cmsg_len) +
+                                        sizeof(cmsgh->cmsg_len));
+
+    if (cmsgh == NULL || msg->msg_control == NULL || msg->msg_controllen < 0)
+        return 0;
+    if (space < cmsg_len_end)
+        space = cmsg_len_end;
+    cmsg_offset = (char *)cmsgh - (char *)msg->msg_control;
+    return (cmsg_offset <= (size_t)-1 - space &&
+            cmsg_offset + space <= msg->msg_controllen);
+}
+
+/* If pointer CMSG_DATA(cmsgh) is in buffer msg->msg_control, set
+   *space to number of bytes following it in the buffer and return
+   true; otherwise, return false.  Assumes cmsgh, msg->msg_control and
+   msg->msg_controllen are valid. */
+static int
+get_cmsg_data_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *space)
+{
+    size_t data_offset;
+    char *data_ptr;
+
+    if ((data_ptr = (char *)CMSG_DATA(cmsgh)) == NULL)
+        return 0;
+    data_offset = data_ptr - (char *)msg->msg_control;
+    if (data_offset > msg->msg_controllen)
+        return 0;
+    *space = msg->msg_controllen - data_offset;
+    return 1;
+}
+
+/* If cmsgh is invalid or not contained in the buffer pointed to by
+   msg->msg_control, return -1.  If cmsgh is valid and its associated
+   data is entirely contained in the buffer, set *data_len to the
+   length of the associated data and return 0.  If only part of the
+   associated data is contained in the buffer but cmsgh is otherwise
+   valid, set *data_len to the length contained in the buffer and
+   return 1. */
+static int
+get_cmsg_data_len(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *data_len)
+{
+    size_t space, cmsg_data_len;
+
+    if (!cmsg_min_space(msg, cmsgh, CMSG_LEN(0)) ||
+        cmsgh->cmsg_len < CMSG_LEN(0))
+        return -1;
+    cmsg_data_len = cmsgh->cmsg_len - CMSG_LEN(0);
+    if (!get_cmsg_data_space(msg, cmsgh, &space))
+        return -1;
+    if (space >= cmsg_data_len) {
+        *data_len = cmsg_data_len;
+        return 0;
+    }
+    *data_len = space;
+    return 1;
+}
+#endif    /* CMSG_LEN */
+
+
 /* s._accept() -> (fd, address) */
 
 static PyObject *
@@ -2631,6 +2754,333 @@
 Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
 
 
+/* The sendmsg() and recvmsg[_into]() methods require a working
+   CMSG_LEN().  See the comment near get_CMSG_LEN(). */
+#ifdef CMSG_LEN
+/*
+ * Call recvmsg() with the supplied iovec structures, flags, and
+ * ancillary data buffer size (controllen).  Returns the tuple return
+ * value for recvmsg() or recvmsg_into(), with the first item provided
+ * by the supplied makeval() function.  makeval() will be called with
+ * the length read and makeval_data as arguments, and must return a
+ * new reference (which will be decrefed if there is a subsequent
+ * error).  On error, closes any file descriptors received via
+ * SCM_RIGHTS.
+ */
+static PyObject *
+sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen,
+                  int flags, Py_ssize_t controllen,
+                  PyObject *(*makeval)(ssize_t, void *), void *makeval_data)
+{
+    ssize_t bytes_received = -1;
+    int timeout;
+    sock_addr_t addrbuf;
+    socklen_t addrbuflen;
+    static const struct msghdr msg_blank;
+    struct msghdr msg;
+    PyObject *cmsg_list = NULL, *retval = NULL;
+    void *controlbuf = NULL;
+    struct cmsghdr *cmsgh;
+    size_t cmsgdatalen = 0;
+    int cmsg_status;
+
+    /* XXX: POSIX says that msg_name and msg_namelen "shall be
+       ignored" when the socket is connected (Linux fills them in
+       anyway for AF_UNIX sockets at least).  Normally msg_namelen
+       seems to be set to 0 if there's no address, but try to
+       initialize msg_name to something that won't be mistaken for a
+       real address if that doesn't happen. */
+    if (!getsockaddrlen(s, &addrbuflen))
+        return NULL;
+    memset(&addrbuf, 0, addrbuflen);
+    SAS2SA(&addrbuf)->sa_family = AF_UNSPEC;
+
+    if (controllen < 0 || controllen > SOCKLEN_T_LIMIT) {
+        PyErr_SetString(PyExc_ValueError,
+                        "invalid ancillary data buffer length");
+        return NULL;
+    }
+    if (controllen > 0 && (controlbuf = PyMem_Malloc(controllen)) == NULL)
+        return PyErr_NoMemory();
+
+    /* Make the system call. */
+    if (!IS_SELECTABLE(s)) {
+        select_error();
+        goto finally;
+    }
+
+    BEGIN_SELECT_LOOP(s)
+    Py_BEGIN_ALLOW_THREADS;
+    msg = msg_blank;    /* Set all members to 0 or NULL */
+    msg.msg_name = SAS2SA(&addrbuf);
+    msg.msg_namelen = addrbuflen;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = iovlen;
+    msg.msg_control = controlbuf;
+    msg.msg_controllen = controllen;
+    timeout = internal_select_ex(s, 0, interval);
+    if (!timeout)
+        bytes_received = recvmsg(s->sock_fd, &msg, flags);
+    Py_END_ALLOW_THREADS;
+    if (timeout == 1) {
+        PyErr_SetString(socket_timeout, "timed out");
+        goto finally;
+    }
+    END_SELECT_LOOP(s)
+
+    if (bytes_received < 0) {
+        s->errorhandler();
+        goto finally;
+    }
+
+    /* Make list of (level, type, data) tuples from control messages. */
+    if ((cmsg_list = PyList_New(0)) == NULL)
+        goto err_closefds;
+    /* Check for empty ancillary data as old CMSG_FIRSTHDR()
+       implementations didn't do so. */
+    for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL);
+         cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) {
+        PyObject *bytes, *tuple;
+        int tmp;
+
+        cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen);
+        if (cmsg_status != 0) {
+            if (PyErr_WarnEx(PyExc_RuntimeWarning,
+                             "received malformed or improperly-truncated "
+                             "ancillary data", 1) == -1)
+                goto err_closefds;
+        }
+        if (cmsg_status < 0)
+            break;
+        if (cmsgdatalen > PY_SSIZE_T_MAX) {
+            PyErr_SetString(socket_error, "control message too long");
+            goto err_closefds;
+        }
+
+        bytes = PyBytes_FromStringAndSize((char *)CMSG_DATA(cmsgh),
+                                          cmsgdatalen);
+        tuple = Py_BuildValue("iiN", (int)cmsgh->cmsg_level,
+                              (int)cmsgh->cmsg_type, bytes);
+        if (tuple == NULL)
+            goto err_closefds;
+        tmp = PyList_Append(cmsg_list, tuple);
+        Py_DECREF(tuple);
+        if (tmp != 0)
+            goto err_closefds;
+
+        if (cmsg_status != 0)
+            break;
+    }
+
+    retval = Py_BuildValue("NOiN",
+                           (*makeval)(bytes_received, makeval_data),
+                           cmsg_list,
+                           (int)msg.msg_flags,
+                           makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
+                                        ((msg.msg_namelen > addrbuflen) ?
+                                         addrbuflen : msg.msg_namelen),
+                                        s->sock_proto));
+    if (retval == NULL)
+        goto err_closefds;
+
+finally:
+    Py_XDECREF(cmsg_list);
+    PyMem_Free(controlbuf);
+    return retval;
+
+err_closefds:
+#ifdef SCM_RIGHTS
+    /* Close all descriptors coming from SCM_RIGHTS, so they don't leak. */
+    for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL);
+         cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) {
+        cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen);
+        if (cmsg_status < 0)
+            break;
+        if (cmsgh->cmsg_level == SOL_SOCKET &&
+            cmsgh->cmsg_type == SCM_RIGHTS) {
+            size_t numfds;
+            int *fdp;
+
+            numfds = cmsgdatalen / sizeof(int);
+            fdp = (int *)CMSG_DATA(cmsgh);
+            while (numfds-- > 0)
+                close(*fdp++);
+        }
+        if (cmsg_status != 0)
+            break;
+    }
+#endif /* SCM_RIGHTS */
+    goto finally;
+}
+
+
+static PyObject *
+makeval_recvmsg(ssize_t received, void *data)
+{
+    PyObject **buf = data;
+
+    if (received < PyBytes_GET_SIZE(*buf))
+        _PyBytes_Resize(buf, received);
+    Py_XINCREF(*buf);
+    return *buf;
+}
+
+/* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */
+
+static PyObject *
+sock_recvmsg(PySocketSockObject *s, PyObject *args)
+{
+    Py_ssize_t bufsize, ancbufsize = 0;
+    int flags = 0;
+    struct iovec iov;
+    PyObject *buf = NULL, *retval = NULL;
+
+    if (!PyArg_ParseTuple(args, "n|ni:recvmsg", &bufsize, &ancbufsize, &flags))
+        return NULL;
+
+    if (bufsize < 0) {
+        PyErr_SetString(PyExc_ValueError, "negative buffer size in recvmsg()");
+        return NULL;
+    }
+    if ((buf = PyBytes_FromStringAndSize(NULL, bufsize)) == NULL)
+        return NULL;
+    iov.iov_base = PyBytes_AS_STRING(buf);
+    iov.iov_len = bufsize;
+
+    /* Note that we're passing a pointer to *our pointer* to the bytes
+       object here (&buf); makeval_recvmsg() may incref the object, or
+       deallocate it and set our pointer to NULL. */
+    retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize,
+                               &makeval_recvmsg, &buf);
+    Py_XDECREF(buf);
+    return retval;
+}
+
+PyDoc_STRVAR(recvmsg_doc,
+"recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)\n\
+\n\
+Receive normal data (up to bufsize bytes) and ancillary data from the\n\
+socket.  The ancbufsize argument sets the size in bytes of the\n\
+internal buffer used to receive the ancillary data; it defaults to 0,\n\
+meaning that no ancillary data will be received.  Appropriate buffer\n\
+sizes for ancillary data can be calculated using CMSG_SPACE() or\n\
+CMSG_LEN(), and items which do not fit into the buffer might be\n\
+truncated or discarded.  The flags argument defaults to 0 and has the\n\
+same meaning as for recv().\n\
+\n\
+The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n\
+The data item is a bytes object holding the non-ancillary data\n\
+received.  The ancdata item is a list of zero or more tuples\n\
+(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n\
+(control messages) received: cmsg_level and cmsg_type are integers\n\
+specifying the protocol level and protocol-specific type respectively,\n\
+and cmsg_data is a bytes object holding the associated data.  The\n\
+msg_flags item is the bitwise OR of various flags indicating\n\
+conditions on the received message; see your system documentation for\n\
+details.  If the receiving socket is unconnected, address is the\n\
+address of the sending socket, if available; otherwise, its value is\n\
+unspecified.\n\
+\n\
+If recvmsg() raises an exception after the system call returns, it\n\
+will first attempt to close any file descriptors received via the\n\
+SCM_RIGHTS mechanism.");
+
+
+static PyObject *
+makeval_recvmsg_into(ssize_t received, void *data)
+{
+    return PyLong_FromSsize_t(received);
+}
+
+/* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */
+
+static PyObject *
+sock_recvmsg_into(PySocketSockObject *s, PyObject *args)
+{
+    Py_ssize_t ancbufsize = 0;
+    int flags = 0;
+    struct iovec *iovs = NULL;
+    Py_ssize_t i, nitems, nbufs = 0;
+    Py_buffer *bufs = NULL;
+    PyObject *buffers_arg, *fast, *retval = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into",
+                          &buffers_arg, &ancbufsize, &flags))
+        return NULL;
+
+    if ((fast = PySequence_Fast(buffers_arg,
+                                "recvmsg_into() argument 1 must be an "
+                                "iterable")) == NULL)
+        return NULL;
+    nitems = PySequence_Fast_GET_SIZE(fast);
+    if (nitems > INT_MAX) {
+        PyErr_SetString(socket_error, "recvmsg_into() argument 1 is too long");
+        goto finally;
+    }
+
+    /* Fill in an iovec for each item, and save the Py_buffer
+       structs to release afterwards. */
+    if (nitems > 0 && ((iovs = PyMem_New(struct iovec, nitems)) == NULL ||
+                       (bufs = PyMem_New(Py_buffer, nitems)) == NULL)) {
+        PyErr_NoMemory();
+        goto finally;
+    }
+    for (; nbufs < nitems; nbufs++) {
+        if (!PyArg_Parse(PySequence_Fast_GET_ITEM(fast, nbufs),
+                         "w*;recvmsg_into() argument 1 must be an iterable "
+                         "of single-segment read-write buffers",
+                         &bufs[nbufs]))
+            goto finally;
+        iovs[nbufs].iov_base = bufs[nbufs].buf;
+        iovs[nbufs].iov_len = bufs[nbufs].len;
+    }
+
+    retval = sock_recvmsg_guts(s, iovs, nitems, flags, ancbufsize,
+                               &makeval_recvmsg_into, NULL);
+finally:
+    for (i = 0; i < nbufs; i++)
+        PyBuffer_Release(&bufs[i]);
+    PyMem_Free(bufs);
+    PyMem_Free(iovs);
+    Py_DECREF(fast);
+    return retval;
+}
+
+PyDoc_STRVAR(recvmsg_into_doc,
+"recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)\n\
+\n\
+Receive normal data and ancillary data from the socket, scattering the\n\
+non-ancillary data into a series of buffers.  The buffers argument\n\
+must be an iterable of objects that export writable buffers\n\
+(e.g. bytearray objects); these will be filled with successive chunks\n\
+of the non-ancillary data until it has all been written or there are\n\
+no more buffers.  The ancbufsize argument sets the size in bytes of\n\
+the internal buffer used to receive the ancillary data; it defaults to\n\
+0, meaning that no ancillary data will be received.  Appropriate\n\
+buffer sizes for ancillary data can be calculated using CMSG_SPACE()\n\
+or CMSG_LEN(), and items which do not fit into the buffer might be\n\
+truncated or discarded.  The flags argument defaults to 0 and has the\n\
+same meaning as for recv().\n\
+\n\
+The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).\n\
+The nbytes item is the total number of bytes of non-ancillary data\n\
+written into the buffers.  The ancdata item is a list of zero or more\n\
+tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary\n\
+data (control messages) received: cmsg_level and cmsg_type are\n\
+integers specifying the protocol level and protocol-specific type\n\
+respectively, and cmsg_data is a bytes object holding the associated\n\
+data.  The msg_flags item is the bitwise OR of various flags\n\
+indicating conditions on the received message; see your system\n\
+documentation for details.  If the receiving socket is unconnected,\n\
+address is the address of the sending socket, if available; otherwise,\n\
+its value is unspecified.\n\
+\n\
+If recvmsg_into() raises an exception after the system call returns,\n\
+it will first attempt to close any file descriptors received via the\n\
+SCM_RIGHTS mechanism.");
+#endif    /* CMSG_LEN */
+
+
 /* s.send(data [,flags]) method */
 
 static PyObject *
@@ -2826,6 +3276,237 @@
 For IP sockets, the address is a pair (hostaddr, port).");
 
 
+/* The sendmsg() and recvmsg[_into]() methods require a working
+   CMSG_LEN().  See the comment near get_CMSG_LEN(). */
+#ifdef CMSG_LEN
+/* s.sendmsg(buffers[, ancdata[, flags[, address]]]) method */
+
+static PyObject *
+sock_sendmsg(PySocketSockObject *s, PyObject *args)
+{
+    Py_ssize_t i, ndataparts, ndatabufs = 0, ncmsgs, ncmsgbufs = 0;
+    Py_buffer *databufs = NULL;
+    struct iovec *iovs = NULL;
+    sock_addr_t addrbuf;
+    static const struct msghdr msg_blank;
+    struct msghdr msg;
+    struct cmsginfo {
+        int level;
+        int type;
+        Py_buffer data;
+    } *cmsgs = NULL;
+    void *controlbuf = NULL;
+    size_t controllen, controllen_last;
+    ssize_t bytes_sent = -1;
+    int addrlen, timeout, flags = 0;
+    PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *data_fast = NULL,
+        *cmsg_fast = NULL, *retval = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|OiO:sendmsg",
+                          &data_arg, &cmsg_arg, &flags, &addr_arg))
+        return NULL;
+
+    msg = msg_blank;    /* Set all members to 0 or NULL */
+
+    /* Parse destination address. */
+    if (addr_arg != NULL && addr_arg != Py_None) {
+        if (!getsockaddrarg(s, addr_arg, SAS2SA(&addrbuf), &addrlen))
+            goto finally;
+        msg.msg_name = &addrbuf;
+        msg.msg_namelen = addrlen;
+    }
+
+    /* Fill in an iovec for each message part, and save the Py_buffer
+       structs to release afterwards. */
+    if ((data_fast = PySequence_Fast(data_arg,
+                                     "sendmsg() argument 1 must be an "
+                                     "iterable")) == NULL)
+        goto finally;
+    ndataparts = PySequence_Fast_GET_SIZE(data_fast);
+    if (ndataparts > INT_MAX) {
+        PyErr_SetString(socket_error, "sendmsg() argument 1 is too long");
+        goto finally;
+    }
+    msg.msg_iovlen = ndataparts;
+    if (ndataparts > 0 &&
+        ((msg.msg_iov = iovs = PyMem_New(struct iovec, ndataparts)) == NULL ||
+         (databufs = PyMem_New(Py_buffer, ndataparts)) == NULL)) {
+        PyErr_NoMemory();
+        goto finally;
+    }
+    for (; ndatabufs < ndataparts; ndatabufs++) {
+        if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs),
+                         "y*;sendmsg() argument 1 must be an iterable of "
+                         "buffer-compatible objects",
+                         &databufs[ndatabufs]))
+            goto finally;
+        iovs[ndatabufs].iov_base = databufs[ndatabufs].buf;
+        iovs[ndatabufs].iov_len = databufs[ndatabufs].len;
+    }
+
+    if (cmsg_arg == NULL)
+        ncmsgs = 0;
+    else {
+        if ((cmsg_fast = PySequence_Fast(cmsg_arg,
+                                         "sendmsg() argument 2 must be an "
+                                         "iterable")) == NULL)
+            goto finally;
+        ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast);
+    }
+
+#ifndef CMSG_SPACE
+    if (ncmsgs > 1) {
+        PyErr_SetString(socket_error,
+                        "sending multiple control messages is not supported "
+                        "on this system");
+        goto finally;
+    }
+#endif
+    /* Save level, type and Py_buffer for each control message,
+       and calculate total size. */
+    if (ncmsgs > 0 && (cmsgs = PyMem_New(struct cmsginfo, ncmsgs)) == NULL) {
+        PyErr_NoMemory();
+        goto finally;
+    }
+    controllen = controllen_last = 0;
+    while (ncmsgbufs < ncmsgs) {
+        size_t bufsize, space;
+
+        if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs),
+                         "(iiy*):[sendmsg() ancillary data items]",
+                         &cmsgs[ncmsgbufs].level,
+                         &cmsgs[ncmsgbufs].type,
+                         &cmsgs[ncmsgbufs].data))
+            goto finally;
+        bufsize = cmsgs[ncmsgbufs++].data.len;
+
+#ifdef CMSG_SPACE
+        if (!get_CMSG_SPACE(bufsize, &space)) {
+#else
+        if (!get_CMSG_LEN(bufsize, &space)) {
+#endif
+            PyErr_SetString(socket_error, "ancillary data item too large");
+            goto finally;
+        }
+        controllen += space;
+        if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) {
+            PyErr_SetString(socket_error, "too much ancillary data");
+            goto finally;
+        }
+        controllen_last = controllen;
+    }
+
+    /* Construct ancillary data block from control message info. */
+    if (ncmsgbufs > 0) {
+        struct cmsghdr *cmsgh = NULL;
+
+        if ((msg.msg_control = controlbuf =
+             PyMem_Malloc(controllen)) == NULL) {
+            PyErr_NoMemory();
+            goto finally;
+        }
+        msg.msg_controllen = controllen;
+
+        /* Need to zero out the buffer as a workaround for glibc's
+           CMSG_NXTHDR() implementation.  After getting the pointer to
+           the next header, it checks its (uninitialized) cmsg_len
+           member to see if the "message" fits in the buffer, and
+           returns NULL if it doesn't.  Zero-filling the buffer
+           ensures that that doesn't happen. */
+        memset(controlbuf, 0, controllen);
+
+        for (i = 0; i < ncmsgbufs; i++) {
+            size_t msg_len, data_len = cmsgs[i].data.len;
+            int enough_space = 0;
+
+            cmsgh = (i == 0) ? CMSG_FIRSTHDR(&msg) : CMSG_NXTHDR(&msg, cmsgh);
+            if (cmsgh == NULL) {
+                PyErr_Format(PyExc_RuntimeError,
+                             "unexpected NULL result from %s()",
+                             (i == 0) ? "CMSG_FIRSTHDR" : "CMSG_NXTHDR");
+                goto finally;
+            }
+            if (!get_CMSG_LEN(data_len, &msg_len)) {
+                PyErr_SetString(PyExc_RuntimeError,
+                                "item size out of range for CMSG_LEN()");
+                goto finally;
+            }
+            if (cmsg_min_space(&msg, cmsgh, msg_len)) {
+                size_t space;
+
+                cmsgh->cmsg_len = msg_len;
+                if (get_cmsg_data_space(&msg, cmsgh, &space))
+                    enough_space = (space >= data_len);
+            }
+            if (!enough_space) {
+                PyErr_SetString(PyExc_RuntimeError,
+                                "ancillary data does not fit in calculated "
+                                "space");
+                goto finally;
+            }
+            cmsgh->cmsg_level = cmsgs[i].level;
+            cmsgh->cmsg_type = cmsgs[i].type;
+            memcpy(CMSG_DATA(cmsgh), cmsgs[i].data.buf, data_len);
+        }
+    }
+
+    /* Make the system call. */
+    if (!IS_SELECTABLE(s)) {
+        select_error();
+        goto finally;
+    }
+
+    BEGIN_SELECT_LOOP(s)
+    Py_BEGIN_ALLOW_THREADS;
+    timeout = internal_select_ex(s, 1, interval);
+    if (!timeout)
+        bytes_sent = sendmsg(s->sock_fd, &msg, flags);
+    Py_END_ALLOW_THREADS;
+    if (timeout == 1) {
+        PyErr_SetString(socket_timeout, "timed out");
+        goto finally;
+    }
+    END_SELECT_LOOP(s)
+
+    if (bytes_sent < 0) {
+        s->errorhandler();
+        goto finally;
+    }
+    retval = PyLong_FromSsize_t(bytes_sent);
+
+finally:
+    PyMem_Free(controlbuf);
+    for (i = 0; i < ncmsgbufs; i++)
+        PyBuffer_Release(&cmsgs[i].data);
+    PyMem_Free(cmsgs);
+    Py_XDECREF(cmsg_fast);
+    for (i = 0; i < ndatabufs; i++)
+        PyBuffer_Release(&databufs[i]);
+    PyMem_Free(databufs);
+    PyMem_Free(iovs);
+    Py_XDECREF(data_fast);
+    return retval;
+}
+
+PyDoc_STRVAR(sendmsg_doc,
+"sendmsg(buffers[, ancdata[, flags[, address]]]) -> count\n\
+\n\
+Send normal and ancillary data to the socket, gathering the\n\
+non-ancillary data from a series of buffers and concatenating it into\n\
+a single message.  The buffers argument specifies the non-ancillary\n\
+data as an iterable of buffer-compatible objects (e.g. bytes objects).\n\
+The ancdata argument specifies the ancillary data (control messages)\n\
+as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n\
+cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n\
+protocol level and protocol-specific type respectively, and cmsg_data\n\
+is a buffer-compatible object holding the associated data.  The flags\n\
+argument defaults to 0 and has the same meaning as for send().  If\n\
+address is supplied and not None, it sets a destination address for\n\
+the message.  The return value is the number of bytes of non-ancillary\n\
+data sent.");
+#endif    /* CMSG_LEN */
+
+
 /* s.shutdown(how) method */
 
 static PyObject *
@@ -2952,6 +3633,14 @@
                       setsockopt_doc},
     {"shutdown",          (PyCFunction)sock_shutdown, METH_O,
                       shutdown_doc},
+#ifdef CMSG_LEN
+    {"recvmsg",           (PyCFunction)sock_recvmsg, METH_VARARGS,
+                      recvmsg_doc},
+    {"recvmsg_into",      (PyCFunction)sock_recvmsg_into, METH_VARARGS,
+                      recvmsg_into_doc,},
+    {"sendmsg",           (PyCFunction)sock_sendmsg, METH_VARARGS,
+                      sendmsg_doc},
+#endif
     {NULL,                      NULL}           /* sentinel */
 };
 
@@ -4377,6 +5066,68 @@
 #endif  /* HAVE_IF_NAMEINDEX */
 
 
+#ifdef CMSG_LEN
+/* Python interface to CMSG_LEN(length). */
+
+static PyObject *
+socket_CMSG_LEN(PyObject *self, PyObject *args)
+{
+    Py_ssize_t length;
+    size_t result;
+
+    if (!PyArg_ParseTuple(args, "n:CMSG_LEN", &length))
+        return NULL;
+    if (length < 0 || !get_CMSG_LEN(length, &result)) {
+        PyErr_Format(PyExc_OverflowError, "CMSG_LEN() argument out of range");
+        return NULL;
+    }
+    return PyLong_FromSize_t(result);
+}
+
+PyDoc_STRVAR(CMSG_LEN_doc,
+"CMSG_LEN(length) -> control message length\n\
+\n\
+Return the total length, without trailing padding, of an ancillary\n\
+data item with associated data of the given length.  This value can\n\
+often be used as the buffer size for recvmsg() to receive a single\n\
+item of ancillary data, but RFC 3542 requires portable applications to\n\
+use CMSG_SPACE() and thus include space for padding, even when the\n\
+item will be the last in the buffer.  Raises OverflowError if length\n\
+is outside the permissible range of values.");
+
+
+#ifdef CMSG_SPACE
+/* Python interface to CMSG_SPACE(length). */
+
+static PyObject *
+socket_CMSG_SPACE(PyObject *self, PyObject *args)
+{
+    Py_ssize_t length;
+    size_t result;
+
+    if (!PyArg_ParseTuple(args, "n:CMSG_SPACE", &length))
+        return NULL;
+    if (length < 0 || !get_CMSG_SPACE(length, &result)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "CMSG_SPACE() argument out of range");
+        return NULL;
+    }
+    return PyLong_FromSize_t(result);
+}
+
+PyDoc_STRVAR(CMSG_SPACE_doc,
+"CMSG_SPACE(length) -> buffer size\n\
+\n\
+Return the buffer size needed for recvmsg() to receive an ancillary\n\
+data item with associated data of the given length, along with any\n\
+trailing padding.  The buffer space needed to receive multiple items\n\
+is the sum of the CMSG_SPACE() values for their associated data\n\
+lengths.  Raises OverflowError if length is outside the permissible\n\
+range of values.");
+#endif    /* CMSG_SPACE */
+#endif    /* CMSG_LEN */
+
+
 /* List of functions exported by this module. */
 
 static PyMethodDef socket_methods[] = {
@@ -4440,6 +5191,14 @@
     {"if_indextoname", socket_if_indextoname,
      METH_O, if_indextoname_doc},
 #endif
+#ifdef CMSG_LEN
+    {"CMSG_LEN",                socket_CMSG_LEN,
+     METH_VARARGS, CMSG_LEN_doc},
+#ifdef CMSG_SPACE
+    {"CMSG_SPACE",              socket_CMSG_SPACE,
+     METH_VARARGS, CMSG_SPACE_doc},
+#endif
+#endif
     {NULL,                      NULL}            /* Sentinel */
 };
 
@@ -4927,6 +5686,15 @@
 #ifdef  SO_SETFIB
     PyModule_AddIntConstant(m, "SO_SETFIB", SO_SETFIB);
 #endif
+#ifdef  SO_PASSCRED
+    PyModule_AddIntConstant(m, "SO_PASSCRED", SO_PASSCRED);
+#endif
+#ifdef  SO_PEERCRED
+    PyModule_AddIntConstant(m, "SO_PEERCRED", SO_PEERCRED);
+#endif
+#ifdef  LOCAL_PEERCRED
+    PyModule_AddIntConstant(m, "LOCAL_PEERCRED", LOCAL_PEERCRED);
+#endif
 
     /* Maximum number of connections for "listen" */
 #ifdef  SOMAXCONN
@@ -4935,6 +5703,17 @@
     PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */
 #endif
 
+    /* Ancilliary message types */
+#ifdef  SCM_RIGHTS
+    PyModule_AddIntConstant(m, "SCM_RIGHTS", SCM_RIGHTS);
+#endif
+#ifdef  SCM_CREDENTIALS
+    PyModule_AddIntConstant(m, "SCM_CREDENTIALS", SCM_CREDENTIALS);
+#endif
+#ifdef  SCM_CREDS
+    PyModule_AddIntConstant(m, "SCM_CREDS", SCM_CREDS);
+#endif
+
     /* Flags for send, recv */
 #ifdef  MSG_OOB
     PyModule_AddIntConstant(m, "MSG_OOB", MSG_OOB);
@@ -4966,6 +5745,33 @@
 #ifdef  MSG_ETAG
     PyModule_AddIntConstant(m, "MSG_ETAG", MSG_ETAG);
 #endif
+#ifdef  MSG_NOSIGNAL
+    PyModule_AddIntConstant(m, "MSG_NOSIGNAL", MSG_NOSIGNAL);
+#endif
+#ifdef  MSG_NOTIFICATION
+    PyModule_AddIntConstant(m, "MSG_NOTIFICATION", MSG_NOTIFICATION);
+#endif
+#ifdef  MSG_CMSG_CLOEXEC
+    PyModule_AddIntConstant(m, "MSG_CMSG_CLOEXEC", MSG_CMSG_CLOEXEC);
+#endif
+#ifdef  MSG_ERRQUEUE
+    PyModule_AddIntConstant(m, "MSG_ERRQUEUE", MSG_ERRQUEUE);
+#endif
+#ifdef  MSG_CONFIRM
+    PyModule_AddIntConstant(m, "MSG_CONFIRM", MSG_CONFIRM);
+#endif
+#ifdef  MSG_MORE
+    PyModule_AddIntConstant(m, "MSG_MORE", MSG_MORE);
+#endif
+#ifdef  MSG_EOF
+    PyModule_AddIntConstant(m, "MSG_EOF", MSG_EOF);
+#endif
+#ifdef  MSG_BCAST
+    PyModule_AddIntConstant(m, "MSG_BCAST", MSG_BCAST);
+#endif
+#ifdef  MSG_MCAST
+    PyModule_AddIntConstant(m, "MSG_MCAST", MSG_MCAST);
+#endif
 
     /* Protocol level and numbers, usable for [gs]etsockopt */
 #ifdef  SOL_SOCKET
@@ -5105,6 +5911,9 @@
 #ifdef  IPPROTO_VRRP
     PyModule_AddIntConstant(m, "IPPROTO_VRRP", IPPROTO_VRRP);
 #endif
+#ifdef  IPPROTO_SCTP
+    PyModule_AddIntConstant(m, "IPPROTO_SCTP", IPPROTO_SCTP);
+#endif
 #ifdef  IPPROTO_BIP
     PyModule_AddIntConstant(m, "IPPROTO_BIP", IPPROTO_BIP);
 #endif