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.
This commit is contained in:
caavery 2017-09-06 18:18:10 -04:00 committed by Christian Heimes
parent 5d578442ed
commit effc12f8e9
9 changed files with 257 additions and 2 deletions

View file

@ -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);