Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qnativesocketengine_unix.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5//#define QNATIVESOCKETENGINE_DEBUG
7#include "private/qnet_unix_p.h"
8#include "qiodevice.h"
9#include "qhostaddress.h"
10#include "qelapsedtimer.h"
11#include "qvarlengtharray.h"
12#include "qnetworkinterface.h"
13#include "qendian.h"
14#ifdef Q_OS_WASM
15#include <private/qeventdispatcher_wasm_p.h>
16#endif
17#include <time.h>
18#include <errno.h>
19#include <fcntl.h>
20#ifndef QT_NO_IPV6IFNAME
21#ifdef Q_OS_LINUX
22#include <linux/if.h>
23#else // Q_OS_LINUX
24#include <net/if.h>
25#endif // !Q_OS_LINUX
26#endif
27#ifdef QT_LINUXBASE
28#include <arpa/inet.h>
29#endif
30#ifdef Q_OS_BSD4
31#include <net/if_dl.h>
32#endif
33#ifdef Q_OS_INTEGRITY
34#include <sys/uio.h>
35#endif
36
37#if defined QNATIVESOCKETENGINE_DEBUG
38#include <private/qdebug_p.h>
39#endif
40
41#include <netinet/tcp.h>
42#ifndef QT_NO_SCTP
43#include <sys/types.h>
44#include <sys/socket.h>
45#include <netinet/sctp.h>
46#endif
47
49
50/*
51 Extracts the port and address from a sockaddr, and stores them in
52 \a port and \a addr if they are non-null.
53*/
55{
56 if (s->a.sa_family == AF_INET6) {
57 Q_IPV6ADDR tmp;
58 memcpy(&tmp, &s->a6.sin6_addr, sizeof(tmp));
59 if (addr) {
60 QHostAddress tmpAddress;
61 tmpAddress.setAddress(tmp);
62 *addr = tmpAddress;
63#if QT_CONFIG(networkinterface)
64 if (s->a6.sin6_scope_id)
66#endif
67 }
68 if (port)
69 *port = ntohs(s->a6.sin6_port);
70 return;
71 }
72
73 if (port)
74 *port = ntohs(s->a4.sin_port);
75 if (addr) {
76 QHostAddress tmpAddress;
77 tmpAddress.setAddress(ntohl(s->a4.sin_addr.s_addr));
78 *addr = tmpAddress;
79 }
80}
81
83 QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
84{
85 n = -1;
86 level = SOL_SOCKET; // default
87
88 switch (opt) {
89 case QNativeSocketEngine::NonBlockingSocketOption: // fcntl, not setsockopt
90 case QNativeSocketEngine::BindExclusively: // not handled on Unix
92 Q_UNREACHABLE();
93
95 n = SO_BROADCAST;
96 break;
98 n = SO_RCVBUF;
99 break;
101 n = SO_SNDBUF;
102 break;
104 n = SO_REUSEADDR;
105 break;
107 n = SO_OOBINLINE;
108 break;
110 level = IPPROTO_TCP;
111 n = TCP_NODELAY;
112 break;
114 n = SO_KEEPALIVE;
115 break;
117 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
118 level = IPPROTO_IPV6;
119 n = IPV6_MULTICAST_HOPS;
120 } else
121 {
122 level = IPPROTO_IP;
123 n = IP_MULTICAST_TTL;
124 }
125 break;
127 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
128 level = IPPROTO_IPV6;
129 n = IPV6_MULTICAST_LOOP;
130 } else
131 {
132 level = IPPROTO_IP;
133 n = IP_MULTICAST_LOOP;
134 }
135 break;
137 if (socketProtocol == QAbstractSocket::IPv4Protocol) {
138 level = IPPROTO_IP;
139 n = IP_TOS;
140 }
141 break;
143 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
144 level = IPPROTO_IPV6;
145 n = IPV6_RECVPKTINFO;
146 } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
147 level = IPPROTO_IP;
148#ifdef IP_PKTINFO
149 n = IP_PKTINFO;
150#elif defined(IP_RECVDSTADDR)
151 // variant found in QNX and FreeBSD; it will get us only the
152 // destination address, not the interface; we need IP_RECVIF for that.
153 n = IP_RECVDSTADDR;
154#endif
155 }
156 break;
158 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
159 level = IPPROTO_IPV6;
160 n = IPV6_RECVHOPLIMIT;
161 } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
162#ifdef IP_RECVTTL // IP_RECVTTL is a non-standard extension supported on some OS
163 level = IPPROTO_IP;
164 n = IP_RECVTTL;
165#endif
166 }
167 break;
168
170 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
171#ifdef IPV6_MTU
172 level = IPPROTO_IPV6;
173 n = IPV6_MTU;
174#endif
175 } else {
176#ifdef IP_MTU
177 level = IPPROTO_IP;
178 n = IP_MTU;
179#endif
180 }
181 break;
182 }
183}
184
192{
193#ifndef QT_NO_SCTP
194 int protocol = (socketType == QAbstractSocket::SctpSocket) ? IPPROTO_SCTP : 0;
195#else
199#if defined (QNATIVESOCKETENGINE_DEBUG)
200 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d): unsupported protocol",
202#endif
203 return false;
204 }
205 int protocol = 0;
206#endif // QT_NO_SCTP
209 int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
210
211 int socket = qt_safe_socket(domain, type, protocol, O_NONBLOCK);
212 if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) {
213 domain = AF_INET;
214 socket = qt_safe_socket(domain, type, protocol, O_NONBLOCK);
216 }
217
218 if (socket < 0) {
219 int ecopy = errno;
220 switch (ecopy) {
221 case EPROTONOSUPPORT:
222 case EAFNOSUPPORT:
223 case EINVAL:
225 break;
226 case ENFILE:
227 case EMFILE:
228 case ENOBUFS:
229 case ENOMEM:
231 break;
232 case EACCES:
234 break;
235 default:
236 break;
237 }
238
239#if defined (QNATIVESOCKETENGINE_DEBUG)
240 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == false (%s)",
242 strerror(ecopy));
243#endif
244
245 return false;
246 }
247
248#if defined (QNATIVESOCKETENGINE_DEBUG)
249 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == true",
251#endif
252
254 this->socketProtocol = socketProtocol;
255 this->socketType = socketType;
256 return true;
257}
258
259/*
260 Returns the value of the socket option \a opt.
261*/
263{
264 Q_Q(const QNativeSocketEngine);
265 if (!q->isValid())
266 return -1;
267
268 // handle non-getsockopt and specific cases first
269 switch (opt) {
273 return -1;
275#ifndef QT_NO_SCTP
276 sctp_initmsg sctpInitMsg;
277 QT_SOCKOPTLEN_T sctpInitMsgSize = sizeof(sctpInitMsg);
278 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
279 &sctpInitMsgSize) == 0)
280 return int(qMin(sctpInitMsg.sinit_num_ostreams, sctpInitMsg.sinit_max_instreams));
281#endif
282 return -1;
283 }
284
286#if defined(IPV6_PATHMTU) && !defined(IPV6_MTU)
287 // Prefer IPV6_MTU (handled by convertToLevelAndOption), if available
288 // (Linux); fall back to IPV6_PATHMTU otherwise (FreeBSD):
290 ip6_mtuinfo mtuinfo;
291 QT_SOCKOPTLEN_T len = sizeof(mtuinfo);
292 if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) == 0)
293 return int(mtuinfo.ip6m_mtu);
294 return -1;
295 }
296#endif
297 break;
298
299 default:
300 break;
301 }
302
303 int n, level;
304 int v = 0;
305 QT_SOCKOPTLEN_T len = sizeof(v);
306
308 if (n != -1 && ::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
309 return len == 1 ? qFromUnaligned<quint8>(&v) : v;
310
311 return -1;
312}
313
314
315/*
316 Sets the socket option \a opt to \a v.
317*/
319{
321 if (!q->isValid())
322 return false;
323
324 // handle non-setsockopt and specific cases first
325 switch (opt) {
327 // Make the socket nonblocking.
328#if !defined(Q_OS_VXWORKS)
329 int flags = ::fcntl(socketDescriptor, F_GETFL, 0);
330 if (flags == -1) {
331#ifdef QNATIVESOCKETENGINE_DEBUG
332 perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_GETFL) failed");
333#endif
334 return false;
335 }
336 if (::fcntl(socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {
337#ifdef QNATIVESOCKETENGINE_DEBUG
338 perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_SETFL) failed");
339#endif
340 return false;
341 }
342#else // Q_OS_VXWORKS
343 int onoff = 1;
344
345 if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) {
346
347#ifdef QNATIVESOCKETENGINE_DEBUG
348 perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed");
349#endif
350 return false;
351 }
352#endif // Q_OS_VXWORKS
353 return true;
354 }
356 return true;
357
359#ifndef QT_NO_SCTP
360 sctp_initmsg sctpInitMsg;
361 QT_SOCKOPTLEN_T sctpInitMsgSize = sizeof(sctpInitMsg);
362 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
363 &sctpInitMsgSize) == 0) {
364 sctpInitMsg.sinit_num_ostreams = sctpInitMsg.sinit_max_instreams = uint16_t(v);
365 return ::setsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
366 sctpInitMsgSize) == 0;
367 }
368#endif
369 return false;
370 }
371
372 default:
373 break;
374 }
375
376 int n, level;
378#if defined(SO_REUSEPORT) && !defined(Q_OS_LINUX)
380 // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the
381 // same port (which is useful for multicast UDP). SO_REUSEPORT is, but
382 // we most definitely do not want to use this for TCP. See QTBUG-6305.
384 n = SO_REUSEPORT;
385 }
386#endif
387
388 if (n == -1)
389 return false;
390 return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
391}
392
394{
395#ifdef QNATIVESOCKETENGINE_DEBUG
396 qDebug() << "QNativeSocketEnginePrivate::nativeConnect() " << socketDescriptor;
397#endif
398
399 qt_sockaddr aa;
400 QT_SOCKLEN_T sockAddrSize;
401 setPortAndAddress(port, addr, &aa, &sockAddrSize);
402
403 int connectResult = qt_safe_connect(socketDescriptor, &aa.a, sockAddrSize);
404#if defined (QNATIVESOCKETENGINE_DEBUG)
405 int ecopy = errno;
406#endif
407 if (connectResult == -1) {
408 switch (errno) {
409 case EISCONN:
411 break;
412 case ECONNREFUSED:
413 case EINVAL:
416 break;
417 case ETIMEDOUT:
419 break;
420 case EHOSTUNREACH:
423 break;
424 case ENETUNREACH:
427 break;
428 case EADDRINUSE:
430 break;
431 case EINPROGRESS:
432 case EALREADY:
435 break;
436 case EAGAIN:
438 break;
439 case EACCES:
440 case EPERM:
443 break;
444 case EAFNOSUPPORT:
445 case EBADF:
446 case EFAULT:
447 case ENOTSOCK:
449 default:
450 break;
451 }
452
454#if defined (QNATIVESOCKETENGINE_DEBUG)
455 qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
456 addr.toString().toLatin1().constData(), port,
458 ? "Connection in progress" : strerror(ecopy));
459#endif
460 return false;
461 }
462 }
463
464#if defined (QNATIVESOCKETENGINE_DEBUG)
465 qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
466 addr.toString().toLatin1().constData(), port);
467#endif
468
470 return true;
471}
472
474{
475 qt_sockaddr aa;
476 QT_SOCKLEN_T sockAddrSize;
477 setPortAndAddress(port, address, &aa, &sockAddrSize);
478
479#ifdef IPV6_V6ONLY
480 if (aa.a.sa_family == AF_INET6) {
481 int ipv6only = 0;
482 if (address.protocol() == QAbstractSocket::IPv6Protocol)
483 ipv6only = 1;
484 //default value of this socket option varies depending on unix variant (or system configuration on BSD), so always set it explicitly
485 ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
486 }
487#endif
488
489 int bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize);
490 if (bindResult < 0 && errno == EAFNOSUPPORT && address.protocol() == QAbstractSocket::AnyIPProtocol) {
491 // retry with v4
492 aa.a4.sin_family = AF_INET;
493 aa.a4.sin_port = htons(port);
494 aa.a4.sin_addr.s_addr = htonl(address.toIPv4Address());
495 sockAddrSize = sizeof(aa.a4);
496 bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize);
497 }
498
499 if (bindResult < 0) {
500#if defined (QNATIVESOCKETENGINE_DEBUG)
501 int ecopy = errno;
502#endif
503 switch(errno) {
504 case EADDRINUSE:
506 break;
507 case EACCES:
509 break;
510 case EINVAL:
512 break;
513 case EADDRNOTAVAIL:
515 break;
516 default:
517 break;
518 }
519
520#if defined (QNATIVESOCKETENGINE_DEBUG)
521 qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
522 address.toString().toLatin1().constData(), port, strerror(ecopy));
523#endif
524
525 return false;
526 }
527
528#if defined (QNATIVESOCKETENGINE_DEBUG)
529 qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
530 address.toString().toLatin1().constData(), port);
531#endif
533 return true;
534}
535
537{
538 if (qt_safe_listen(socketDescriptor, backlog) < 0) {
539#if defined (QNATIVESOCKETENGINE_DEBUG)
540 int ecopy = errno;
541#endif
542 switch (errno) {
543 case EADDRINUSE:
546 break;
547 default:
548 break;
549 }
550
551#if defined (QNATIVESOCKETENGINE_DEBUG)
552 qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",
553 backlog, strerror(ecopy));
554#endif
555 return false;
556 }
557
558#if defined (QNATIVESOCKETENGINE_DEBUG)
559 qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == true", backlog);
560#endif
561
563 return true;
564}
565
567{
568 int acceptedDescriptor = qt_safe_accept(socketDescriptor, nullptr, nullptr);
569 if (acceptedDescriptor == -1) {
570 switch (errno) {
571 case EBADF:
572 case EOPNOTSUPP:
574 break;
575 case ECONNABORTED:
577 break;
578 case EFAULT:
579 case ENOTSOCK:
581 break;
582 case EPROTONOSUPPORT:
583#if !defined(Q_OS_OPENBSD)
584 case EPROTO:
585#endif
586 case EAFNOSUPPORT:
587 case EINVAL:
589 break;
590 case ENFILE:
591 case EMFILE:
592 case ENOBUFS:
593 case ENOMEM:
595 break;
596 case EACCES:
597 case EPERM:
599 break;
600#if EAGAIN != EWOULDBLOCK
601 case EWOULDBLOCK:
602#endif
603 case EAGAIN:
605 break;
606 default:
608 break;
609 }
610 }
611
612 return qintptr(acceptedDescriptor);
613}
614
615#ifndef QT_NO_NETWORKINTERFACE
616
618 int how6,
619 int how4,
620 const QHostAddress &groupAddress,
622{
623 int level = 0;
624 int sockOpt = 0;
625 void *sockArg;
626 int sockArgSize;
627
628 ip_mreq mreq4;
629 ipv6_mreq mreq6;
630
631 if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) {
632 level = IPPROTO_IPV6;
633 sockOpt = how6;
634 sockArg = &mreq6;
635 sockArgSize = sizeof(mreq6);
636 memset(&mreq6, 0, sizeof(mreq6));
637 Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
638 memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
639 mreq6.ipv6mr_interface = interface.index();
640 } else if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
641 level = IPPROTO_IP;
642 sockOpt = how4;
643 sockArg = &mreq4;
644 sockArgSize = sizeof(mreq4);
645 memset(&mreq4, 0, sizeof(mreq4));
646 mreq4.imr_multiaddr.s_addr = htonl(groupAddress.toIPv4Address());
647
648 if (interface.isValid()) {
649 const QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
650 bool found = false;
651 for (const QNetworkAddressEntry &entry : addressEntries) {
652 const QHostAddress ip = entry.ip();
654 mreq4.imr_interface.s_addr = htonl(ip.toIPv4Address());
655 found = true;
656 break;
657 }
658 }
659 if (!found) {
662 return false;
663 }
664 } else {
665 mreq4.imr_interface.s_addr = INADDR_ANY;
666 }
667 } else {
668 // unreachable
671 return false;
672 }
673
674 int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize);
675 if (res == -1) {
676 switch (errno) {
677 case ENOPROTOOPT:
680 break;
681 case EADDRNOTAVAIL:
684 break;
685 default:
688 break;
689 }
690 return false;
691 }
692 return true;
693}
694
697{
698 return multicastMembershipHelper(this,
699 IPV6_JOIN_GROUP,
700 IP_ADD_MEMBERSHIP,
701 groupAddress,
702 interface);
703}
704
707{
708 return multicastMembershipHelper(this,
709 IPV6_LEAVE_GROUP,
710 IP_DROP_MEMBERSHIP,
711 groupAddress,
712 interface);
713}
714
716{
718 uint v;
719 QT_SOCKOPTLEN_T sizeofv = sizeof(v);
720 if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1)
721 return QNetworkInterface();
723 }
724
725#if defined(Q_OS_SOLARIS)
726 struct in_addr v = { 0, 0, 0, 0};
727#else
728 struct in_addr v = { 0 };
729#endif
730 QT_SOCKOPTLEN_T sizeofv = sizeof(v);
731 if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
732 return QNetworkInterface();
733 if (v.s_addr != 0 && sizeofv >= QT_SOCKOPTLEN_T(sizeof(v))) {
734 QHostAddress ipv4(ntohl(v.s_addr));
736 for (int i = 0; i < ifaces.size(); ++i) {
737 const QNetworkInterface &iface = ifaces.at(i);
738 QList<QNetworkAddressEntry> entries = iface.addressEntries();
739 for (int j = 0; j < entries.size(); ++j) {
740 const QNetworkAddressEntry &entry = entries.at(j);
741 if (entry.ip() == ipv4)
742 return iface;
743 }
744 }
745 }
746 return QNetworkInterface();
747}
748
750{
752 uint v = iface.index();
753 return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1);
754 }
755
756 struct in_addr v;
757 if (iface.isValid()) {
758 QList<QNetworkAddressEntry> entries = iface.addressEntries();
759 for (int i = 0; i < entries.size(); ++i) {
760 const QNetworkAddressEntry &entry = entries.at(i);
761 const QHostAddress &ip = entry.ip();
763 v.s_addr = htonl(ip.toIPv4Address());
764 int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v));
765 if (r != -1)
766 return true;
767 }
768 }
769 return false;
770 }
771
772 v.s_addr = INADDR_ANY;
773 return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v)) != -1);
774}
775
776#endif // QT_NO_NETWORKINTERFACE
777
779{
780 int nbytes = 0;
781 // gives shorter than true amounts on Unix domain sockets.
782 qint64 available = -1;
783
784#if defined (SO_NREAD)
786 socklen_t sz = sizeof nbytes;
787 if (!::getsockopt(socketDescriptor, SOL_SOCKET, SO_NREAD, &nbytes, &sz))
788 available = nbytes;
789 }
790#endif
791
792 if (available == -1 && qt_safe_ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
793 available = nbytes;
794
795#if defined (QNATIVESOCKETENGINE_DEBUG)
796 qDebug("QNativeSocketEnginePrivate::nativeBytesAvailable() == %lli", available);
797#endif
798 return available > 0 ? available : 0;
799}
800
802{
803 // Peek 1 bytes into the next message.
804 ssize_t readBytes;
805 char c;
806 EINTR_LOOP(readBytes, ::recv(socketDescriptor, &c, 1, MSG_PEEK));
807
808 // If there's no error, or if our buffer was too small, there must be a
809 // pending datagram.
810 bool result = (readBytes != -1) || errno == EMSGSIZE;
811
812#if defined (QNATIVESOCKETENGINE_DEBUG)
813 qDebug("QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == %s",
814 result ? "true" : "false");
815#endif
816 return result;
817}
818
820{
821 ssize_t recvResult = -1;
822#ifdef Q_OS_LINUX
823 // Linux can return the actual datagram size if we use MSG_TRUNC
824 char c;
825 EINTR_LOOP(recvResult, ::recv(socketDescriptor, &c, 1, MSG_PEEK | MSG_TRUNC));
826#elif defined(SO_NREAD)
827 // macOS can return the actual datagram size if we use SO_NREAD
828 int value;
829 socklen_t valuelen = sizeof(value);
830 recvResult = getsockopt(socketDescriptor, SOL_SOCKET, SO_NREAD, &value, &valuelen);
831 if (recvResult != -1)
832 recvResult = value;
833#else
834 // We need to grow the buffer to fit the entire datagram.
835 // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
836 // almost all uses (effective MTU for UDP under IPv4 is 1468), except
837 // for localhost datagrams and those reassembled by the IP layer.
838 char udpMessagePeekBuffer[1500];
839 struct msghdr msg;
840 struct iovec vec;
841
842 memset(&msg, 0, sizeof(msg));
843 msg.msg_iov = &vec;
844 msg.msg_iovlen = 1;
845 vec.iov_base = udpMessagePeekBuffer;
846 vec.iov_len = sizeof(udpMessagePeekBuffer);
847
848 for (;;) {
849 // the data written to udpMessagePeekBuffer is discarded, so
850 // this function is still reentrant although it might not look
851 // so.
852 recvResult = ::recvmsg(socketDescriptor, &msg, MSG_PEEK);
853 if (recvResult == -1 && errno == EINTR)
854 continue;
855
856 // was the result truncated?
857 if ((msg.msg_flags & MSG_TRUNC) == 0)
858 break;
859
860 // grow by 16 times
861 msg.msg_iovlen *= 16;
862 if (msg.msg_iov != &vec)
863 delete[] msg.msg_iov;
864 msg.msg_iov = new struct iovec[msg.msg_iovlen];
865 std::fill_n(msg.msg_iov, msg.msg_iovlen, vec);
866 }
867
868 if (msg.msg_iov != &vec)
869 delete[] msg.msg_iov;
870#endif
871
872#if defined (QNATIVESOCKETENGINE_DEBUG)
873 qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %zd", recvResult);
874#endif
875
876 return qint64(recvResult);
877}
878
880 QAbstractSocketEngine::PacketHeaderOptions options)
881{
882 // we use quintptr to force the alignment
883 quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
884#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(Q_OS_BSD4)
885 + CMSG_SPACE(sizeof(sockaddr_dl))
886#endif
887#ifndef QT_NO_SCTP
888 + CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))
889#endif
890 + sizeof(quintptr) - 1) / sizeof(quintptr)];
891
892 struct msghdr msg;
893 struct iovec vec;
894 qt_sockaddr aa;
895 char c;
896 memset(&msg, 0, sizeof(msg));
897 memset(&aa, 0, sizeof(aa));
898
899 // we need to receive at least one byte, even if our user isn't interested in it
900 vec.iov_base = maxSize ? data : &c;
901 vec.iov_len = maxSize ? maxSize : 1;
902 msg.msg_iov = &vec;
903 msg.msg_iovlen = 1;
905 msg.msg_name = &aa;
906 msg.msg_namelen = sizeof(aa);
907 }
910 msg.msg_control = cbuf;
911 msg.msg_controllen = sizeof(cbuf);
912 }
913
914 ssize_t recvResult = 0;
915 do {
916 recvResult = ::recvmsg(socketDescriptor, &msg, 0);
917 } while (recvResult == -1 && errno == EINTR);
918
919 if (recvResult == -1) {
920 switch (errno) {
921#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
922 case EWOULDBLOCK:
923#endif
924 case EAGAIN:
925 // No datagram was available for reading
926 recvResult = -2;
927 break;
928 case ECONNREFUSED:
930 break;
931 default:
933 }
934 if (header)
935 header->clear();
936 } else if (options != QAbstractSocketEngine::WantNone) {
938 qt_socket_getPortAndAddress(&aa, &header->senderPort, &header->senderAddress);
939 header->destinationPort = localPort;
940 header->endOfRecord = (msg.msg_flags & MSG_EOR) != 0;
941
942 // parse the ancillary data
943 struct cmsghdr *cmsgptr;
945 QT_WARNING_DISABLE_CLANG("-Wsign-compare")
946 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != nullptr;
947 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
949 if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO
950 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in6_pktinfo))) {
951 in6_pktinfo *info = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
952
953 header->destinationAddress.setAddress(reinterpret_cast<quint8 *>(&info->ipi6_addr));
954 header->ifindex = info->ipi6_ifindex;
955 if (header->ifindex)
956 header->destinationAddress.setScopeId(QString::number(info->ipi6_ifindex));
957 }
958
959#ifdef IP_PKTINFO
960 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO
961 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in_pktinfo))) {
962 in_pktinfo *info = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsgptr));
963
964 header->destinationAddress.setAddress(ntohl(info->ipi_addr.s_addr));
965 header->ifindex = info->ipi_ifindex;
966 }
967#else
968# ifdef IP_RECVDSTADDR
969 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVDSTADDR
970 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in_addr))) {
971 in_addr *addr = reinterpret_cast<in_addr *>(CMSG_DATA(cmsgptr));
972
973 header->destinationAddress.setAddress(ntohl(addr->s_addr));
974 }
975# endif
976# if defined(IP_RECVIF) && defined(Q_OS_BSD4)
977 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF
978 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) {
979 sockaddr_dl *sdl = reinterpret_cast<sockaddr_dl *>(CMSG_DATA(cmsgptr));
980 header->ifindex = sdl->sdl_index;
981 }
982# endif
983#endif
984
985 if (cmsgptr->cmsg_len == CMSG_LEN(sizeof(int))
986 && ((cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_HOPLIMIT)
987 || (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_TTL))) {
988 static_assert(sizeof(header->hopLimit) == sizeof(int));
989 memcpy(&header->hopLimit, CMSG_DATA(cmsgptr), sizeof(header->hopLimit));
990 }
991
992#ifndef QT_NO_SCTP
993 if (cmsgptr->cmsg_level == IPPROTO_SCTP && cmsgptr->cmsg_type == SCTP_SNDRCV
994 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sctp_sndrcvinfo))) {
995 sctp_sndrcvinfo *rcvInfo = reinterpret_cast<sctp_sndrcvinfo *>(CMSG_DATA(cmsgptr));
996
997 header->streamNumber = int(rcvInfo->sinfo_stream);
998 }
999#endif
1000 }
1001 }
1002
1003#if defined (QNATIVESOCKETENGINE_DEBUG)
1004 qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",
1005 data, QtDebugUtils::toPrintable(data, recvResult, 16).constData(), maxSize,
1006 (recvResult != -1 && options != QAbstractSocketEngine::WantNone)
1007 ? header->senderAddress.toString().toLatin1().constData() : "(unknown)",
1008 (recvResult != -1 && options != QAbstractSocketEngine::WantNone)
1009 ? header->senderPort : 0, (qint64) recvResult);
1010#endif
1011
1012 return qint64((maxSize || recvResult < 0) ? recvResult : Q_INT64_C(0));
1013}
1014
1016{
1017 // we use quintptr to force the alignment
1018 quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
1019#ifndef QT_NO_SCTP
1020 + CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))
1021#endif
1022 + sizeof(quintptr) - 1) / sizeof(quintptr)];
1023
1024 struct cmsghdr *cmsgptr = reinterpret_cast<struct cmsghdr *>(cbuf);
1025 struct msghdr msg;
1026 struct iovec vec;
1027 qt_sockaddr aa;
1028
1029 memset(&msg, 0, sizeof(msg));
1030 memset(&aa, 0, sizeof(aa));
1031 vec.iov_base = const_cast<char *>(data);
1032 vec.iov_len = len;
1033 msg.msg_iov = &vec;
1034 msg.msg_iovlen = 1;
1035 msg.msg_control = &cbuf;
1036
1037 if (header.destinationPort != 0) {
1038 msg.msg_name = &aa.a;
1039 setPortAndAddress(header.destinationPort, header.destinationAddress,
1040 &aa, &msg.msg_namelen);
1041 }
1042
1043 if (msg.msg_namelen == sizeof(aa.a6)) {
1044 if (header.hopLimit != -1) {
1045 msg.msg_controllen += CMSG_SPACE(sizeof(int));
1046 cmsgptr->cmsg_len = CMSG_LEN(sizeof(int));
1047 cmsgptr->cmsg_level = IPPROTO_IPV6;
1048 cmsgptr->cmsg_type = IPV6_HOPLIMIT;
1049 memcpy(CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
1050 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(int)));
1051 }
1052 if (header.ifindex != 0 || !header.senderAddress.isNull()) {
1053 struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
1054 memset(data, 0, sizeof(*data));
1055 msg.msg_controllen += CMSG_SPACE(sizeof(*data));
1056 cmsgptr->cmsg_len = CMSG_LEN(sizeof(*data));
1057 cmsgptr->cmsg_level = IPPROTO_IPV6;
1058 cmsgptr->cmsg_type = IPV6_PKTINFO;
1059 data->ipi6_ifindex = header.ifindex;
1060
1061 QIPv6Address tmp = header.senderAddress.toIPv6Address();
1062 memcpy(&data->ipi6_addr, &tmp, sizeof(tmp));
1063 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1064 }
1065 } else {
1066 if (header.hopLimit != -1) {
1067 msg.msg_controllen += CMSG_SPACE(sizeof(int));
1068 cmsgptr->cmsg_len = CMSG_LEN(sizeof(int));
1069 cmsgptr->cmsg_level = IPPROTO_IP;
1070 cmsgptr->cmsg_type = IP_TTL;
1071 memcpy(CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
1072 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(int)));
1073 }
1074
1075#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
1076 if (header.ifindex != 0 || !header.senderAddress.isNull()) {
1077# ifdef IP_PKTINFO
1078 struct in_pktinfo *data = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsgptr));
1079 memset(data, 0, sizeof(*data));
1080 cmsgptr->cmsg_type = IP_PKTINFO;
1081 data->ipi_ifindex = header.ifindex;
1082 data->ipi_addr.s_addr = htonl(header.senderAddress.toIPv4Address());
1083# elif defined(IP_SENDSRCADDR)
1084 struct in_addr *data = reinterpret_cast<in_addr *>(CMSG_DATA(cmsgptr));
1085 cmsgptr->cmsg_type = IP_SENDSRCADDR;
1086 data->s_addr = htonl(header.senderAddress.toIPv4Address());
1087# endif
1088 cmsgptr->cmsg_level = IPPROTO_IP;
1089 msg.msg_controllen += CMSG_SPACE(sizeof(*data));
1090 cmsgptr->cmsg_len = CMSG_LEN(sizeof(*data));
1091 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1092 }
1093#endif
1094 }
1095
1096#ifndef QT_NO_SCTP
1097 if (header.streamNumber != -1) {
1098 struct sctp_sndrcvinfo *data = reinterpret_cast<sctp_sndrcvinfo *>(CMSG_DATA(cmsgptr));
1099 memset(data, 0, sizeof(*data));
1100 msg.msg_controllen += CMSG_SPACE(sizeof(sctp_sndrcvinfo));
1101 cmsgptr->cmsg_len = CMSG_LEN(sizeof(sctp_sndrcvinfo));
1102 cmsgptr->cmsg_level = IPPROTO_SCTP;
1103 cmsgptr->cmsg_type = SCTP_SNDRCV;
1104 data->sinfo_stream = uint16_t(header.streamNumber);
1105 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1106 }
1107#endif
1108
1109 if (msg.msg_controllen == 0)
1110 msg.msg_control = nullptr;
1111 ssize_t sentBytes = qt_safe_sendmsg(socketDescriptor, &msg, 0);
1112
1113 if (sentBytes < 0) {
1114 switch (errno) {
1115#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1116 case EWOULDBLOCK:
1117#endif
1118 case EAGAIN:
1119 sentBytes = -2;
1120 break;
1121 case EMSGSIZE:
1123 break;
1124 case ECONNRESET:
1126 break;
1127 default:
1129 }
1130 }
1131
1132#if defined (QNATIVESOCKETENGINE_DEBUG)
1133 qDebug("QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
1134 QtDebugUtils::toPrintable(data, len, 16).constData(), len,
1135 header.destinationAddress.toString().toLatin1().constData(),
1136 header.destinationPort, (qint64) sentBytes);
1137#endif
1138
1139 return qint64(sentBytes);
1140}
1141
1143{
1144 localPort = 0;
1146 peerPort = 0;
1149
1150 if (socketDescriptor == -1)
1151 return false;
1152
1153 qt_sockaddr sa;
1154 QT_SOCKLEN_T sockAddrSize = sizeof(sa);
1155
1156 // Determine local address
1157 memset(&sa, 0, sizeof(sa));
1158 if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
1160
1161 // Determine protocol family
1162 switch (sa.a.sa_family) {
1163 case AF_INET:
1165 break;
1166 case AF_INET6:
1168 break;
1169 default:
1171 break;
1172 }
1173
1174 } else if (errno == EBADF) {
1176 return false;
1177 }
1178
1179#if defined (IPV6_V6ONLY)
1180 // determine if local address is dual mode
1181 // On linux, these are returned as "::" (==AnyIPv6)
1182 // On OSX, these are returned as "::FFFF:0.0.0.0" (==AnyIPv4)
1183 // in either case, the IPV6_V6ONLY option is cleared
1184 int ipv6only = 0;
1185 socklen_t optlen = sizeof(ipv6only);
1188 && !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
1189 if (optlen != sizeof(ipv6only))
1190 qWarning("unexpected size of IPV6_V6ONLY socket option");
1191 if (!ipv6only) {
1194 }
1195 }
1196#endif
1197
1198 // Determine the remote address
1199 bool connected = ::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0;
1200 if (connected) {
1203 }
1204
1205 // Determine the socket type (UDP/TCP/SCTP)
1206 int value = 0;
1207 QT_SOCKOPTLEN_T valueSize = sizeof(int);
1208 if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, &value, &valueSize) == 0) {
1209 if (value == SOCK_STREAM) {
1210#ifndef QT_NO_SCTP
1213 if (connected) {
1214 sctp_status sctpStatus;
1215 QT_SOCKOPTLEN_T sctpStatusSize = sizeof(sctpStatus);
1216 sctp_event_subscribe sctpEvents;
1217
1218 memset(&sctpEvents, 0, sizeof(sctpEvents));
1219 sctpEvents.sctp_data_io_event = 1;
1220 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_STATUS, &sctpStatus,
1221 &sctpStatusSize) == 0 &&
1222 ::setsockopt(socketDescriptor, SOL_SCTP, SCTP_EVENTS, &sctpEvents,
1223 sizeof(sctpEvents)) == 0) {
1224 inboundStreamCount = int(sctpStatus.sstat_instrms);
1225 outboundStreamCount = int(sctpStatus.sstat_outstrms);
1226 } else {
1229 return false;
1230 }
1231 }
1232 } else {
1234 }
1235#else
1237#endif
1238 } else {
1239 if (value == SOCK_DGRAM)
1241 else
1243 }
1244 }
1245#if defined (QNATIVESOCKETENGINE_DEBUG)
1246 QString socketProtocolStr = QStringLiteral("UnknownProtocol");
1247 if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol");
1249
1250 QString socketTypeStr = QStringLiteral("UnknownSocketType");
1251 if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket");
1252 else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = QStringLiteral("UdpSocket");
1253 else if (socketType == QAbstractSocket::SctpSocket) socketTypeStr = QStringLiteral("SctpSocket");
1254
1255 qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i,"
1256 " peer == %s:%i, socket == %s - %s, inboundStreamCount == %i, outboundStreamCount == %i",
1260#endif
1261 return true;
1262}
1263
1265{
1266#if defined (QNATIVESOCKETENGINE_DEBUG)
1267 qDebug("QNativeSocketEngine::nativeClose()");
1268#endif
1269
1271}
1272
1274{
1276
1277 ssize_t writtenBytes;
1279
1280 if (writtenBytes < 0) {
1281 switch (errno) {
1282 case EPIPE:
1283 case ECONNRESET:
1284 writtenBytes = -1;
1286 q->close();
1287 break;
1288 case EAGAIN:
1289 writtenBytes = 0;
1290 break;
1291 case EMSGSIZE:
1293 break;
1294 default:
1295 break;
1296 }
1297 }
1298
1299#if defined (QNATIVESOCKETENGINE_DEBUG)
1300 qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %llu) == %i", data,
1301 QtDebugUtils::toPrintable(data, len, 16).constData(), len, (int) writtenBytes);
1302#endif
1303
1304 return qint64(writtenBytes);
1305}
1306/*
1307*/
1309{
1311 if (!q->isValid()) {
1312 qWarning("QNativeSocketEngine::nativeRead: Invalid socket");
1313 return -1;
1314 }
1315
1316 ssize_t r = 0;
1317 r = qt_safe_read(socketDescriptor, data, maxSize);
1318
1319 if (r < 0) {
1320 r = -1;
1321 switch (errno) {
1322#if EWOULDBLOCK-0 && EWOULDBLOCK != EAGAIN
1323 case EWOULDBLOCK:
1324#endif
1325 case EAGAIN:
1326 // No data was available for reading
1327 r = -2;
1328 break;
1329 case ECONNRESET:
1330#if defined(Q_OS_VXWORKS)
1331 case ESHUTDOWN:
1332#endif
1333 r = 0;
1334 break;
1335 case ETIMEDOUT:
1337 break;
1338 default:
1340 break;
1341 }
1342
1343 if (r == -1) {
1344 hasSetSocketError = true;
1346 }
1347 }
1348
1349#if defined (QNATIVESOCKETENGINE_DEBUG)
1350 qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %zd", data,
1351 QtDebugUtils::toPrintable(data, r, 16).constData(), maxSize, r);
1352#endif
1353
1354 return qint64(r);
1355}
1356
1357int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
1358{
1359 bool dummy;
1360 return nativeSelect(timeout, selectForRead, !selectForRead, &dummy, &dummy);
1361}
1362
1363#ifndef Q_OS_WASM
1364
1365int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
1366 bool *selectForRead, bool *selectForWrite) const
1367{
1368 pollfd pfd = qt_make_pollfd(socketDescriptor, 0);
1369
1370 if (checkRead)
1371 pfd.events |= POLLIN;
1372
1373 if (checkWrite)
1374 pfd.events |= POLLOUT;
1375
1376 const int ret = qt_poll_msecs(&pfd, 1, timeout);
1377
1378 if (ret <= 0)
1379 return ret;
1380
1381 if (pfd.revents & POLLNVAL) {
1382 errno = EBADF;
1383 return -1;
1384 }
1385
1386 static const short read_flags = POLLIN | POLLHUP | POLLERR;
1387 static const short write_flags = POLLOUT | POLLERR;
1388
1389 *selectForRead = ((pfd.revents & read_flags) != 0);
1390 *selectForWrite = ((pfd.revents & write_flags) != 0);
1391
1392 return ret;
1393}
1394
1395#else
1396
1397int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
1398 bool *selectForRead, bool *selectForWrite) const
1399{
1400 *selectForRead = checkRead;
1401 *selectForWrite = checkWrite;
1402 bool socketDisconnect = false;
1403 QEventDispatcherWasm::socketSelect(timeout, socketDescriptor, checkRead, checkWrite,selectForRead, selectForWrite, &socketDisconnect);
1404
1405 // The disconnect/close handling code in QAbstractsScket::canReadNotification()
1406 // does not detect remote disconnect properly; do that here as a workardound.
1407 if (socketDisconnect)
1409
1410 return 1;
1411}
1412
1413#endif // Q_OS_WASM
1414
bool connected
QAbstractSocketEngineReceiver * receiver
QAbstractSocket::NetworkLayerProtocol socketProtocol
QAbstractSocket::SocketState socketState
QAbstractSocket::SocketError socketError
QAbstractSocket::SocketType socketType
virtual void closeNotification()=0
static constexpr auto IPv4Protocol
static constexpr auto UnknownNetworkLayerProtocol
static constexpr auto AnyIPProtocol
static constexpr auto IPv6Protocol
SocketType
This enum describes the transport layer protocol.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
static void socketSelect(int timeout, int socket, bool waitForRead, bool waitForWrite, bool *selectForRead, bool *selectForWrite, bool *socketDisconnect)
The QHostAddress class provides an IP address.
quint32 toIPv4Address(bool *ok=nullptr) const
Returns the IPv4 address as a number.
void clear()
Sets the host address to null and sets the protocol to QAbstractSocket::UnknownNetworkLayerProtocol.
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
Q_IPV6ADDR toIPv6Address() const
Returns the IPv6 address as a Q_IPV6ADDR structure.
void setScopeId(const QString &id)
QString toString() const
Returns the address as a string.
NetworkLayerProtocol protocol() const
Returns the network layer protocol of the host address.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol)
QNetworkInterface nativeMulticastInterface() const
int nativeSelect(int timeout, bool selectForRead) const
qint64 nativeWrite(const char *data, qint64 length)
int option(QNativeSocketEngine::SocketOption option) const
bool nativeJoinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
bool setOption(QNativeSocketEngine::SocketOption option, int value)
void setError(QAbstractSocket::SocketError error, ErrorString errorString) const
bool nativeSetMulticastInterface(const QNetworkInterface &iface)
bool fetchConnectionParameters()
Fetches information about both ends of the connection: whatever is available.
bool nativeBind(const QHostAddress &address, quint16 port)
qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header)
bool nativeConnect(const QHostAddress &address, quint16 port)
void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
qint64 nativeRead(char *data, qint64 maxLength)
qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header, QAbstractSocketEngine::PacketHeaderOptions options)
The QNativeSocketEngine class provides low level access to a socket.
The QNetworkAddressEntry class stores one IP address supported by a network interface,...
The QNetworkInterface class provides a listing of the host's IP addresses and network interfaces.
static QNetworkInterface interfaceFromIndex(int index)
Returns a QNetworkInterface object for the interface whose internal ID is index.
static QString interfaceNameFromIndex(int index)
static QList< QNetworkInterface > allInterfaces()
Returns a listing of all the network interfaces found on the host machine.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
QStyleOptionButton opt
Combined button and popup list for selecting options.
Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize)
Definition qdebug.cpp:29
#define QT_WARNING_POP
#define QT_WARNING_PUSH
#define QT_WARNING_DISABLE_CLANG(text)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static struct pollfd qt_make_pollfd(int fd, short events)
static int qt_poll_msecs(struct pollfd *fds, nfds_t nfds, int timeout)
#define EINTR_LOOP(var, cmd)
static int qt_safe_close(int fd)
static qint64 qt_safe_write_nosignal(int fd, const void *data, qint64 len)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
static QString header(const QString &name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputPortEXT port
static QT_BEGIN_NAMESPACE const char * socketType(QSocketNotifier::Type type)
QIPv6Address Q_IPV6ADDR
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
#define qDebug
[1]
Definition qlogging.h:160
#define qWarning
Definition qlogging.h:162
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt, QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
static QT_BEGIN_NAMESPACE void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *port, QHostAddress *addr)
static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, int how6, int how4, const QHostAddress &groupAddress, const QNetworkInterface &interface)
#define IPV6_V6ONLY
#define AF_INET6
static int qt_safe_ioctl(int sockfd, unsigned long request, T arg)
static int qt_safe_listen(int s, int backlog)
static int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags)
static int qt_safe_socket(int domain, int type, int protocol, int flags=0)
Definition qnet_unix_p.h:45
#define QT_SOCKOPTLEN_T
Definition qnet_unix_p.h:42
static int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags=0)
Definition qnet_unix_p.h:71
static int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLint level
GLboolean r
[2]
GLbitfield GLuint64 timeout
[4]
GLenum type
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat n
GLuint res
const GLubyte * c
GLuint entry
GLenum GLsizei len
GLenum const void * addr
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
unsigned short quint16
Definition qtypes.h:43
size_t quintptr
Definition qtypes.h:72
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
unsigned char quint8
Definition qtypes.h:41
#define Q_INT64_C(c)
Definition qtypes.h:52
ptrdiff_t qintptr
Definition qtypes.h:71
QFileInfo info(fileName)
[8]
QTcpSocket * socket
[1]