Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 "qdeadlinetimer.h"
9#include "qiodevice.h"
10#include "qhostaddress.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#ifdef Q_OS_INTEGRITY
21#include <sys/uio.h>
22#endif
23
24#if defined QNATIVESOCKETENGINE_DEBUG
25#include <private/qdebug_p.h>
26#endif
27
28#include <netinet/tcp.h>
29#ifndef QT_NO_SCTP
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <netinet/sctp.h>
33#endif
34#ifdef Q_OS_BSD4
35# include <net/if_dl.h>
36#endif
37
39
40/*
41 Extracts the port and address from a sockaddr, and stores them in
42 \a port and \a addr if they are non-null.
43*/
45{
46 if (s->a.sa_family == AF_INET6) {
47 Q_IPV6ADDR tmp;
48 memcpy(&tmp, &s->a6.sin6_addr, sizeof(tmp));
49 if (addr) {
50 QHostAddress tmpAddress;
51 tmpAddress.setAddress(tmp);
52 *addr = tmpAddress;
53#if QT_CONFIG(networkinterface)
54 if (s->a6.sin6_scope_id)
55 addr->setScopeId(QNetworkInterface::interfaceNameFromIndex(s->a6.sin6_scope_id));
56#endif
57 }
58 if (port)
59 *port = ntohs(s->a6.sin6_port);
60 return;
61 }
62
63 if (port)
64 *port = ntohs(s->a4.sin_port);
65 if (addr) {
66 QHostAddress tmpAddress;
67 tmpAddress.setAddress(ntohl(s->a4.sin_addr.s_addr));
68 *addr = tmpAddress;
69 }
70}
71
73 QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
74{
75 n = -1;
76 level = SOL_SOCKET; // default
77
78 switch (opt) {
79 case QNativeSocketEngine::NonBlockingSocketOption: // fcntl, not setsockopt
80 case QNativeSocketEngine::BindExclusively: // not handled on Unix
82 Q_UNREACHABLE();
83
85 n = SO_BROADCAST;
86 break;
88 n = SO_RCVBUF;
89 break;
91 n = SO_SNDBUF;
92 break;
94 n = SO_REUSEADDR;
95 break;
97 n = SO_OOBINLINE;
98 break;
100 level = IPPROTO_TCP;
101 n = TCP_NODELAY;
102 break;
104 n = SO_KEEPALIVE;
105 break;
107 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
108 level = IPPROTO_IPV6;
109 n = IPV6_MULTICAST_HOPS;
110 } else
111 {
112 level = IPPROTO_IP;
113 n = IP_MULTICAST_TTL;
114 }
115 break;
117 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
118 level = IPPROTO_IPV6;
119 n = IPV6_MULTICAST_LOOP;
120 } else
121 {
122 level = IPPROTO_IP;
123 n = IP_MULTICAST_LOOP;
124 }
125 break;
127 if (socketProtocol == QAbstractSocket::IPv4Protocol) {
128 level = IPPROTO_IP;
129 n = IP_TOS;
130 }
131 break;
133 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
134 level = IPPROTO_IPV6;
135 n = IPV6_RECVPKTINFO;
136 } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
137 level = IPPROTO_IP;
138#ifdef IP_PKTINFO
139 n = IP_PKTINFO;
140#elif defined(IP_RECVDSTADDR)
141 // variant found in QNX and FreeBSD; it will get us only the
142 // destination address, not the interface; we need IP_RECVIF for that.
143 n = IP_RECVDSTADDR;
144#endif
145 }
146 break;
148 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
149 level = IPPROTO_IPV6;
150 n = IPV6_RECVHOPLIMIT;
151 } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
152#ifdef IP_RECVTTL // IP_RECVTTL is a non-standard extension supported on some OS
153 level = IPPROTO_IP;
154 n = IP_RECVTTL;
155#endif
156 }
157 break;
158
160 if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
161#ifdef IPV6_MTU
162 level = IPPROTO_IPV6;
163 n = IPV6_MTU;
164#endif
165 } else {
166#ifdef IP_MTU
167 level = IPPROTO_IP;
168 n = IP_MTU;
169#endif
170 }
171 break;
172 }
173}
174
182{
183#ifndef QT_NO_SCTP
184 int protocol = (socketType == QAbstractSocket::SctpSocket) ? IPPROTO_SCTP : 0;
185#else
189#if defined (QNATIVESOCKETENGINE_DEBUG)
190 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d): unsupported protocol",
192#endif
193 return false;
194 }
195 int protocol = 0;
196#endif // QT_NO_SCTP
199 int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
200
201 int socket = qt_safe_socket(domain, type, protocol, O_NONBLOCK);
202 if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) {
203 domain = AF_INET;
204 socket = qt_safe_socket(domain, type, protocol, O_NONBLOCK);
206 }
207
208 if (socket < 0) {
209 int ecopy = errno;
210 switch (ecopy) {
211 case EPROTONOSUPPORT:
212 case EAFNOSUPPORT:
213 case EINVAL:
215 break;
216 case ENFILE:
217 case EMFILE:
218 case ENOBUFS:
219 case ENOMEM:
221 break;
222 case EACCES:
224 break;
225 default:
226 break;
227 }
228
229#if defined (QNATIVESOCKETENGINE_DEBUG)
230 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == false (%s)",
232 strerror(ecopy));
233#endif
234
235 return false;
236 }
237
238#if defined (QNATIVESOCKETENGINE_DEBUG)
239 qDebug("QNativeSocketEnginePrivate::createNewSocket(%d, %d) == true",
241#endif
242
244 this->socketProtocol = socketProtocol;
245 this->socketType = socketType;
246 return true;
247}
248
249/*
250 Returns the value of the socket option \a opt.
251*/
253{
254 Q_Q(const QNativeSocketEngine);
255 if (!q->isValid())
256 return -1;
257
258 // handle non-getsockopt and specific cases first
259 switch (opt) {
263 return -1;
265#ifndef QT_NO_SCTP
266 sctp_initmsg sctpInitMsg;
267 QT_SOCKOPTLEN_T sctpInitMsgSize = sizeof(sctpInitMsg);
268 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
269 &sctpInitMsgSize) == 0)
270 return int(qMin(sctpInitMsg.sinit_num_ostreams, sctpInitMsg.sinit_max_instreams));
271#endif
272 return -1;
273 }
274
276#if defined(IPV6_PATHMTU) && !defined(IPV6_MTU)
277 // Prefer IPV6_MTU (handled by convertToLevelAndOption), if available
278 // (Linux); fall back to IPV6_PATHMTU otherwise (FreeBSD):
280 ip6_mtuinfo mtuinfo;
281 QT_SOCKOPTLEN_T len = sizeof(mtuinfo);
282 if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) == 0)
283 return int(mtuinfo.ip6m_mtu);
284 return -1;
285 }
286#endif
287 break;
288
289 default:
290 break;
291 }
292
293 int n, level;
294 int v = 0;
295 QT_SOCKOPTLEN_T len = sizeof(v);
296
298 if (n != -1 && ::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
299 return len == 1 ? qFromUnaligned<quint8>(&v) : v;
300
301 return -1;
302}
303
304
305/*
306 Sets the socket option \a opt to \a v.
307*/
309{
311 if (!q->isValid())
312 return false;
313
314 // handle non-setsockopt and specific cases first
315 switch (opt) {
317 // Make the socket nonblocking.
318#if !defined(Q_OS_VXWORKS)
319 int flags = ::fcntl(socketDescriptor, F_GETFL, 0);
320 if (flags == -1) {
321#ifdef QNATIVESOCKETENGINE_DEBUG
322 perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_GETFL) failed");
323#endif
324 return false;
325 }
326 if (::fcntl(socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {
327#ifdef QNATIVESOCKETENGINE_DEBUG
328 perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_SETFL) failed");
329#endif
330 return false;
331 }
332#else // Q_OS_VXWORKS
333 int onoff = 1;
334
335 if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) {
336
337#ifdef QNATIVESOCKETENGINE_DEBUG
338 perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed");
339#endif
340 return false;
341 }
342#endif // Q_OS_VXWORKS
343 return true;
344 }
346 return true;
347
349#ifndef QT_NO_SCTP
350 sctp_initmsg sctpInitMsg;
351 QT_SOCKOPTLEN_T sctpInitMsgSize = sizeof(sctpInitMsg);
352 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
353 &sctpInitMsgSize) == 0) {
354 sctpInitMsg.sinit_num_ostreams = sctpInitMsg.sinit_max_instreams = uint16_t(v);
355 return ::setsockopt(socketDescriptor, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg,
356 sctpInitMsgSize) == 0;
357 }
358#endif
359 return false;
360 }
361
362 default:
363 break;
364 }
365
366 int n, level;
368#if defined(SO_REUSEPORT) && !defined(Q_OS_LINUX)
370 // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the
371 // same port (which is useful for multicast UDP). SO_REUSEPORT is, but
372 // we most definitely do not want to use this for TCP. See QTBUG-6305.
374 n = SO_REUSEPORT;
375 }
376#endif
377
378 if (n == -1)
379 return false;
380 return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
381}
382
384{
385#ifdef QNATIVESOCKETENGINE_DEBUG
386 qDebug() << "QNativeSocketEnginePrivate::nativeConnect() " << socketDescriptor;
387#endif
388
389 qt_sockaddr aa;
390 QT_SOCKLEN_T sockAddrSize;
391 setPortAndAddress(port, addr, &aa, &sockAddrSize);
392
393 int connectResult = qt_safe_connect(socketDescriptor, &aa.a, sockAddrSize);
394#if defined (QNATIVESOCKETENGINE_DEBUG)
395 int ecopy = errno;
396#endif
397 if (connectResult == -1) {
398 switch (errno) {
399 case EISCONN:
401 break;
402 case ECONNREFUSED:
403 case EINVAL:
406 break;
407 case ETIMEDOUT:
409 break;
410 case EHOSTUNREACH:
413 break;
414 case ENETUNREACH:
417 break;
418 case EADDRINUSE:
420 break;
421 case EINPROGRESS:
422 case EALREADY:
425 break;
426 case EAGAIN:
428 break;
429 case EACCES:
430 case EPERM:
433 break;
434 case EAFNOSUPPORT:
435 case EBADF:
436 case EFAULT:
437 case ENOTSOCK:
439 break;
440 default:
441 break;
442 }
443
445#if defined (QNATIVESOCKETENGINE_DEBUG)
446 qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
447 addr.toString().toLatin1().constData(), port,
449 ? "Connection in progress" : strerror(ecopy));
450#endif
451 return false;
452 }
453 }
454
455#if defined (QNATIVESOCKETENGINE_DEBUG)
456 qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
457 addr.toString().toLatin1().constData(), port);
458#endif
459
461 return true;
462}
463
465{
466 qt_sockaddr aa;
467 QT_SOCKLEN_T sockAddrSize;
468 setPortAndAddress(port, address, &aa, &sockAddrSize);
469
470#ifdef IPV6_V6ONLY
471 if (aa.a.sa_family == AF_INET6) {
472 int ipv6only = 0;
473 if (address.protocol() == QAbstractSocket::IPv6Protocol)
474 ipv6only = 1;
475 //default value of this socket option varies depending on unix variant (or system configuration on BSD), so always set it explicitly
476 ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
477 }
478#endif
479
480 int bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize);
481 if (bindResult < 0 && errno == EAFNOSUPPORT && address.protocol() == QAbstractSocket::AnyIPProtocol) {
482 // retry with v4
483 aa.a4.sin_family = AF_INET;
484 aa.a4.sin_port = htons(port);
485 aa.a4.sin_addr.s_addr = htonl(address.toIPv4Address());
486 sockAddrSize = sizeof(aa.a4);
487 bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize);
488 }
489
490 if (bindResult < 0) {
491#if defined (QNATIVESOCKETENGINE_DEBUG)
492 int ecopy = errno;
493#endif
494 switch(errno) {
495 case EADDRINUSE:
497 break;
498 case EACCES:
500 break;
501 case EINVAL:
503 break;
504 case EADDRNOTAVAIL:
506 break;
507 default:
508 break;
509 }
510
511#if defined (QNATIVESOCKETENGINE_DEBUG)
512 qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
513 address.toString().toLatin1().constData(), port, strerror(ecopy));
514#endif
515
516 return false;
517 }
518
519#if defined (QNATIVESOCKETENGINE_DEBUG)
520 qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
521 address.toString().toLatin1().constData(), port);
522#endif
524 return true;
525}
526
528{
529 if (qt_safe_listen(socketDescriptor, backlog) < 0) {
530#if defined (QNATIVESOCKETENGINE_DEBUG)
531 int ecopy = errno;
532#endif
533 switch (errno) {
534 case EADDRINUSE:
537 break;
538 default:
539 break;
540 }
541
542#if defined (QNATIVESOCKETENGINE_DEBUG)
543 qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",
544 backlog, strerror(ecopy));
545#endif
546 return false;
547 }
548
549#if defined (QNATIVESOCKETENGINE_DEBUG)
550 qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == true", backlog);
551#endif
552
554 return true;
555}
556
558{
559 int acceptedDescriptor = qt_safe_accept(socketDescriptor, nullptr, nullptr);
560 if (acceptedDescriptor == -1) {
561 switch (errno) {
562 case EBADF:
563 case EOPNOTSUPP:
565 break;
566 case ECONNABORTED:
568 break;
569 case EFAULT:
570 case ENOTSOCK:
572 break;
573 case EPROTONOSUPPORT:
574#if !defined(Q_OS_OPENBSD)
575 case EPROTO:
576#endif
577 case EAFNOSUPPORT:
578 case EINVAL:
580 break;
581 case ENFILE:
582 case EMFILE:
583 case ENOBUFS:
584 case ENOMEM:
586 break;
587 case EACCES:
588 case EPERM:
590 break;
591#if EAGAIN != EWOULDBLOCK
592 case EWOULDBLOCK:
593#endif
594 case EAGAIN:
596 break;
597 default:
599 break;
600 }
601 }
602
603 return qintptr(acceptedDescriptor);
604}
605
606#ifndef QT_NO_NETWORKINTERFACE
607
609 int how6,
610 int how4,
611 const QHostAddress &groupAddress,
613{
614 int level = 0;
615 int sockOpt = 0;
616 void *sockArg;
617 int sockArgSize;
618
619 ip_mreq mreq4;
620 ipv6_mreq mreq6;
621
622 if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) {
623 level = IPPROTO_IPV6;
624 sockOpt = how6;
625 sockArg = &mreq6;
626 sockArgSize = sizeof(mreq6);
627 memset(&mreq6, 0, sizeof(mreq6));
628 Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
629 memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
630 mreq6.ipv6mr_interface = interface.index();
631 } else if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
632 level = IPPROTO_IP;
633 sockOpt = how4;
634 sockArg = &mreq4;
635 sockArgSize = sizeof(mreq4);
636 memset(&mreq4, 0, sizeof(mreq4));
637 mreq4.imr_multiaddr.s_addr = htonl(groupAddress.toIPv4Address());
638
639 if (interface.isValid()) {
640 const QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
641 bool found = false;
642 for (const QNetworkAddressEntry &entry : addressEntries) {
643 const QHostAddress ip = entry.ip();
645 mreq4.imr_interface.s_addr = htonl(ip.toIPv4Address());
646 found = true;
647 break;
648 }
649 }
650 if (!found) {
653 return false;
654 }
655 } else {
656 mreq4.imr_interface.s_addr = INADDR_ANY;
657 }
658 } else {
659 // unreachable
662 return false;
663 }
664
665 int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize);
666 if (res == -1) {
667 switch (errno) {
668 case ENOPROTOOPT:
671 break;
672 case EADDRNOTAVAIL:
675 break;
676 default:
679 break;
680 }
681 return false;
682 }
683 return true;
684}
685
688{
689 return multicastMembershipHelper(this,
690 IPV6_JOIN_GROUP,
691 IP_ADD_MEMBERSHIP,
692 groupAddress,
693 interface);
694}
695
698{
699 return multicastMembershipHelper(this,
700 IPV6_LEAVE_GROUP,
701 IP_DROP_MEMBERSHIP,
702 groupAddress,
703 interface);
704}
705
707{
709 uint v;
710 QT_SOCKOPTLEN_T sizeofv = sizeof(v);
711 if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1)
712 return QNetworkInterface();
714 }
715
716#if defined(Q_OS_SOLARIS)
717 struct in_addr v = { 0, 0, 0, 0};
718#else
719 struct in_addr v = { 0 };
720#endif
721 QT_SOCKOPTLEN_T sizeofv = sizeof(v);
722 if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
723 return QNetworkInterface();
724 if (v.s_addr != 0 && sizeofv >= QT_SOCKOPTLEN_T(sizeof(v))) {
725 QHostAddress ipv4(ntohl(v.s_addr));
726 QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
727 for (int i = 0; i < ifaces.size(); ++i) {
728 const QNetworkInterface &iface = ifaces.at(i);
729 QList<QNetworkAddressEntry> entries = iface.addressEntries();
730 for (int j = 0; j < entries.size(); ++j) {
731 const QNetworkAddressEntry &entry = entries.at(j);
732 if (entry.ip() == ipv4)
733 return iface;
734 }
735 }
736 }
737 return QNetworkInterface();
738}
739
741{
743 uint v = iface.index();
744 return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1);
745 }
746
747 struct in_addr v;
748 if (iface.isValid()) {
749 QList<QNetworkAddressEntry> entries = iface.addressEntries();
750 for (int i = 0; i < entries.size(); ++i) {
751 const QNetworkAddressEntry &entry = entries.at(i);
752 const QHostAddress &ip = entry.ip();
754 v.s_addr = htonl(ip.toIPv4Address());
755 int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v));
756 if (r != -1)
757 return true;
758 }
759 }
760 return false;
761 }
762
763 v.s_addr = INADDR_ANY;
764 return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, sizeof(v)) != -1);
765}
766
767#endif // QT_NO_NETWORKINTERFACE
768
770{
771 int nbytes = 0;
772 // gives shorter than true amounts on Unix domain sockets.
773 qint64 available = -1;
774
775#if defined (SO_NREAD)
777 socklen_t sz = sizeof nbytes;
778 if (!::getsockopt(socketDescriptor, SOL_SOCKET, SO_NREAD, &nbytes, &sz))
779 available = nbytes;
780 }
781#endif
782
783 if (available == -1 && qt_safe_ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
784 available = nbytes;
785
786#if defined (QNATIVESOCKETENGINE_DEBUG)
787 qDebug("QNativeSocketEnginePrivate::nativeBytesAvailable() == %lli", available);
788#endif
789 return available > 0 ? available : 0;
790}
791
793{
794 // Peek 1 bytes into the next message.
795 ssize_t readBytes;
796 char c;
797 QT_EINTR_LOOP(readBytes, ::recv(socketDescriptor, &c, 1, MSG_PEEK));
798
799 // If there's no error, or if our buffer was too small, there must be a
800 // pending datagram.
801 bool result = (readBytes != -1) || errno == EMSGSIZE;
802
803#if defined (QNATIVESOCKETENGINE_DEBUG)
804 qDebug("QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == %s",
805 result ? "true" : "false");
806#endif
807 return result;
808}
809
811{
812 ssize_t recvResult = -1;
813#ifdef Q_OS_LINUX
814 // Linux can return the actual datagram size if we use MSG_TRUNC
815 char c;
816 QT_EINTR_LOOP(recvResult, ::recv(socketDescriptor, &c, 1, MSG_PEEK | MSG_TRUNC));
817#elif defined(SO_NREAD)
818 // macOS can return the actual datagram size if we use SO_NREAD
819 int value;
820 socklen_t valuelen = sizeof(value);
821 recvResult = getsockopt(socketDescriptor, SOL_SOCKET, SO_NREAD, &value, &valuelen);
822 if (recvResult != -1)
823 recvResult = value;
824#else
825 // We need to grow the buffer to fit the entire datagram.
826 // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
827 // almost all uses (effective MTU for UDP under IPv4 is 1468), except
828 // for localhost datagrams and those reassembled by the IP layer.
829 char udpMessagePeekBuffer[1500];
830 struct msghdr msg;
831 struct iovec vec;
832
833 memset(&msg, 0, sizeof(msg));
834 msg.msg_iov = &vec;
835 msg.msg_iovlen = 1;
836 vec.iov_base = udpMessagePeekBuffer;
837 vec.iov_len = sizeof(udpMessagePeekBuffer);
838
839 for (;;) {
840 // the data written to udpMessagePeekBuffer is discarded, so
841 // this function is still reentrant although it might not look
842 // so.
843 recvResult = ::recvmsg(socketDescriptor, &msg, MSG_PEEK);
844 if (recvResult == -1 && errno == EINTR)
845 continue;
846
847 // was the result truncated?
848 if ((msg.msg_flags & MSG_TRUNC) == 0)
849 break;
850
851 // grow by 16 times
852 msg.msg_iovlen *= 16;
853 if (msg.msg_iov != &vec)
854 delete[] msg.msg_iov;
855 msg.msg_iov = new struct iovec[msg.msg_iovlen];
856 std::fill_n(msg.msg_iov, msg.msg_iovlen, vec);
857 }
858
859 if (msg.msg_iov != &vec)
860 delete[] msg.msg_iov;
861#endif
862
863#if defined (QNATIVESOCKETENGINE_DEBUG)
864 qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %zd", recvResult);
865#endif
866
867 return qint64(recvResult);
868}
869
871 QAbstractSocketEngine::PacketHeaderOptions options)
872{
873 // we use quintptr to force the alignment
874 quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
875#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(Q_OS_BSD4)
876 + CMSG_SPACE(sizeof(sockaddr_dl))
877#endif
878#ifndef QT_NO_SCTP
879 + CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))
880#endif
881 + sizeof(quintptr) - 1) / sizeof(quintptr)];
882
883 struct msghdr msg;
884 struct iovec vec;
885 qt_sockaddr aa;
886 char c;
887 memset(&msg, 0, sizeof(msg));
888 memset(&aa, 0, sizeof(aa));
889
890 // we need to receive at least one byte, even if our user isn't interested in it
891 vec.iov_base = maxSize ? data : &c;
892 vec.iov_len = maxSize ? maxSize : 1;
893 msg.msg_iov = &vec;
894 msg.msg_iovlen = 1;
896 msg.msg_name = &aa;
897 msg.msg_namelen = sizeof(aa);
898 }
901 msg.msg_control = cbuf;
902 msg.msg_controllen = sizeof(cbuf);
903 }
904
905 ssize_t recvResult = 0;
906 do {
907 recvResult = ::recvmsg(socketDescriptor, &msg, 0);
908 } while (recvResult == -1 && errno == EINTR);
909
910 if (recvResult == -1) {
911 switch (errno) {
912#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
913 case EWOULDBLOCK:
914#endif
915 case EAGAIN:
916 // No datagram was available for reading
917 recvResult = -2;
918 break;
919 case ECONNREFUSED:
921 break;
922 default:
924 }
925 if (header)
926 header->clear();
927 } else if (options != QAbstractSocketEngine::WantNone) {
929 qt_socket_getPortAndAddress(&aa, &header->senderPort, &header->senderAddress);
930 header->destinationPort = localPort;
931 header->endOfRecord = (msg.msg_flags & MSG_EOR) != 0;
932
933 // parse the ancillary data
934 struct cmsghdr *cmsgptr;
936 QT_WARNING_DISABLE_CLANG("-Wsign-compare")
937 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != nullptr;
938 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
940 if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO
941 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in6_pktinfo))) {
942 in6_pktinfo *info = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
943
944 header->destinationAddress.setAddress(reinterpret_cast<quint8 *>(&info->ipi6_addr));
945 header->ifindex = info->ipi6_ifindex;
946 if (header->ifindex)
947 header->destinationAddress.setScopeId(QString::number(info->ipi6_ifindex));
948 }
949
950#ifdef IP_PKTINFO
951 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO
952 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in_pktinfo))) {
953 in_pktinfo *info = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsgptr));
954
955 header->destinationAddress.setAddress(ntohl(info->ipi_addr.s_addr));
956 header->ifindex = info->ipi_ifindex;
957 }
958#else
959# ifdef IP_RECVDSTADDR
960 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVDSTADDR
961 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in_addr))) {
962 in_addr *addr = reinterpret_cast<in_addr *>(CMSG_DATA(cmsgptr));
963
964 header->destinationAddress.setAddress(ntohl(addr->s_addr));
965 }
966# endif
967# if defined(IP_RECVIF) && defined(Q_OS_BSD4)
968 if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF
969 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) {
970 sockaddr_dl *sdl = reinterpret_cast<sockaddr_dl *>(CMSG_DATA(cmsgptr));
971 header->ifindex = sdl->sdl_index;
972 }
973# endif
974#endif
975
976 if (cmsgptr->cmsg_len == CMSG_LEN(sizeof(int))
977 && ((cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_HOPLIMIT)
978 || (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_TTL))) {
979 static_assert(sizeof(header->hopLimit) == sizeof(int));
980 memcpy(&header->hopLimit, CMSG_DATA(cmsgptr), sizeof(header->hopLimit));
981 }
982
983#ifndef QT_NO_SCTP
984 if (cmsgptr->cmsg_level == IPPROTO_SCTP && cmsgptr->cmsg_type == SCTP_SNDRCV
985 && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sctp_sndrcvinfo))) {
986 sctp_sndrcvinfo *rcvInfo = reinterpret_cast<sctp_sndrcvinfo *>(CMSG_DATA(cmsgptr));
987
988 header->streamNumber = int(rcvInfo->sinfo_stream);
989 }
990#endif
991 }
992 }
993
994#if defined (QNATIVESOCKETENGINE_DEBUG)
995 qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",
996 data, QtDebugUtils::toPrintable(data, recvResult, 16).constData(), maxSize,
997 (recvResult != -1 && options != QAbstractSocketEngine::WantNone)
998 ? header->senderAddress.toString().toLatin1().constData() : "(unknown)",
999 (recvResult != -1 && options != QAbstractSocketEngine::WantNone)
1000 ? header->senderPort : 0, (qint64) recvResult);
1001#endif
1002
1003 return qint64((maxSize || recvResult < 0) ? recvResult : Q_INT64_C(0));
1004}
1005
1007{
1008 // we use quintptr to force the alignment
1009 quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
1010#ifndef QT_NO_SCTP
1011 + CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))
1012#endif
1013 + sizeof(quintptr) - 1) / sizeof(quintptr)];
1014
1015 struct cmsghdr *cmsgptr = reinterpret_cast<struct cmsghdr *>(cbuf);
1016 struct msghdr msg;
1017 struct iovec vec;
1018 qt_sockaddr aa;
1019
1020 memset(&msg, 0, sizeof(msg));
1021 memset(&aa, 0, sizeof(aa));
1022 vec.iov_base = const_cast<char *>(data);
1023 vec.iov_len = len;
1024 msg.msg_iov = &vec;
1025 msg.msg_iovlen = 1;
1026 msg.msg_control = &cbuf;
1027
1028 if (header.destinationPort != 0) {
1029 msg.msg_name = &aa.a;
1030 setPortAndAddress(header.destinationPort, header.destinationAddress,
1031 &aa, &msg.msg_namelen);
1032 }
1033
1034 if (msg.msg_namelen == sizeof(aa.a6)) {
1035 if (header.hopLimit != -1) {
1036 msg.msg_controllen += CMSG_SPACE(sizeof(int));
1037 cmsgptr->cmsg_len = CMSG_LEN(sizeof(int));
1038 cmsgptr->cmsg_level = IPPROTO_IPV6;
1039 cmsgptr->cmsg_type = IPV6_HOPLIMIT;
1040 memcpy(CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
1041 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(int)));
1042 }
1043 if (header.ifindex != 0 || !header.senderAddress.isNull()) {
1044 struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
1045 memset(data, 0, sizeof(*data));
1046 msg.msg_controllen += CMSG_SPACE(sizeof(*data));
1047 cmsgptr->cmsg_len = CMSG_LEN(sizeof(*data));
1048 cmsgptr->cmsg_level = IPPROTO_IPV6;
1049 cmsgptr->cmsg_type = IPV6_PKTINFO;
1050 data->ipi6_ifindex = header.ifindex;
1051
1052 QIPv6Address tmp = header.senderAddress.toIPv6Address();
1053 memcpy(&data->ipi6_addr, &tmp, sizeof(tmp));
1054 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1055 }
1056 } else {
1057 if (header.hopLimit != -1) {
1058 msg.msg_controllen += CMSG_SPACE(sizeof(int));
1059 cmsgptr->cmsg_len = CMSG_LEN(sizeof(int));
1060 cmsgptr->cmsg_level = IPPROTO_IP;
1061 cmsgptr->cmsg_type = IP_TTL;
1062 memcpy(CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
1063 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(int)));
1064 }
1065
1066#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
1067 if (header.ifindex != 0 || !header.senderAddress.isNull()) {
1068# ifdef IP_PKTINFO
1069 struct in_pktinfo *data = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsgptr));
1070 memset(data, 0, sizeof(*data));
1071 cmsgptr->cmsg_type = IP_PKTINFO;
1072 data->ipi_ifindex = header.ifindex;
1073 data->ipi_addr.s_addr = htonl(header.senderAddress.toIPv4Address());
1074# elif defined(IP_SENDSRCADDR)
1075 struct in_addr *data = reinterpret_cast<in_addr *>(CMSG_DATA(cmsgptr));
1076 cmsgptr->cmsg_type = IP_SENDSRCADDR;
1077 data->s_addr = htonl(header.senderAddress.toIPv4Address());
1078# endif
1079 cmsgptr->cmsg_level = IPPROTO_IP;
1080 msg.msg_controllen += CMSG_SPACE(sizeof(*data));
1081 cmsgptr->cmsg_len = CMSG_LEN(sizeof(*data));
1082 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1083 }
1084#endif
1085 }
1086
1087#ifndef QT_NO_SCTP
1088 if (header.streamNumber != -1) {
1089 struct sctp_sndrcvinfo *data = reinterpret_cast<sctp_sndrcvinfo *>(CMSG_DATA(cmsgptr));
1090 memset(data, 0, sizeof(*data));
1091 msg.msg_controllen += CMSG_SPACE(sizeof(sctp_sndrcvinfo));
1092 cmsgptr->cmsg_len = CMSG_LEN(sizeof(sctp_sndrcvinfo));
1093 cmsgptr->cmsg_level = IPPROTO_SCTP;
1094 cmsgptr->cmsg_type = SCTP_SNDRCV;
1095 data->sinfo_stream = uint16_t(header.streamNumber);
1096 cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data)));
1097 }
1098#endif
1099
1100 if (msg.msg_controllen == 0)
1101 msg.msg_control = nullptr;
1102 ssize_t sentBytes = qt_safe_sendmsg(socketDescriptor, &msg, 0);
1103
1104 if (sentBytes < 0) {
1105 switch (errno) {
1106#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1107 case EWOULDBLOCK:
1108#endif
1109 case EAGAIN:
1110 sentBytes = -2;
1111 break;
1112 case EMSGSIZE:
1114 break;
1115 case ECONNRESET:
1117 break;
1118 default:
1120 }
1121 }
1122
1123#if defined (QNATIVESOCKETENGINE_DEBUG)
1124 qDebug("QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
1125 QtDebugUtils::toPrintable(data, len, 16).constData(), len,
1126 header.destinationAddress.toString().toLatin1().constData(),
1127 header.destinationPort, (qint64) sentBytes);
1128#endif
1129
1130 return qint64(sentBytes);
1131}
1132
1134{
1135 localPort = 0;
1137 peerPort = 0;
1140
1141 if (socketDescriptor == -1)
1142 return false;
1143
1144 qt_sockaddr sa;
1145 QT_SOCKLEN_T sockAddrSize = sizeof(sa);
1146
1147 // Determine local address
1148 memset(&sa, 0, sizeof(sa));
1149 if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
1151
1152 // Determine protocol family
1153 switch (sa.a.sa_family) {
1154 case AF_INET:
1156 break;
1157 case AF_INET6:
1159 break;
1160 default:
1162 break;
1163 }
1164
1165 } else if (errno == EBADF) {
1167 return false;
1168 }
1169
1170#if defined (IPV6_V6ONLY)
1171 // determine if local address is dual mode
1172 // On linux, these are returned as "::" (==AnyIPv6)
1173 // On OSX, these are returned as "::FFFF:0.0.0.0" (==AnyIPv4)
1174 // in either case, the IPV6_V6ONLY option is cleared
1175 int ipv6only = 0;
1176 socklen_t optlen = sizeof(ipv6only);
1179 && !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
1180 if (optlen != sizeof(ipv6only))
1181 qWarning("unexpected size of IPV6_V6ONLY socket option");
1182 if (!ipv6only) {
1185 }
1186 }
1187#endif
1188
1189 // Determine the remote address
1190 bool connected = ::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0;
1191 if (connected) {
1194 }
1195
1196 // Determine the socket type (UDP/TCP/SCTP)
1197 int value = 0;
1198 QT_SOCKOPTLEN_T valueSize = sizeof(int);
1199 if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, &value, &valueSize) == 0) {
1200 if (value == SOCK_STREAM) {
1201#ifndef QT_NO_SCTP
1204 if (connected) {
1205 sctp_status sctpStatus;
1206 QT_SOCKOPTLEN_T sctpStatusSize = sizeof(sctpStatus);
1207 sctp_event_subscribe sctpEvents;
1208
1209 memset(&sctpEvents, 0, sizeof(sctpEvents));
1210 sctpEvents.sctp_data_io_event = 1;
1211 if (::getsockopt(socketDescriptor, SOL_SCTP, SCTP_STATUS, &sctpStatus,
1212 &sctpStatusSize) == 0 &&
1213 ::setsockopt(socketDescriptor, SOL_SCTP, SCTP_EVENTS, &sctpEvents,
1214 sizeof(sctpEvents)) == 0) {
1215 inboundStreamCount = int(sctpStatus.sstat_instrms);
1216 outboundStreamCount = int(sctpStatus.sstat_outstrms);
1217 } else {
1220 return false;
1221 }
1222 }
1223 } else {
1225 }
1226#else
1228#endif
1229 } else {
1230 if (value == SOCK_DGRAM)
1232 else
1234 }
1235 }
1236#if defined (QNATIVESOCKETENGINE_DEBUG)
1237 QString socketProtocolStr = QStringLiteral("UnknownProtocol");
1238 if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol");
1240
1241 QString socketTypeStr = QStringLiteral("UnknownSocketType");
1242 if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket");
1243 else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = QStringLiteral("UdpSocket");
1244 else if (socketType == QAbstractSocket::SctpSocket) socketTypeStr = QStringLiteral("SctpSocket");
1245
1246 qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i,"
1247 " peer == %s:%i, socket == %s - %s, inboundStreamCount == %i, outboundStreamCount == %i",
1249 peerAddress.toString().toLatin1().constData(), peerPort,socketTypeStr.toLatin1().constData(),
1250 socketProtocolStr.toLatin1().constData(), inboundStreamCount, outboundStreamCount);
1251#endif
1252 return true;
1253}
1254
1256{
1257#if defined (QNATIVESOCKETENGINE_DEBUG)
1258 qDebug("QNativeSocketEngine::nativeClose()");
1259#endif
1260
1262}
1263
1265{
1267
1268 ssize_t writtenBytes;
1270
1271 if (writtenBytes < 0) {
1272 switch (errno) {
1273 case EPIPE:
1274 case ECONNRESET:
1275 writtenBytes = -1;
1277 q->close();
1278 break;
1279#if EWOULDBLOCK != EAGAIN
1280 case EWOULDBLOCK:
1281#endif
1282 case EAGAIN:
1283 writtenBytes = 0;
1284 break;
1285 case EMSGSIZE:
1287 break;
1288 default:
1289 break;
1290 }
1291 }
1292
1293#if defined (QNATIVESOCKETENGINE_DEBUG)
1294 qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %llu) == %i", data,
1295 QtDebugUtils::toPrintable(data, len, 16).constData(), len, (int) writtenBytes);
1296#endif
1297
1298 return qint64(writtenBytes);
1299}
1300/*
1301*/
1303{
1305 if (!q->isValid()) {
1306 qWarning("QNativeSocketEngine::nativeRead: Invalid socket");
1307 return -1;
1308 }
1309
1310 ssize_t r = 0;
1311 r = qt_safe_read(socketDescriptor, data, maxSize);
1312
1313 if (r < 0) {
1314 r = -1;
1315 switch (errno) {
1316#if EWOULDBLOCK-0 && EWOULDBLOCK != EAGAIN
1317 case EWOULDBLOCK:
1318#endif
1319 case EAGAIN:
1320 // No data was available for reading
1321 r = -2;
1322 break;
1323 case ECONNRESET:
1324#if defined(Q_OS_VXWORKS)
1325 case ESHUTDOWN:
1326#endif
1327 r = 0;
1328 break;
1329 case ETIMEDOUT:
1331 break;
1332 default:
1334 break;
1335 }
1336
1337 if (r == -1) {
1338 hasSetSocketError = true;
1340 }
1341 }
1342
1343#if defined (QNATIVESOCKETENGINE_DEBUG)
1344 qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %zd", data,
1345 QtDebugUtils::toPrintable(data, r, 16).constData(), maxSize, r);
1346#endif
1347
1348 return qint64(r);
1349}
1350
1352{
1353 bool dummy;
1354 return nativeSelect(deadline, selectForRead, !selectForRead, &dummy, &dummy);
1355}
1356
1357#ifndef Q_OS_WASM
1358
1360 bool checkWrite, bool *selectForRead,
1361 bool *selectForWrite) const
1362{
1363 pollfd pfd = qt_make_pollfd(socketDescriptor, 0);
1364
1365 if (checkRead)
1366 pfd.events |= POLLIN;
1367
1368 if (checkWrite)
1369 pfd.events |= POLLOUT;
1370
1371 const int ret = qt_safe_poll(&pfd, 1, deadline);
1372
1373 if (ret <= 0)
1374 return ret;
1375
1376 if (pfd.revents & POLLNVAL) {
1377 errno = EBADF;
1378 return -1;
1379 }
1380
1381 static const short read_flags = POLLIN | POLLHUP | POLLERR;
1382 static const short write_flags = POLLOUT | POLLERR;
1383
1384 *selectForRead = ((pfd.revents & read_flags) != 0);
1385 *selectForWrite = ((pfd.revents & write_flags) != 0);
1386
1387 return ret;
1388}
1389
1390#else
1391
1393 bool checkWrite, bool *selectForRead,
1394 bool *selectForWrite) const
1395{
1396 *selectForRead = checkRead;
1397 *selectForWrite = checkWrite;
1398 bool socketDisconnect = false;
1400 checkWrite, selectForRead, selectForWrite,
1401 &socketDisconnect);
1402
1403 // The disconnect/close handling code in QAbstractsScket::canReadNotification()
1404 // does not detect remote disconnect properly; do that here as a workardound.
1405 if (socketDisconnect)
1407
1408 return 1;
1409}
1410
1411#endif // Q_OS_WASM
1412
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:124
\inmodule QtCore
qint64 remainingTime() const noexcept
Returns the remaining time in this QDeadlineTimer object in milliseconds.
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.
QString toString() const
Returns the address as a string.
NetworkLayerProtocol protocol() const
Returns the network layer protocol of the host address.
bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol)
QNetworkInterface nativeMulticastInterface() 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)
int nativeSelect(QDeadlineTimer deadline, bool selectForRead) const
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:129
QByteArray toLatin1() const &
Definition qstring.h:630
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:8084
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:24
#define QT_WARNING_POP
#define QT_WARNING_PUSH
#define QT_WARNING_DISABLE_CLANG(text)
int qt_safe_poll(struct pollfd *fds, nfds_t nfds, QDeadlineTimer deadline)
#define QT_EINTR_LOOP(var, cmd)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static struct pollfd qt_make_pollfd(int fd, short events)
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:164
#define qWarning
Definition qlogging.h:166
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]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLbitfield flags
GLfloat n
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
const GLubyte * c
GLuint entry
GLenum const void * addr
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLuint GLenum option
GLenum GLsizei len
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
unsigned short quint16
Definition qtypes.h:48
size_t quintptr
Definition qtypes.h:167
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
unsigned char quint8
Definition qtypes.h:46
#define Q_INT64_C(c)
Definition qtypes.h:57
ptrdiff_t qintptr
Definition qtypes.h:166
QDeadlineTimer deadline(30s)
QTcpSocket * socket
[1]
QHostInfo info
[0]