bpo-31425: Expose AF_QIPCRTR in socket module (GH-3706)
The AF_QIPCRTR address family was introduced in Linux v4.7. Co-authored-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
parent
2aaf98c16a
commit
bb8165172a
|
@ -193,6 +193,13 @@ created. Socket addresses are represented as follows:
|
||||||
- *addr* - Optional bytes-like object specifying the hardware physical
|
- *addr* - Optional bytes-like object specifying the hardware physical
|
||||||
address, whose interpretation depends on the device.
|
address, whose interpretation depends on the device.
|
||||||
|
|
||||||
|
- :const:`AF_QIPCRTR` is a Linux-only socket based interface for communicating
|
||||||
|
with services running on co-processors in Qualcomm platforms. The address
|
||||||
|
family is represented as a ``(node, port)`` tuple where the *node* and *port*
|
||||||
|
are non-negative integers.
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
If you use a hostname in the *host* portion of IPv4/v6 socket address, the
|
If you use a hostname in the *host* portion of IPv4/v6 socket address, the
|
||||||
program may show a nondeterministic behavior, as Python uses the first address
|
program may show a nondeterministic behavior, as Python uses the first address
|
||||||
returned from the DNS resolution. The socket address will be resolved
|
returned from the DNS resolution. The socket address will be resolved
|
||||||
|
@ -481,6 +488,13 @@ Constants
|
||||||
:const:`HCI_DATA_DIR` are not available for FreeBSD, NetBSD, or
|
:const:`HCI_DATA_DIR` are not available for FreeBSD, NetBSD, or
|
||||||
DragonFlyBSD.
|
DragonFlyBSD.
|
||||||
|
|
||||||
|
.. data:: AF_QIPCRTR
|
||||||
|
|
||||||
|
Constant for Qualcomm's IPC router protocol, used to communicate with
|
||||||
|
service providing remote processors.
|
||||||
|
|
||||||
|
Availability: Linux >= 4.7.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,16 @@ def _have_socket_alg():
|
||||||
s.close()
|
s.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _have_socket_qipcrtr():
|
||||||
|
"""Check whether AF_QIPCRTR sockets are supported on this host."""
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM, 0)
|
||||||
|
except (AttributeError, OSError):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
s.close()
|
||||||
|
return True
|
||||||
|
|
||||||
def _have_socket_vsock():
|
def _have_socket_vsock():
|
||||||
"""Check whether AF_VSOCK sockets are supported on this host."""
|
"""Check whether AF_VSOCK sockets are supported on this host."""
|
||||||
ret = get_cid() is not None
|
ret = get_cid() is not None
|
||||||
|
@ -113,6 +123,8 @@ HAVE_SOCKET_RDS = _have_socket_rds()
|
||||||
|
|
||||||
HAVE_SOCKET_ALG = _have_socket_alg()
|
HAVE_SOCKET_ALG = _have_socket_alg()
|
||||||
|
|
||||||
|
HAVE_SOCKET_QIPCRTR = _have_socket_qipcrtr()
|
||||||
|
|
||||||
HAVE_SOCKET_VSOCK = _have_socket_vsock()
|
HAVE_SOCKET_VSOCK = _have_socket_vsock()
|
||||||
|
|
||||||
# Size in bytes of the int type
|
# Size in bytes of the int type
|
||||||
|
@ -2054,6 +2066,34 @@ class RDSTest(ThreadedRDSSocketTest):
|
||||||
self.data = b'select'
|
self.data = b'select'
|
||||||
self.cli.sendto(self.data, 0, (HOST, self.port))
|
self.cli.sendto(self.data, 0, (HOST, self.port))
|
||||||
|
|
||||||
|
@unittest.skipUnless(HAVE_SOCKET_QIPCRTR,
|
||||||
|
'QIPCRTR sockets required for this test.')
|
||||||
|
class BasicQIPCRTRTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def testCrucialConstants(self):
|
||||||
|
socket.AF_QIPCRTR
|
||||||
|
|
||||||
|
def testCreateSocket(self):
|
||||||
|
with socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM) as s:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def testUnbound(self):
|
||||||
|
with socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM) as s:
|
||||||
|
self.assertEqual(s.getsockname()[1], 0)
|
||||||
|
|
||||||
|
def testBindSock(self):
|
||||||
|
with socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM) as s:
|
||||||
|
support.bind_port(s, host=s.getsockname()[0])
|
||||||
|
self.assertNotEqual(s.getsockname()[1], 0)
|
||||||
|
|
||||||
|
def testInvalidBindSock(self):
|
||||||
|
with socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM) as s:
|
||||||
|
self.assertRaises(OSError, support.bind_port, s, host=-2)
|
||||||
|
|
||||||
|
def testAutoBindSock(self):
|
||||||
|
with socket.socket(socket.AF_QIPCRTR, socket.SOCK_DGRAM) as s:
|
||||||
|
s.connect((123, 123))
|
||||||
|
self.assertNotEqual(s.getsockname()[1], 0)
|
||||||
|
|
||||||
@unittest.skipIf(fcntl is None, "need fcntl")
|
@unittest.skipIf(fcntl is None, "need fcntl")
|
||||||
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
|
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
|
||||||
|
@ -5978,6 +6018,7 @@ def test_main():
|
||||||
tests.extend([BasicCANTest, CANTest])
|
tests.extend([BasicCANTest, CANTest])
|
||||||
tests.extend([BasicRDSTest, RDSTest])
|
tests.extend([BasicRDSTest, RDSTest])
|
||||||
tests.append(LinuxKernelCryptoAPI)
|
tests.append(LinuxKernelCryptoAPI)
|
||||||
|
tests.append(BasicQIPCRTRTest)
|
||||||
tests.extend([
|
tests.extend([
|
||||||
BasicVSOCKTest,
|
BasicVSOCKTest,
|
||||||
ThreadedVSOCKSocketStreamTest,
|
ThreadedVSOCKSocketStreamTest,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Add support for sockets of the AF_QIPCRTR address family, supported by the
|
||||||
|
Linux kernel. This is used to communicate with services, such as GPS or
|
||||||
|
radio, running on Qualcomm devices.
|
|
@ -7,8 +7,8 @@ This module provides an interface to Berkeley socket IPC.
|
||||||
Limitations:
|
Limitations:
|
||||||
|
|
||||||
- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
|
- 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_QIPCRTR and AF_TIPC are
|
||||||
under Linux.
|
supported under Linux.
|
||||||
- No read/write operations (use sendall/recv or makefile instead).
|
- No read/write operations (use sendall/recv or makefile instead).
|
||||||
- Additional restrictions apply on some non-Unix platforms (compensated
|
- Additional restrictions apply on some non-Unix platforms (compensated
|
||||||
for by socket.py).
|
for by socket.py).
|
||||||
|
@ -55,6 +55,8 @@ Module interface:
|
||||||
the Ethernet protocol number to be received. For example:
|
the Ethernet protocol number to be received. For example:
|
||||||
("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple
|
("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple
|
||||||
specify packet-type and ha-type/addr.
|
specify packet-type and ha-type/addr.
|
||||||
|
- an AF_QIPCRTR socket address is a (node, port) tuple where the
|
||||||
|
node and port are non-negative integers.
|
||||||
- an AF_TIPC socket address is expressed as
|
- an AF_TIPC socket address is expressed as
|
||||||
(addr_type, v1, v2, v3 [, scope]); where addr_type can be one of:
|
(addr_type, v1, v2, v3 [, scope]); where addr_type can be one of:
|
||||||
TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID;
|
TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID;
|
||||||
|
@ -1293,6 +1295,14 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
||||||
}
|
}
|
||||||
#endif /* AF_NETLINK */
|
#endif /* AF_NETLINK */
|
||||||
|
|
||||||
|
#if defined(AF_QIPCRTR)
|
||||||
|
case AF_QIPCRTR:
|
||||||
|
{
|
||||||
|
struct sockaddr_qrtr *a = (struct sockaddr_qrtr *) addr;
|
||||||
|
return Py_BuildValue("II", a->sq_node, a->sq_port);
|
||||||
|
}
|
||||||
|
#endif /* AF_QIPCRTR */
|
||||||
|
|
||||||
#if defined(AF_VSOCK)
|
#if defined(AF_VSOCK)
|
||||||
case AF_VSOCK:
|
case AF_VSOCK:
|
||||||
{
|
{
|
||||||
|
@ -1668,6 +1678,30 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
||||||
}
|
}
|
||||||
#endif /* AF_NETLINK */
|
#endif /* AF_NETLINK */
|
||||||
|
|
||||||
|
#if defined(AF_QIPCRTR)
|
||||||
|
case AF_QIPCRTR:
|
||||||
|
{
|
||||||
|
struct sockaddr_qrtr* addr;
|
||||||
|
unsigned int node, port;
|
||||||
|
addr = (struct sockaddr_qrtr *)addr_ret;
|
||||||
|
if (!PyTuple_Check(args)) {
|
||||||
|
PyErr_Format(
|
||||||
|
PyExc_TypeError,
|
||||||
|
"getsockaddrarg: "
|
||||||
|
"AF_QIPCRTR address must be tuple, not %.500s",
|
||||||
|
Py_TYPE(args)->tp_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &node, &port))
|
||||||
|
return 0;
|
||||||
|
addr->sq_family = AF_QIPCRTR;
|
||||||
|
addr->sq_node = node;
|
||||||
|
addr->sq_port = port;
|
||||||
|
*len_ret = sizeof(*addr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* AF_QIPCRTR */
|
||||||
|
|
||||||
#if defined(AF_VSOCK)
|
#if defined(AF_VSOCK)
|
||||||
case AF_VSOCK:
|
case AF_VSOCK:
|
||||||
{
|
{
|
||||||
|
@ -2263,6 +2297,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
|
||||||
}
|
}
|
||||||
#endif /* AF_NETLINK */
|
#endif /* AF_NETLINK */
|
||||||
|
|
||||||
|
#if defined(AF_QIPCRTR)
|
||||||
|
case AF_QIPCRTR:
|
||||||
|
{
|
||||||
|
*len_ret = sizeof (struct sockaddr_qrtr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* AF_QIPCRTR */
|
||||||
|
|
||||||
#if defined(AF_VSOCK)
|
#if defined(AF_VSOCK)
|
||||||
case AF_VSOCK:
|
case AF_VSOCK:
|
||||||
{
|
{
|
||||||
|
@ -6983,6 +7025,11 @@ PyInit__socket(void)
|
||||||
#endif
|
#endif
|
||||||
#endif /* AF_NETLINK */
|
#endif /* AF_NETLINK */
|
||||||
|
|
||||||
|
#ifdef AF_QIPCRTR
|
||||||
|
/* Qualcomm IPCROUTER */
|
||||||
|
PyModule_AddIntMacro(m, AF_QIPCRTR);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AF_VSOCK
|
#ifdef AF_VSOCK
|
||||||
PyModule_AddIntConstant(m, "AF_VSOCK", 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_SIZE", 0);
|
||||||
|
|
|
@ -54,6 +54,15 @@ typedef int socklen_t;
|
||||||
# undef AF_NETLINK
|
# undef AF_NETLINK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_QRTR_H
|
||||||
|
# ifdef HAVE_ASM_TYPES_H
|
||||||
|
# include <asm/types.h>
|
||||||
|
# endif
|
||||||
|
# include <linux/qrtr.h>
|
||||||
|
#else
|
||||||
|
# undef AF_QIPCRTR
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
|
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/rfcomm.h>
|
#include <bluetooth/rfcomm.h>
|
||||||
|
@ -203,6 +212,9 @@ typedef union sock_addr {
|
||||||
#ifdef HAVE_SOCKADDR_ALG
|
#ifdef HAVE_SOCKADDR_ALG
|
||||||
struct sockaddr_alg alg;
|
struct sockaddr_alg alg;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef AF_QIPCRTR
|
||||||
|
struct sockaddr_qrtr sq;
|
||||||
|
#endif
|
||||||
#ifdef AF_VSOCK
|
#ifdef AF_VSOCK
|
||||||
struct sockaddr_vm vm;
|
struct sockaddr_vm vm;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8023,6 +8023,28 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# On Linux, qrtr.h requires asm/types.h
|
||||||
|
for ac_header in linux/qrtr.h
|
||||||
|
do :
|
||||||
|
ac_fn_c_check_header_compile "$LINENO" "linux/qrtr.h" "ac_cv_header_linux_qrtr_h" "
|
||||||
|
#ifdef HAVE_ASM_TYPES_H
|
||||||
|
#include <asm/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"
|
||||||
|
if test "x$ac_cv_header_linux_qrtr_h" = xyes; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_LINUX_QRTR_H 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
for ac_header in linux/vm_sockets.h
|
for ac_header in linux/vm_sockets.h
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" "
|
ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" "
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -2112,6 +2112,16 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# On Linux, qrtr.h requires asm/types.h
|
||||||
|
AC_CHECK_HEADERS(linux/qrtr.h,,,[
|
||||||
|
#ifdef HAVE_ASM_TYPES_H
|
||||||
|
#include <asm/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
|
||||||
AC_CHECK_HEADERS(linux/vm_sockets.h,,,[
|
AC_CHECK_HEADERS(linux/vm_sockets.h,,,[
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
|
@ -615,6 +615,9 @@
|
||||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||||
#undef HAVE_LINUX_NETLINK_H
|
#undef HAVE_LINUX_NETLINK_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <linux/qrtr.h> header file. */
|
||||||
|
#undef HAVE_LINUX_QRTR_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <linux/random.h> header file. */
|
/* Define to 1 if you have the <linux/random.h> header file. */
|
||||||
#undef HAVE_LINUX_RANDOM_H
|
#undef HAVE_LINUX_RANDOM_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue