diff -r 3d726dbfca31 Doc/library/socket.rst --- a/Doc/library/socket.rst Wed Jun 15 17:16:16 2016 -0500 +++ b/Doc/library/socket.rst Thu Jul 21 10:53:53 2016 -0400 @@ -131,6 +131,33 @@ string format. (ex. ``b'12:23:34:45:56:67'``) This protocol is not supported under FreeBSD. + .. versionadded:: 3.4 + +- :const:`AF_VSOCK` sockets are represented as a (CID, port) tuple + where the context ID or CID and port are integers. + + - :const:`VMADDR_CID_ANY` will bind to any CID. Equivalent of INADDR_ANY. + + - :const:`VMADDR_CID_HOST` is the destination CID in an address when + referring to the host. + + - :const:`VMADDR_PORT_ANY` will bind to any available port. + + - :const:`IOCTL_VM_SOCKETS_GET_LOCAL_CID` an IOCTL available to discover + the local CID address. + + - :const:`SO_VM_SOCKETS_BUFFER_SIZE` is used as the option name in + setsockopt or getsockopt to set or get an unsigned long long that + specifies the size of the underlying stream socket buffer. + + - :const:`SO_VM_SOCKETS_BUFFER_MIN_SIZE` is used as the option name in + setsockopt or getsockopt to set or get an unsigned long long that + specifies the minimum size allowed for the underying stream socket buffer. + + - :const:`SO_VM_SOCKETS_BUFFER_MAX_SIZE` is used as the option name in + setsockopt or getsockopt to set or get an unsigned long long that + specifies the maximum size allowed for the underying socket buffer. + - Certain other address families (:const:`AF_PACKET`, :const:`AF_CAN`) support specific representations. diff -r 3d726dbfca31 Modules/socketmodule.c --- a/Modules/socketmodule.c Wed Jun 15 17:16:16 2016 -0500 +++ b/Modules/socketmodule.c Thu Jul 21 10:53:53 2016 -0400 @@ -7,7 +7,8 @@ Limitations: - Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a - portable manner, though AF_PACKET, AF_NETLINK and AF_TIPC are supported + portable manner, though AF_PACKET, AF_NETLINK, AF_VSOCK and AF_TIPCi + are supported under Linux. - No read/write operations (use sendall/recv or makefile instead). - Additional restrictions apply on some non-Unix platforms (compensated @@ -183,6 +184,7 @@ # endif #endif + #if !defined(HAVE_GETHOSTBYNAME_R) && defined(WITH_THREAD) && \ !defined(MS_WINDOWS) # define USE_GETHOSTBYNAME_LOCK @@ -1206,6 +1208,14 @@ } #endif /* AF_NETLINK */ +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm *a = (struct sockaddr_vm *) addr; + return Py_BuildValue("II", a->svm_cid, a->svm_port); + } +#endif /* AF_VSOCK */ + #ifdef ENABLE_IPV6 case AF_INET6: { @@ -1538,6 +1548,32 @@ } #endif +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm* addr; + int port, cid; + addr = (struct sockaddr_vm *)addr_ret; + memset(addr, 0, sizeof(struct sockaddr_vm)); + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, + "getsockaddrarg: " + "AF_VSOCK address must be tuple, not %.500s", + Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &cid, &port)) + return 0; + addr->svm_family = s->sock_family; + addr->svm_port = port; + addr->svm_cid = cid; + *len_ret = sizeof(*addr); + return 1; + } +#endif + + #ifdef AF_RDS case AF_RDS: /* RDS sockets use sockaddr_in: fall-through */ @@ -1975,6 +2011,14 @@ } #endif +#if defined(AF_VSOCK) + case AF_VSOCK: + { + *len_ret = sizeof (struct sockaddr_vm); + return 1; + } +#endif + #ifdef AF_RDS case AF_RDS: /* RDS sockets use sockaddr_in: fall-through */ @@ -2448,6 +2492,19 @@ Py_buffer optval; int flag; +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag; + if (PyArg_ParseTuple(args, "iiK:setsockopt", + &level, &optname, &vflag)) { + // level should always be set to AF_VSOCK + res = setsockopt(s->sock_fd, level, optname, + (void*)&vflag, sizeof vflag); + goto finally; + } + } +#endif + if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { res = setsockopt(s->sock_fd, level, optname, @@ -2473,6 +2530,11 @@ #endif PyBuffer_Release(&optval); } + +#ifdef AF_VSOCK +finally: +#endif + if (res < 0) { return s->errorhandler(); } @@ -2500,20 +2562,39 @@ int res; PyObject *buf; socklen_t buflen = 0; + int flag = 0; + socklen_t flagsize; if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &buflen)) return NULL; if (buflen == 0) { - int flag = 0; - socklen_t flagsize = sizeof flag; +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag = 0; + flagsize = sizeof vflag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&vflag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromLong(vflag); + } +#endif + flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, (void *)&flag, &flagsize); if (res < 0) return s->errorhandler(); return PyLong_FromLong(flag); } +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + PyErr_SetString(PyExc_OSError, + "getsockopt string buffer not allowed"); + return NULL; + } +#endif if (buflen <= 0 || buflen > 1024) { PyErr_SetString(PyExc_OSError, "getsockopt buflen out of range"); @@ -6330,6 +6411,19 @@ PyModule_AddIntMacro(m, NETLINK_TAPBASE); #endif #endif /* AF_NETLINK */ + +#ifdef AF_VSOCK + PyModule_AddIntConstant(m, "AF_VSOCK", AF_VSOCK); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); + PyModule_AddIntConstant(m, "VMADDR_CID_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_PORT_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_CID_HOST", 2); + PyModule_AddIntConstant(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); + PyModule_AddIntConstant(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); +#endif + #ifdef AF_ROUTE /* Alias to emulate 4.4BSD */ PyModule_AddIntMacro(m, AF_ROUTE); diff -r 3d726dbfca31 Modules/socketmodule.h --- a/Modules/socketmodule.h Wed Jun 15 17:16:16 2016 -0500 +++ b/Modules/socketmodule.h Thu Jul 21 10:53:53 2016 -0400 @@ -54,6 +54,12 @@ # undef AF_NETLINK #endif +#ifdef HAVE_LINUX_VM_SOCKETS_H +# include +#else +# undef AF_VSOCK +#endif + #ifdef HAVE_BLUETOOTH_BLUETOOTH_H #include #include diff -r 3d726dbfca31 configure.ac --- a/configure.ac Wed Jun 15 17:16:16 2016 -0500 +++ b/configure.ac Thu Jul 21 10:53:53 2016 -0400 @@ -1919,6 +1919,13 @@ #endif ]) +AC_CHECK_HEADERS(linux/vm_sockets.h,,,[ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +]) + + # On Linux, can.h and can/raw.h require sys/socket.h AC_CHECK_HEADERS(linux/can.h linux/can/raw.h linux/can/bcm.h,,,[ #ifdef HAVE_SYS_SOCKET_H