summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorcaavery <cavery@redhat.com>2017-09-06 22:18:10 (GMT)
committerChristian Heimes <christian@python.org>2017-09-06 22:18:10 (GMT)
commiteffc12f8e9e20d0951d2ba5883587666bd8218e3 (patch)
tree7c017ddd36f528c98a36c2b08293eb843194deb9 /Modules
parent5d578442ed5ba5025e465b384341cb8646ffd819 (diff)
downloadcpython-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.c93
-rw-r--r--Modules/socketmodule.h9
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,