diff options
author | caavery <cavery@redhat.com> | 2017-09-06 22:18:10 (GMT) |
---|---|---|
committer | Christian Heimes <christian@python.org> | 2017-09-06 22:18:10 (GMT) |
commit | effc12f8e9e20d0951d2ba5883587666bd8218e3 (patch) | |
tree | 7c017ddd36f528c98a36c2b08293eb843194deb9 /Modules | |
parent | 5d578442ed5ba5025e465b384341cb8646ffd819 (diff) | |
download | cpython-effc12f8e9e20d0951d2ba5883587666bd8218e3.zip cpython-effc12f8e9e20d0951d2ba5883587666bd8218e3.tar.gz cpython-effc12f8e9e20d0951d2ba5883587666bd8218e3.tar.bz2 |
bpo-27584: New addition of vSockets to the python socket module (#2489)
* bpo-27584: New addition of vSockets to the python socket module
Support for AF_VSOCK on Linux only
* bpo-27584: Fixes for V2
Fixed syntax and naming problems.
Fixed #ifdef AF_VSOCK checking
Restored original aclocal.m4
* bpo-27584: Fixes for V3
Added checking for fcntl and thread modules.
* bpo-27584: Fixes for V4
Fixed white space error
* bpo-27584: Fixes for V5
Added back comma in (CID, port).
* bpo-27584: Fixes for V6
Added news file.
socket.rst now reflects first Linux introduction of AF_VSOCK.
Fixed get_cid in test_socket.py.
Replaced PyLong_FromLong with PyLong_FromUnsignedLong in socketmodule.c
Got rid of extra AF_VSOCK #define.
Added sockaddr_vm to sock_addr.
* bpo-27584: Fixes for V7
Minor cleanup.
* bpo-27584: Fixes for V8
Put back #undef AF_VSOCK as it is necessary when vm_sockets.h is not installed.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/socketmodule.c | 93 | ||||
-rw-r--r-- | Modules/socketmodule.h | 9 |
2 files changed, 100 insertions, 2 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 37626e6..a431e25 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1225,6 +1225,14 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #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: { @@ -1586,6 +1594,32 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #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 */ @@ -2103,6 +2137,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) } #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 */ @@ -2598,6 +2640,21 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) unsigned int optlen; PyObject *none; +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag; // Must be set width of 64 bits + /* setsockopt(level, opt, flag) */ + 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 done; + } + return NULL; + } +#endif + /* setsockopt(level, opt, flag) */ if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { @@ -2668,20 +2725,39 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) 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; // Must be set width of 64 bits + flagsize = sizeof vflag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&vflag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromUnsignedLong(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"); @@ -6645,6 +6721,19 @@ PyInit__socket(void) PyModule_AddIntMacro(m, NETLINK_CRYPTO); #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 --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 03f982b..03dbf18 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -107,6 +107,12 @@ typedef int socklen_t; #define SOL_ALG 279 #endif +#ifdef HAVE_LINUX_VM_SOCKETS_H +# include <linux/vm_sockets.h> +#else +# undef AF_VSOCK +#endif + /* Linux 3.19 */ #ifndef ALG_SET_AEAD_ASSOCLEN #define ALG_SET_AEAD_ASSOCLEN 4 @@ -193,6 +199,9 @@ typedef union sock_addr { #ifdef HAVE_SOCKADDR_ALG struct sockaddr_alg alg; #endif +#ifdef AF_VSOCK + struct sockaddr_vm vm; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, |