1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 //#define QNATIVESOCKETENGINE_DEBUG
42 
43 /*! \class QNativeSocketEngine
44     \internal
45 
46     \brief The QNativeSocketEngine class provides low level access to a socket.
47 
48     \reentrant
49     \ingroup network
50     \inmodule QtNetwork
51 
52     QtSocketLayer provides basic socket functionality provided by the
53     operating system. It also keeps track of what state the socket is
54     in, and which errors that occur.
55 
56     The classes QTcpSocket, QUdpSocket and QTcpServer provide a
57     higher level API, and are in general more useful for the common
58     application.
59 
60     There are two main ways of initializing the a QNativeSocketEngine; either
61     create a new socket by passing the socket type (TcpSocket or
62     UdpSocket) and network layer protocol (IPv4Protocol or
63     IPv6Protocol) to initialize(), or pass an existing socket
64     descriptor and have QNativeSocketEngine determine the type and protocol
65     itself. The native socket descriptor can later be fetched by
66     calling socketDescriptor(). The socket is made non-blocking, but
67     blocking behavior can still be achieved by calling waitForRead()
68     and waitForWrite(). isValid() can be called to check if the socket
69     has been successfully initialized and is ready to use.
70 
71     To connect to a host, determine its address and pass this and the
72     port number to connectToHost(). The socket can then be used as a
73     TCP or UDP client. Otherwise; bind(), listen() and accept() are
74     used to have the socket function as a TCP or UDP server. Call
75     close() to close the socket.
76 
77     bytesAvailable() is called to determine how much data is available
78     for reading. read() and write() are used by both TCP and UDP
79     clients to exchange data with the connected peer. UDP clients can
80     also call hasMoreDatagrams(), nextDatagramSize(),
81     readDatagram(), and writeDatagram().
82 
83     Call state() to determine the state of the socket, for
84     example, ListeningState or ConnectedState. socketType() tells
85     whether the socket is a TCP socket or a UDP socket, or if the
86     socket type is unknown. protocol() is used to determine the
87     socket's network layer protocol.
88 
89     localAddress(), localPort() are called to find the address and
90     port that are currently bound to the socket. If the socket is
91     connected, peerAddress() and peerPort() determine the address and
92     port of the connected peer.
93 
94     Finally, if any function should fail, error() and
95     errorString() can be called to determine the cause of the error.
96 */
97 
98 /*!
99     \enum QAbstractSocketEngine::PacketHeaderOption
100 
101     Specifies which fields in the IP packet header are desired in the call to
102     readDatagram().
103 
104     \value WantNone             caller isn't interested in the packet metadata
105     \value WantDatagramSender   caller wants the sender address and port number
106     \value WantDatagramDestination caller wants the packet's destination address and port number
107                                    (this option is useful to distinguish multicast packets from unicast)
108     \value WantDatagramHopLimit caller wants the packet's remaining hop limit or time to live
109                                 (this option is useful in IPv4 multicasting, where the TTL is used
110                                 to indicate the realm)
111     \value WantAll              this is a catch-all value to indicate the caller is
112                                 interested in all the available information
113 
114     \sa readDatagram(), QNetworkDatagram
115 */
116 
117 #include "qnativesocketengine_p.h"
118 
119 #include <qabstracteventdispatcher.h>
120 #include <qsocketnotifier.h>
121 #include <qnetworkinterface.h>
122 
123 #include <private/qthread_p.h>
124 #include <private/qobject_p.h>
125 
126 #if !defined(QT_NO_NETWORKPROXY)
127 # include "qnetworkproxy.h"
128 # include "qabstractsocket.h"
129 # include "qtcpserver.h"
130 #endif
131 
132 #if !defined(QT_NO_SCTP)
133 # include "qsctpserver.h"
134 #endif
135 
136 QT_BEGIN_NAMESPACE
137 
138 //#define QNATIVESOCKETENGINE_DEBUG
139 
140 #define Q_VOID
141 
142 // Common constructs
143 #define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \
144     if (!isValid()) { \
145         qWarning(""#function" was called on an uninitialized socket device"); \
146         return returnValue; \
147     } } while (0)
148 #define Q_CHECK_INVALID_SOCKETLAYER(function, returnValue) do { \
149     if (isValid()) { \
150         qWarning(""#function" was called on an already initialized socket device"); \
151         return returnValue; \
152     } } while (0)
153 #define Q_CHECK_STATE(function, checkState, returnValue) do { \
154     if (d->socketState != (checkState)) { \
155         qWarning(""#function" was not called in "#checkState); \
156         return (returnValue); \
157     } } while (0)
158 #define Q_CHECK_NOT_STATE(function, checkState, returnValue) do { \
159     if (d->socketState == (checkState)) { \
160         qWarning(""#function" was called in "#checkState); \
161         return (returnValue); \
162     } } while (0)
163 #define Q_CHECK_STATES(function, state1, state2, returnValue) do { \
164     if (d->socketState != (state1) && d->socketState != (state2)) { \
165         qWarning(""#function" was called" \
166                  " not in "#state1" or "#state2); \
167         return (returnValue); \
168     } } while (0)
169 #define Q_CHECK_STATES3(function, state1, state2, state3, returnValue) do { \
170     if (d->socketState != (state1) && d->socketState != (state2) && d->socketState != (state3)) { \
171         qWarning(""#function" was called" \
172                  " not in "#state1" or "#state2); \
173         return (returnValue); \
174     } } while (0)
175 #define Q_CHECK_TYPE(function, type, returnValue) do { \
176     if (d->socketType != (type)) { \
177         qWarning(#function" was called by a" \
178                  " socket other than "#type""); \
179         return (returnValue); \
180     } } while (0)
181 #define Q_CHECK_TYPES(function, type1, type2, returnValue) do { \
182     if (d->socketType != (type1) && d->socketType != (type2)) { \
183         qWarning(#function" was called by a" \
184                  " socket other than "#type1" or "#type2); \
185         return (returnValue); \
186     } } while (0)
187 #define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
188 
189 /*! \internal
190     Constructs the private class and initializes all data members.
191 */
QNativeSocketEnginePrivate()192 QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() :
193     socketDescriptor(-1),
194     readNotifier(nullptr),
195     writeNotifier(nullptr),
196     exceptNotifier(nullptr)
197 {
198 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
199     QSysInfo::machineHostName();        // this initializes ws2_32.dll
200 #endif
201 }
202 
203 /*! \internal
204     Destructs the private class.
205 */
~QNativeSocketEnginePrivate()206 QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate()
207 {
208 }
209 
210 /*! \internal
211 
212     Sets the error and error string if not set already. The only
213     interesting error is the first one that occurred, and not the last
214     one.
215 */
setError(QAbstractSocket::SocketError error,ErrorString errorString) const216 void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const
217 {
218     if (hasSetSocketError) {
219         // Only set socket errors once for one engine; expect the
220         // socket to recreate its engine after an error. Note: There's
221         // one exception: SocketError(11) bypasses this as it's purely
222         // a temporary internal error condition.
223         // Another exception is the way the waitFor*() functions set
224         // an error when a timeout occurs. After the call to setError()
225         // they reset the hasSetSocketError to false
226         return;
227     }
228     if (error != QAbstractSocket::SocketError(11))
229         hasSetSocketError = true;
230 
231     socketError = error;
232 
233     switch (errorString) {
234     case NonBlockingInitFailedErrorString:
235         socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket");
236         break;
237     case BroadcastingInitFailedErrorString:
238         socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket");
239         break;
240     // should not happen anymore
241     case NoIpV6ErrorString:
242         socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support");
243         break;
244     case RemoteHostClosedErrorString:
245         socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection");
246         break;
247     case TimeOutErrorString:
248         socketErrorString = QNativeSocketEngine::tr("Network operation timed out");
249         break;
250     case ResourceErrorString:
251         socketErrorString = QNativeSocketEngine::tr("Out of resources");
252         break;
253     case OperationUnsupportedErrorString:
254         socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation");
255         break;
256     case ProtocolUnsupportedErrorString:
257         socketErrorString = QNativeSocketEngine::tr("Protocol type not supported");
258         break;
259     case InvalidSocketErrorString:
260         socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor");
261         break;
262     case HostUnreachableErrorString:
263         socketErrorString = QNativeSocketEngine::tr("Host unreachable");
264         break;
265     case NetworkUnreachableErrorString:
266         socketErrorString = QNativeSocketEngine::tr("Network unreachable");
267         break;
268     case AccessErrorString:
269         socketErrorString = QNativeSocketEngine::tr("Permission denied");
270         break;
271     case ConnectionTimeOutErrorString:
272         socketErrorString = QNativeSocketEngine::tr("Connection timed out");
273         break;
274     case ConnectionRefusedErrorString:
275         socketErrorString = QNativeSocketEngine::tr("Connection refused");
276         break;
277     case AddressInuseErrorString:
278         socketErrorString = QNativeSocketEngine::tr("The bound address is already in use");
279         break;
280     case AddressNotAvailableErrorString:
281         socketErrorString = QNativeSocketEngine::tr("The address is not available");
282         break;
283     case AddressProtectedErrorString:
284         socketErrorString = QNativeSocketEngine::tr("The address is protected");
285         break;
286     case DatagramTooLargeErrorString:
287         socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send");
288         break;
289     case SendDatagramErrorString:
290         socketErrorString = QNativeSocketEngine::tr("Unable to send a message");
291         break;
292     case ReceiveDatagramErrorString:
293         socketErrorString = QNativeSocketEngine::tr("Unable to receive a message");
294         break;
295     case WriteErrorString:
296         socketErrorString = QNativeSocketEngine::tr("Unable to write");
297         break;
298     case ReadErrorString:
299         socketErrorString = QNativeSocketEngine::tr("Network error");
300         break;
301     case PortInuseErrorString:
302         socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port");
303         break;
304     case NotSocketErrorString:
305         socketErrorString = QNativeSocketEngine::tr("Operation on non-socket");
306         break;
307     case InvalidProxyTypeString:
308         socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation");
309         break;
310     case TemporaryErrorString:
311         socketErrorString = QNativeSocketEngine::tr("Temporary error");
312         break;
313     case NetworkDroppedConnectionErrorString:
314         socketErrorString = QNativeSocketEngine::tr("Network dropped connection on reset");
315         break;
316     case ConnectionResetErrorString:
317         socketErrorString = QNativeSocketEngine::tr("Connection reset by peer");
318         break;
319     case UnknownSocketErrorString:
320         socketErrorString = QNativeSocketEngine::tr("Unknown error");
321         break;
322     }
323 }
324 
325 /*!
326     \internal
327 
328     Adjusts the incoming \a address family to match the currently bound address
329     (if any). This function will convert v4-mapped IPv6 addresses to IPv4 and
330     vice-versa. All other address types and values will be left unchanged.
331  */
adjustAddressProtocol(const QHostAddress & address) const332 QHostAddress QNativeSocketEnginePrivate::adjustAddressProtocol(const QHostAddress &address) const
333 {
334     QAbstractSocket::NetworkLayerProtocol targetProtocol = socketProtocol;
335     if (Q_LIKELY(targetProtocol == QAbstractSocket::UnknownNetworkLayerProtocol))
336         return address;
337 
338     QAbstractSocket::NetworkLayerProtocol sourceProtocol = address.protocol();
339 
340     if (targetProtocol == QAbstractSocket::AnyIPProtocol)
341         targetProtocol = QAbstractSocket::IPv6Protocol;
342     if (targetProtocol == QAbstractSocket::IPv6Protocol && sourceProtocol == QAbstractSocket::IPv4Protocol) {
343         // convert to IPv6 v4-mapped address. This always works
344         return QHostAddress(address.toIPv6Address());
345     }
346 
347     if (targetProtocol == QAbstractSocket::IPv4Protocol && sourceProtocol == QAbstractSocket::IPv6Protocol) {
348         // convert to IPv4 if the source is a v4-mapped address
349         quint32 ip4 = address.toIPv4Address();
350         if (ip4)
351             return QHostAddress(ip4);
352     }
353 
354     return address;
355 }
356 
checkProxy(const QHostAddress & address)357 bool QNativeSocketEnginePrivate::checkProxy(const QHostAddress &address)
358 {
359     if (address.isLoopback())
360         return true;
361 
362 #if !defined(QT_NO_NETWORKPROXY)
363     QObject *parent = q_func()->parent();
364     QNetworkProxy proxy;
365     QNetworkProxyQuery::QueryType queryType = QNetworkProxyQuery::TcpSocket;
366     if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(parent)) {
367         proxy = socket->proxy();
368         switch (socket->socketType()) {
369         case QAbstractSocket::UdpSocket:
370             queryType = QNetworkProxyQuery::UdpSocket;
371             break;
372         case QAbstractSocket::SctpSocket:
373             queryType = QNetworkProxyQuery::SctpSocket;
374             break;
375         case QAbstractSocket::TcpSocket:
376         case QAbstractSocket::UnknownSocketType:
377             queryType = QNetworkProxyQuery::TcpSocket;
378         }
379     } else if (QTcpServer *server = qobject_cast<QTcpServer *>(parent)) {
380         proxy = server->proxy();
381         queryType = QNetworkProxyQuery::TcpServer;
382 #ifndef QT_NO_SCTP
383         if (qobject_cast<QSctpServer *>(server))
384             queryType = QNetworkProxyQuery::SctpServer;
385 #endif
386     } else {
387         // no parent -> no proxy
388         return true;
389     }
390 
391     if (proxy.type() == QNetworkProxy::DefaultProxy) {
392         // This is similar to what we have in QNetworkProxy::applicationProxy,
393         // the only difference is that we provide the correct query type instead of
394         // always using TcpSocket unconditionally (this is the default type for
395         // QNetworkProxyQuery).
396         QNetworkProxyQuery query;
397         query.setQueryType(queryType);
398         proxy = QNetworkProxyFactory::proxyForQuery(query).constFirst();
399     }
400 
401     if (proxy.type() != QNetworkProxy::DefaultProxy &&
402         proxy.type() != QNetworkProxy::NoProxy) {
403         // QNativeSocketEngine doesn't do proxies
404         setError(QAbstractSocket::UnsupportedSocketOperationError,
405                  QNativeSocketEnginePrivate::InvalidProxyTypeString);
406         return false;
407     }
408 #endif
409 
410     return true;
411 }
412 
413 /*!
414     Constructs a QNativeSocketEngine.
415 
416     \sa initialize()
417 */
QNativeSocketEngine(QObject * parent)418 QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
419     : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent)
420 {
421 }
422 
423 /*!
424     Destructs a QNativeSocketEngine.
425 */
~QNativeSocketEngine()426 QNativeSocketEngine::~QNativeSocketEngine()
427 {
428     close();
429 }
430 
431 /*!
432     Initializes a QNativeSocketEngine by creating a new socket of type \a
433     socketType and network layer protocol \a protocol. Returns \c true on
434     success; otherwise returns \c false.
435 
436     If the socket was already initialized, this function closes the
437     socket before reeinitializing it.
438 
439     The new socket is non-blocking, and for UDP sockets it's also
440     broadcast enabled.
441 */
initialize(QAbstractSocket::SocketType socketType,QAbstractSocket::NetworkLayerProtocol protocol)442 bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol protocol)
443 {
444     Q_D(QNativeSocketEngine);
445     if (isValid())
446         close();
447 
448     // Create the socket
449     if (!d->createNewSocket(socketType, protocol)) {
450 #if defined (QNATIVESOCKETENGINE_DEBUG)
451         QString typeStr = QLatin1String("UnknownSocketType");
452         if (socketType == QAbstractSocket::TcpSocket) typeStr = QLatin1String("TcpSocket");
453         else if (socketType == QAbstractSocket::UdpSocket) typeStr = QLatin1String("UdpSocket");
454         else if (socketType == QAbstractSocket::SctpSocket) typeStr = QLatin1String("SctpSocket");
455         QString protocolStr = QLatin1String("UnknownProtocol");
456         if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = QLatin1String("IPv4Protocol");
457         else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = QLatin1String("IPv6Protocol");
458         qDebug("QNativeSocketEngine::initialize(type == %s, protocol == %s) failed: %s",
459                typeStr.toLatin1().constData(), protocolStr.toLatin1().constData(), d->socketErrorString.toLatin1().constData());
460 #endif
461         return false;
462     }
463 
464     if (socketType == QAbstractSocket::UdpSocket) {
465         // Set the broadcasting flag if it's a UDP socket.
466         if (!setOption(BroadcastSocketOption, 1)) {
467             d->setError(QAbstractSocket::UnsupportedSocketOperationError,
468                         QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
469             close();
470             return false;
471         }
472 
473         // Set some extra flags that are interesting to us, but accept failure
474         setOption(ReceivePacketInformation, 1);
475         setOption(ReceiveHopLimit, 1);
476     }
477 
478 
479     // Make sure we receive out-of-band data
480     if (socketType == QAbstractSocket::TcpSocket
481         && !setOption(ReceiveOutOfBandData, 1)) {
482         qWarning("QNativeSocketEngine::initialize unable to inline out-of-band data");
483     }
484 
485     // Before Qt 4.6, we always set the send and receive buffer size to 49152 as
486     // this was found to be an optimal value. However, modern OS
487     // all have some kind of auto tuning for this and we therefore don't set
488     // this explictly anymore.
489     // If it introduces any performance regressions for Qt 4.6.x (x > 0) then
490     // it will be put back in.
491     //
492     // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed
493     // with this.
494     //
495     // pre-4.6:
496     // setReceiveBufferSize(49152);
497     // setSendBufferSize(49152);
498 
499     return true;
500 }
501 
502 /*! \overload
503 
504     Initializes the socket using \a socketDescriptor instead of
505     creating a new one. The socket type and network layer protocol are
506     determined automatically. The socket's state is set to \a
507     socketState.
508 
509     If the socket type is either TCP or UDP, it is made non-blocking.
510     UDP sockets are also broadcast enabled.
511  */
initialize(qintptr socketDescriptor,QAbstractSocket::SocketState socketState)512 bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState)
513 {
514     Q_D(QNativeSocketEngine);
515 
516     if (isValid())
517         close();
518 
519     d->socketDescriptor = socketDescriptor;
520 
521     // determine socket type and protocol
522     if (!d->fetchConnectionParameters()) {
523 #if defined (QNATIVESOCKETENGINE_DEBUG)
524         qDebug() << "QNativeSocketEngine::initialize(socketDescriptor) failed:"
525                  << socketDescriptor << d->socketErrorString;
526 #endif
527         d->socketDescriptor = -1;
528         return false;
529     }
530 
531     if (d->socketType != QAbstractSocket::UnknownSocketType) {
532         // Make the socket nonblocking.
533         if (!setOption(NonBlockingSocketOption, 1)) {
534             d->setError(QAbstractSocket::UnsupportedSocketOperationError,
535                 QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
536             close();
537             return false;
538         }
539 
540         // Set the broadcasting flag if it's a UDP socket.
541         if (d->socketType == QAbstractSocket::UdpSocket
542             && !setOption(BroadcastSocketOption, 1)) {
543             d->setError(QAbstractSocket::UnsupportedSocketOperationError,
544                 QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
545             close();
546             return false;
547         }
548     }
549 
550     d->socketState = socketState;
551     return true;
552 }
553 
554 /*!
555     Returns \c true if the socket is valid; otherwise returns \c false. A
556     socket is valid if it has not been successfully initialized, or if
557     it has been closed.
558 */
isValid() const559 bool QNativeSocketEngine::isValid() const
560 {
561     Q_D(const QNativeSocketEngine);
562     return d->socketDescriptor != -1;
563 }
564 
565 /*!
566     Returns the native socket descriptor. Any use of this descriptor
567     stands the risk of being non-portable.
568 */
socketDescriptor() const569 qintptr QNativeSocketEngine::socketDescriptor() const
570 {
571     Q_D(const QNativeSocketEngine);
572     return d->socketDescriptor;
573 }
574 
575 /*!
576     Connects to the IP address and port specified by \a address and \a
577     port. If the connection is established, this function returns \c true
578     and the socket enters ConnectedState. Otherwise, false is
579     returned.
580 
581     If false is returned, state() should be called to see if the
582     socket is in ConnectingState. If so, a delayed TCP connection is
583     taking place, and connectToHost() must be called again later to
584     determine if the connection was established successfully or
585     not. The second connection attempt must be made when the socket is
586     ready for writing. This state can be determined either by
587     connecting a QSocketNotifier to the socket descriptor returned by
588     socketDescriptor(), or by calling the blocking function
589     waitForWrite().
590 
591     Example:
592     \snippet code/src_network_socket_qnativesocketengine.cpp 0
593 
594     Otherwise, error() should be called to determine the cause of the
595     error.
596 */
connectToHost(const QHostAddress & address,quint16 port)597 bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 port)
598 {
599     Q_D(QNativeSocketEngine);
600     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::connectToHost(), false);
601 
602     if (!d->checkProxy(address))
603         return false;
604 
605     Q_CHECK_STATES3(QNativeSocketEngine::connectToHost(), QAbstractSocket::BoundState,
606                    QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false);
607 
608     d->peerAddress = address;
609     d->peerPort = port;
610     bool connected = d->nativeConnect(d->adjustAddressProtocol(address), port);
611     if (connected)
612         d->fetchConnectionParameters();
613 
614     return connected;
615 }
616 
617 /*!
618     If there's a connection activity on the socket, process it. Then
619     notify our parent if there really was activity.
620 */
connectionNotification()621 void QNativeSocketEngine::connectionNotification()
622 {
623     Q_D(QNativeSocketEngine);
624     Q_ASSERT(state() == QAbstractSocket::ConnectingState);
625 
626     connectToHost(d->peerAddress, d->peerPort);
627     if (state() != QAbstractSocket::ConnectingState) {
628         // we changed states
629         QAbstractSocketEngine::connectionNotification();
630     }
631 }
632 
633 /*!
634     Connects to the remote host name given by \a name on port \a
635     port. When this function is called, the upper-level will not
636     perform a hostname lookup.
637 
638     The native socket engine does not support this operation,
639     but some other socket engines (notably proxy-based ones) do.
640 */
connectToHostByName(const QString & name,quint16 port)641 bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
642 {
643     Q_UNUSED(name);
644     Q_UNUSED(port);
645     Q_D(QNativeSocketEngine);
646     d->setError(QAbstractSocket::UnsupportedSocketOperationError,
647                 QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
648     return false;
649 }
650 
651 /*!
652     Binds the socket to the address \a address and port \a
653     port. Returns \c true on success; otherwise false is returned. The
654     port may be 0, in which case an arbitrary unused port is assigned
655     automatically by the operating system.
656 
657     Servers call this function to set up the server's address and
658     port. TCP servers must in addition call listen() after bind().
659 */
bind(const QHostAddress & address,quint16 port)660 bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
661 {
662     Q_D(QNativeSocketEngine);
663     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bind(), false);
664 
665     if (!d->checkProxy(address))
666         return false;
667 
668     Q_CHECK_STATE(QNativeSocketEngine::bind(), QAbstractSocket::UnconnectedState, false);
669 
670     if (!d->nativeBind(d->adjustAddressProtocol(address), port))
671         return false;
672 
673     d->fetchConnectionParameters();
674     return true;
675 }
676 
677 /*!
678     Prepares a TCP server for accepting incoming connections. This
679     function must be called after bind(), and only by TCP sockets.
680 
681     After this function has been called, pending client connections
682     are detected by checking if the socket is ready for reading. This
683     can be done by either creating a QSocketNotifier, passing the
684     socket descriptor returned by socketDescriptor(), or by calling
685     the blocking function waitForRead().
686 
687     Example:
688     \snippet code/src_network_socket_qnativesocketengine.cpp 1
689 
690     \sa bind(), accept()
691 */
listen()692 bool QNativeSocketEngine::listen()
693 {
694     Q_D(QNativeSocketEngine);
695     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::listen(), false);
696     Q_CHECK_STATE(QNativeSocketEngine::listen(), QAbstractSocket::BoundState, false);
697 #ifndef QT_NO_SCTP
698     Q_CHECK_TYPES(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket,
699                   QAbstractSocket::SctpSocket, false);
700 #else
701     Q_CHECK_TYPE(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, false);
702 #endif
703 
704     // We're using a backlog of 50. Most modern kernels support TCP
705     // syncookies by default, and if they do, the backlog is ignored.
706     // When there is no support for TCP syncookies, this value is
707     // fine.
708     return d->nativeListen(50);
709 }
710 
711 /*!
712     Accepts a pending connection from the socket, which must be in
713     ListeningState, and returns its socket descriptor. If no pending
714     connections are available, -1 is returned.
715 
716     \sa bind(), listen()
717 */
accept()718 int QNativeSocketEngine::accept()
719 {
720     Q_D(QNativeSocketEngine);
721     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::accept(), -1);
722     Q_CHECK_STATE(QNativeSocketEngine::accept(), QAbstractSocket::ListeningState, -1);
723 #ifndef QT_NO_SCTP
724     Q_CHECK_TYPES(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket,
725                   QAbstractSocket::SctpSocket, -1);
726 #else
727     Q_CHECK_TYPE(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, -1);
728 #endif
729 
730     return d->nativeAccept();
731 }
732 
733 /*!
734     Returns the number of bytes that are currently available for
735     reading. On error, -1 is returned.
736 
737     For UDP sockets, this function returns the accumulated size of all
738     pending datagrams, and it is therefore more useful for UDP sockets
739     to call hasPendingDatagrams() and pendingDatagramSize().
740 */
bytesAvailable() const741 qint64 QNativeSocketEngine::bytesAvailable() const
742 {
743     Q_D(const QNativeSocketEngine);
744     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1);
745     Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, -1);
746 
747     return d->nativeBytesAvailable();
748 }
749 
750 #ifndef QT_NO_UDPSOCKET
751 #ifndef QT_NO_NETWORKINTERFACE
752 
753 /*!
754     \since 4.8
755 */
joinMulticastGroup(const QHostAddress & groupAddress,const QNetworkInterface & iface)756 bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress,
757                                              const QNetworkInterface &iface)
758 {
759     Q_D(QNativeSocketEngine);
760     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::joinMulticastGroup(), false);
761     Q_CHECK_STATE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::BoundState, false);
762     Q_CHECK_TYPE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::UdpSocket, false);
763 
764     // if the user binds a socket to an IPv6 address (or QHostAddress::Any) and
765     // then attempts to join an IPv4 multicast group, this won't work on
766     // Windows. In order to make this cross-platform, we warn & fail on all
767     // platforms.
768     if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol &&
769         (d->socketProtocol == QAbstractSocket::IPv6Protocol ||
770          d->socketProtocol == QAbstractSocket::AnyIPProtocol)) {
771         qWarning("QAbstractSocket: cannot bind to QHostAddress::Any (or an IPv6 address) and join an IPv4 multicast group;"
772                  " bind to QHostAddress::AnyIPv4 instead if you want to do this");
773         return false;
774     }
775 
776     return d->nativeJoinMulticastGroup(groupAddress, iface);
777 }
778 
779 /*!
780     \since 4.8
781 */
leaveMulticastGroup(const QHostAddress & groupAddress,const QNetworkInterface & iface)782 bool QNativeSocketEngine::leaveMulticastGroup(const QHostAddress &groupAddress,
783                                               const QNetworkInterface &iface)
784 {
785     Q_D(QNativeSocketEngine);
786     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::leaveMulticastGroup(), false);
787     Q_CHECK_STATE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::BoundState, false);
788     Q_CHECK_TYPE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::UdpSocket, false);
789     return d->nativeLeaveMulticastGroup(groupAddress, iface);
790 }
791 
792 /*!
793     \since 4.8
794 */
multicastInterface() const795 QNetworkInterface QNativeSocketEngine::multicastInterface() const
796 {
797     Q_D(const QNativeSocketEngine);
798     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::multicastInterface(), QNetworkInterface());
799     Q_CHECK_TYPE(QNativeSocketEngine::multicastInterface(), QAbstractSocket::UdpSocket, QNetworkInterface());
800     return d->nativeMulticastInterface();
801 }
802 
803 /*!
804     \since 4.8
805 */
setMulticastInterface(const QNetworkInterface & iface)806 bool QNativeSocketEngine::setMulticastInterface(const QNetworkInterface &iface)
807 {
808     Q_D(QNativeSocketEngine);
809     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setMulticastInterface(), false);
810     Q_CHECK_TYPE(QNativeSocketEngine::setMulticastInterface(), QAbstractSocket::UdpSocket, false);
811     return d->nativeSetMulticastInterface(iface);
812 }
813 
814 #endif // QT_NO_NETWORKINTERFACE
815 
816 /*!
817     Returns \c true if there is at least one datagram pending. This
818     function is only called by UDP sockets, where a datagram can have
819     a size of 0. TCP sockets call bytesAvailable().
820 */
hasPendingDatagrams() const821 bool QNativeSocketEngine::hasPendingDatagrams() const
822 {
823     Q_D(const QNativeSocketEngine);
824     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::hasPendingDatagrams(), false);
825     Q_CHECK_NOT_STATE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UnconnectedState, false);
826     Q_CHECK_TYPE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false);
827 
828     return d->nativeHasPendingDatagrams();
829 }
830 
831 /*!
832     Returns the size of the pending datagram, or -1 if no datagram is
833     pending. A datagram size of 0 is perfectly valid. This function is
834     called by UDP sockets before receiveMessage(). For TCP sockets,
835     call bytesAvailable().
836 */
pendingDatagramSize() const837 qint64 QNativeSocketEngine::pendingDatagramSize() const
838 {
839     Q_D(const QNativeSocketEngine);
840     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::pendingDatagramSize(), -1);
841     Q_CHECK_TYPE(QNativeSocketEngine::pendingDatagramSize(), QAbstractSocket::UdpSocket, -1);
842 
843     return d->nativePendingDatagramSize();
844 }
845 #endif // QT_NO_UDPSOCKET
846 
847 /*!
848     Reads up to \a maxSize bytes of a datagram from the socket,
849     stores it in \a data and returns the number of bytes read. The
850     address, port, and other IP header fields are stored in \a header
851     according to the request in \a options.
852 
853     For UDP sockets, to avoid unnecessarily loss of data, call
854     pendingDatagramSize() to determine the size of the pending message
855     before reading it. If \a maxSize is too small, the rest of the
856     datagram will be lost.
857 
858     Returns -1 if an error occurred.
859 
860     \sa hasPendingDatagrams()
861 */
readDatagram(char * data,qint64 maxSize,QIpPacketHeader * header,PacketHeaderOptions options)862 qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QIpPacketHeader *header,
863                                          PacketHeaderOptions options)
864 {
865     Q_D(QNativeSocketEngine);
866     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1);
867     Q_CHECK_STATES(QNativeSocketEngine::readDatagram(), QAbstractSocket::BoundState,
868                    QAbstractSocket::ConnectedState, -1);
869 
870     return d->nativeReceiveDatagram(data, maxSize, header, options);
871 }
872 
873 /*!
874     Writes a datagram of size \a size bytes to the socket from
875     \a data to the destination contained in \a header, and returns the
876     number of bytes written, or -1 if an error occurred. If \a header
877     contains other settings like hop limit or source address, this function
878     will try to pass them to the operating system too, but will not
879     indicate an error if it could not pass them.
880 
881     Only one datagram is sent, and if there is too much data to fit
882     into a single datagram, the operation will fail and error()
883     will return QAbstractSocket::DatagramTooLargeError. Operating systems impose an
884     upper limit to the size of a datagram, but this size is different
885     on almost all platforms. Sending large datagrams is in general
886     disadvised, as even if they are sent successfully, they are likely
887     to be fragmented before arriving at their destination.
888 
889     Experience has shown that it is in general safe to send IPv4 datagrams
890     no larger than 512 bytes or IPv6 datagrams no larger than 1280 (the
891     minimum MTU).
892 
893     \sa readDatagram()
894 */
writeDatagram(const char * data,qint64 size,const QIpPacketHeader & header)895 qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, const QIpPacketHeader &header)
896 {
897     Q_D(QNativeSocketEngine);
898     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1);
899     Q_CHECK_STATES(QNativeSocketEngine::writeDatagram(), QAbstractSocket::BoundState,
900                    QAbstractSocket::ConnectedState, -1);
901 
902     return d->nativeSendDatagram(data, size, header);
903 }
904 
905 /*!
906     Writes a block of \a size bytes from \a data to the socket.
907     Returns the number of bytes written, or -1 if an error occurred.
908 
909     Passing zero as the \a size parameter on a connected UDP socket
910     will send an empty datagram. For other socket types results are
911     unspecified.
912 */
write(const char * data,qint64 size)913 qint64 QNativeSocketEngine::write(const char *data, qint64 size)
914 {
915     Q_D(QNativeSocketEngine);
916     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::write(), -1);
917     Q_CHECK_STATE(QNativeSocketEngine::write(), QAbstractSocket::ConnectedState, -1);
918     return d->nativeWrite(data, size);
919 }
920 
921 
bytesToWrite() const922 qint64 QNativeSocketEngine::bytesToWrite() const
923 {
924     return 0;
925 }
926 
927 /*!
928     Reads up to \a maxSize bytes into \a data from the socket.
929     Returns the number of bytes read, or -1 if an error occurred.
930 */
read(char * data,qint64 maxSize)931 qint64 QNativeSocketEngine::read(char *data, qint64 maxSize)
932 {
933     Q_D(QNativeSocketEngine);
934     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::read(), -1);
935     Q_CHECK_STATES(QNativeSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1);
936 
937     qint64 readBytes = d->nativeRead(data, maxSize);
938 
939     // Handle remote close
940     if (readBytes == 0 && (d->socketType == QAbstractSocket::TcpSocket
941 #ifndef QT_NO_SCTP
942         || d->socketType == QAbstractSocket::SctpSocket
943 #endif
944         )) {
945         d->setError(QAbstractSocket::RemoteHostClosedError,
946                     QNativeSocketEnginePrivate::RemoteHostClosedErrorString);
947         close();
948         return -1;
949     } else if (readBytes == -1) {
950         if (!d->hasSetSocketError) {
951             d->hasSetSocketError = true;
952             d->socketError = QAbstractSocket::NetworkError;
953             d->socketErrorString = qt_error_string();
954         }
955         close();
956         return -1;
957     }
958     return readBytes;
959 }
960 
961 /*!
962     Closes the socket. In order to use the socket again, initialize()
963     must be called.
964 */
close()965 void QNativeSocketEngine::close()
966 {
967     Q_D(QNativeSocketEngine);
968     if (d->readNotifier)
969         d->readNotifier->setEnabled(false);
970     if (d->writeNotifier)
971         d->writeNotifier->setEnabled(false);
972     if (d->exceptNotifier)
973         d->exceptNotifier->setEnabled(false);
974 
975     if(d->socketDescriptor != -1) {
976         d->nativeClose();
977         d->socketDescriptor = -1;
978     }
979     d->socketState = QAbstractSocket::UnconnectedState;
980     d->hasSetSocketError = false;
981     d->localPort = 0;
982     d->localAddress.clear();
983     d->peerPort = 0;
984     d->peerAddress.clear();
985     d->inboundStreamCount = d->outboundStreamCount = 0;
986     if (d->readNotifier) {
987         qDeleteInEventHandler(d->readNotifier);
988         d->readNotifier = nullptr;
989     }
990     if (d->writeNotifier) {
991         qDeleteInEventHandler(d->writeNotifier);
992         d->writeNotifier = nullptr;
993     }
994     if (d->exceptNotifier) {
995         qDeleteInEventHandler(d->exceptNotifier);
996         d->exceptNotifier = nullptr;
997     }
998 }
999 
1000 /*!
1001     Waits for \a msecs milliseconds or until the socket is ready for
1002     reading. If \a timedOut is not \nullptr and \a msecs milliseconds
1003     have passed, the value of \a timedOut is set to true.
1004 
1005     Returns \c true if data is available for reading; otherwise returns
1006     false.
1007 
1008     This is a blocking function call; its use is disadvised in a
1009     single threaded application, as the whole thread will stop
1010     responding until the function returns. waitForRead() is most
1011     useful when there is no event loop available. The general approach
1012     is to create a QSocketNotifier, passing the socket descriptor
1013     returned by socketDescriptor() to its constructor.
1014 */
waitForRead(int msecs,bool * timedOut)1015 bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
1016 {
1017     Q_D(const QNativeSocketEngine);
1018     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false);
1019     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(),
1020                       QAbstractSocket::UnconnectedState, false);
1021 
1022     if (timedOut)
1023         *timedOut = false;
1024 
1025     int ret = d->nativeSelect(msecs, true);
1026     if (ret == 0) {
1027         if (timedOut)
1028             *timedOut = true;
1029         d->setError(QAbstractSocket::SocketTimeoutError,
1030             QNativeSocketEnginePrivate::TimeOutErrorString);
1031         d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
1032         return false;
1033     } else if (state() == QAbstractSocket::ConnectingState) {
1034         connectToHost(d->peerAddress, d->peerPort);
1035     }
1036 
1037     return ret > 0;
1038 }
1039 
1040 /*!
1041     Waits for \a msecs milliseconds or until the socket is ready for
1042     writing. If \a timedOut is not \nullptr and \a msecs milliseconds
1043     have passed, the value of \a timedOut is set to true.
1044 
1045     Returns \c true if data is available for writing; otherwise returns
1046     false.
1047 
1048     This is a blocking function call; its use is disadvised in a
1049     single threaded application, as the whole thread will stop
1050     responding until the function returns. waitForWrite() is most
1051     useful when there is no event loop available. The general approach
1052     is to create a QSocketNotifier, passing the socket descriptor
1053     returned by socketDescriptor() to its constructor.
1054 */
waitForWrite(int msecs,bool * timedOut)1055 bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
1056 {
1057     Q_D(QNativeSocketEngine);
1058     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
1059     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(),
1060                       QAbstractSocket::UnconnectedState, false);
1061 
1062     if (timedOut)
1063         *timedOut = false;
1064 
1065     int ret = d->nativeSelect(msecs, false);
1066     // On Windows, the socket is in connected state if a call to
1067     // select(writable) is successful. In this case we should not
1068     // issue a second call to WSAConnect()
1069 #if defined (Q_OS_WIN)
1070     if (state() == QAbstractSocket::ConnectingState) {
1071         if (ret > 0) {
1072             setState(QAbstractSocket::ConnectedState);
1073             d_func()->fetchConnectionParameters();
1074             return true;
1075         } else {
1076             int value = 0;
1077             int valueSize = sizeof(value);
1078             if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
1079                 if (value == WSAECONNREFUSED) {
1080                     d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
1081                     d->socketState = QAbstractSocket::UnconnectedState;
1082                     return false;
1083                 } else if (value == WSAETIMEDOUT) {
1084                     d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
1085                     d->socketState = QAbstractSocket::UnconnectedState;
1086                     return false;
1087                 } else if (value == WSAEHOSTUNREACH) {
1088                     d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
1089                     d->socketState = QAbstractSocket::UnconnectedState;
1090                     return false;
1091                 }
1092             }
1093         }
1094     }
1095 #endif
1096 
1097     if (ret == 0) {
1098         if (timedOut)
1099             *timedOut = true;
1100         d->setError(QAbstractSocket::SocketTimeoutError,
1101                     QNativeSocketEnginePrivate::TimeOutErrorString);
1102         d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
1103         return false;
1104     } else if (state() == QAbstractSocket::ConnectingState || (state() == QAbstractSocket::BoundState && d->socketDescriptor != -1)) {
1105         connectToHost(d->peerAddress, d->peerPort);
1106     }
1107 
1108     return ret > 0;
1109 }
1110 
waitForReadOrWrite(bool * readyToRead,bool * readyToWrite,bool checkRead,bool checkWrite,int msecs,bool * timedOut)1111 bool QNativeSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
1112                                       bool checkRead, bool checkWrite,
1113                                       int msecs, bool *timedOut)
1114 {
1115     Q_D(QNativeSocketEngine);
1116     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForReadOrWrite(), false);
1117     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(),
1118                       QAbstractSocket::UnconnectedState, false);
1119 
1120     int ret = d->nativeSelect(msecs, checkRead, checkWrite, readyToRead, readyToWrite);
1121     // On Windows, the socket is in connected state if a call to
1122     // select(writable) is successful. In this case we should not
1123     // issue a second call to WSAConnect()
1124 #if defined (Q_OS_WIN)
1125     if (state() == QAbstractSocket::ConnectingState) {
1126         if (checkWrite && ((readyToWrite && *readyToWrite) || !readyToWrite) && ret > 0) {
1127             setState(QAbstractSocket::ConnectedState);
1128             d_func()->fetchConnectionParameters();
1129             return true;
1130         } else {
1131             int value = 0;
1132             int valueSize = sizeof(value);
1133             if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
1134                 if (value == WSAECONNREFUSED) {
1135                     d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
1136                     d->socketState = QAbstractSocket::UnconnectedState;
1137                     return false;
1138                 } else if (value == WSAETIMEDOUT) {
1139                     d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
1140                     d->socketState = QAbstractSocket::UnconnectedState;
1141                     return false;
1142                 } else if (value == WSAEHOSTUNREACH) {
1143                     d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
1144                     d->socketState = QAbstractSocket::UnconnectedState;
1145                     return false;
1146                 }
1147             }
1148         }
1149     }
1150 #endif
1151     if (ret == 0) {
1152         if (timedOut)
1153             *timedOut = true;
1154         d->setError(QAbstractSocket::SocketTimeoutError,
1155                     QNativeSocketEnginePrivate::TimeOutErrorString);
1156         d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
1157         return false;
1158     } else if (state() == QAbstractSocket::ConnectingState) {
1159         connectToHost(d->peerAddress, d->peerPort);
1160     }
1161 
1162     return ret > 0;
1163 }
1164 
1165 #if 0   // currently unused
1166 /*
1167     Returns the size of the operating system's socket receive
1168     buffer. Depending on the operating system, this size may be
1169     different from what has been set earlier with
1170     setReceiveBufferSize().
1171 */
1172 qint64 QNativeSocketEngine::receiveBufferSize() const
1173 {
1174     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::receiveBufferSize(), -1);
1175     return option(ReceiveBufferSocketOption);
1176 }
1177 
1178 /*
1179     Sets the size of the operating system receive buffer to \a size.
1180 
1181     For clients, this should be set before connectToHost() is called;
1182     otherwise it will have no effect. For servers, it should be called
1183     before listen().
1184 
1185     The operating system receive buffer size effectively limits two
1186     things: how much data can be in transit at any one moment, and how
1187     much data can be received in one iteration of the main event loop.
1188     Setting the size of the receive buffer may have an impact on the
1189     socket's performance.
1190 
1191     The default value is operating system-dependent.
1192 */
1193 void QNativeSocketEngine::setReceiveBufferSize(qint64 size)
1194 {
1195     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setReceiveBufferSize(), Q_VOID);
1196     setOption(ReceiveBufferSocketOption, size);
1197 }
1198 
1199 /*
1200     Returns the size of the operating system send buffer. Depending on
1201     the operating system, this size may be different from what has
1202     been set earlier with setSendBufferSize().
1203 */
1204 qint64 QNativeSocketEngine::sendBufferSize() const
1205 {
1206     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), -1);
1207     return option(SendBufferSocketOption);
1208 }
1209 
1210 /*
1211     Sets the size of the operating system send buffer to \a size.
1212 
1213     The operating system send buffer size effectively limits how much
1214     data can be in transit at any one moment. Setting the size of the
1215     send buffer may have an impact on the socket's performance.
1216 
1217     The default value is operating system-dependent.
1218 */
1219 void QNativeSocketEngine::setSendBufferSize(qint64 size)
1220 {
1221     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), Q_VOID);
1222     setOption(SendBufferSocketOption, size);
1223 }
1224 #endif
1225 
1226 /*!
1227     Sets the option \a option to the value \a value.
1228 */
setOption(SocketOption option,int value)1229 bool QNativeSocketEngine::setOption(SocketOption option, int value)
1230 {
1231     Q_D(QNativeSocketEngine);
1232     return d->setOption(option, value);
1233 }
1234 
1235 /*!
1236     Returns the value of the option \a socketOption.
1237 */
option(SocketOption socketOption) const1238 int QNativeSocketEngine::option(SocketOption socketOption) const
1239 {
1240     Q_D(const QNativeSocketEngine);
1241     return d->option(socketOption);
1242 }
1243 
isReadNotificationEnabled() const1244 bool QNativeSocketEngine::isReadNotificationEnabled() const
1245 {
1246     Q_D(const QNativeSocketEngine);
1247     return d->readNotifier && d->readNotifier->isEnabled();
1248 }
1249 
1250 /*
1251   \internal
1252   \class QReadNotifier
1253   \brief The QReadNotifer class is used to improve performance.
1254 
1255   QReadNotifier is a private class used for performance reasons vs
1256   connecting to the QSocketNotifier activated() signal.
1257  */
1258 class QReadNotifier : public QSocketNotifier
1259 {
1260 public:
QReadNotifier(qintptr fd,QNativeSocketEngine * parent)1261     QReadNotifier(qintptr fd, QNativeSocketEngine *parent)
1262         : QSocketNotifier(fd, QSocketNotifier::Read, parent)
1263     { engine = parent; }
1264 
1265 protected:
1266     bool event(QEvent *) override;
1267 
1268     QNativeSocketEngine *engine;
1269 };
1270 
event(QEvent * e)1271 bool QReadNotifier::event(QEvent *e)
1272 {
1273     if (e->type() == QEvent::SockAct) {
1274         engine->readNotification();
1275         return true;
1276     } else if (e->type() == QEvent::SockClose) {
1277         engine->closeNotification();
1278         return true;
1279     }
1280     return QSocketNotifier::event(e);
1281 }
1282 
1283 /*
1284   \internal
1285   \class QWriteNotifier
1286   \brief The QWriteNotifer class is used to improve performance.
1287 
1288   QWriteNotifier is a private class used for performance reasons vs
1289   connecting to the QSocketNotifier activated() signal.
1290  */
1291 class QWriteNotifier : public QSocketNotifier
1292 {
1293 public:
QWriteNotifier(int fd,QNativeSocketEngine * parent)1294     QWriteNotifier(int fd, QNativeSocketEngine *parent)
1295         : QSocketNotifier(fd, QSocketNotifier::Write, parent) { engine = parent; }
1296 
1297 protected:
1298     bool event(QEvent *) override;
1299 
1300     QNativeSocketEngine *engine;
1301 };
1302 
event(QEvent * e)1303 bool QWriteNotifier::event(QEvent *e)
1304 {
1305     if (e->type() == QEvent::SockAct) {
1306         if (engine->state() == QAbstractSocket::ConnectingState)
1307             engine->connectionNotification();
1308         else
1309             engine->writeNotification();
1310         return true;
1311     }
1312     return QSocketNotifier::event(e);
1313 }
1314 
1315 class QExceptionNotifier : public QSocketNotifier
1316 {
1317 public:
QExceptionNotifier(int fd,QNativeSocketEngine * parent)1318     QExceptionNotifier(int fd, QNativeSocketEngine *parent)
1319         : QSocketNotifier(fd, QSocketNotifier::Exception, parent) { engine = parent; }
1320 
1321 protected:
1322     bool event(QEvent *) override;
1323 
1324     QNativeSocketEngine *engine;
1325 };
1326 
event(QEvent * e)1327 bool QExceptionNotifier::event(QEvent *e)
1328 {
1329     if (e->type() == QEvent::SockAct) {
1330         if (engine->state() == QAbstractSocket::ConnectingState)
1331             engine->connectionNotification();
1332         else
1333             engine->exceptionNotification();
1334         return true;
1335     }
1336     return QSocketNotifier::event(e);
1337 }
1338 
setReadNotificationEnabled(bool enable)1339 void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
1340 {
1341     Q_D(QNativeSocketEngine);
1342     if (d->readNotifier) {
1343         d->readNotifier->setEnabled(enable);
1344     } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
1345         d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
1346         d->readNotifier->setEnabled(true);
1347     }
1348 }
1349 
isWriteNotificationEnabled() const1350 bool QNativeSocketEngine::isWriteNotificationEnabled() const
1351 {
1352     Q_D(const QNativeSocketEngine);
1353     return d->writeNotifier && d->writeNotifier->isEnabled();
1354 }
1355 
setWriteNotificationEnabled(bool enable)1356 void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
1357 {
1358     Q_D(QNativeSocketEngine);
1359     if (d->writeNotifier) {
1360         d->writeNotifier->setEnabled(enable);
1361     } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
1362         d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
1363         d->writeNotifier->setEnabled(true);
1364     }
1365 }
1366 
isExceptionNotificationEnabled() const1367 bool QNativeSocketEngine::isExceptionNotificationEnabled() const
1368 {
1369     Q_D(const QNativeSocketEngine);
1370     return d->exceptNotifier && d->exceptNotifier->isEnabled();
1371 }
1372 
setExceptionNotificationEnabled(bool enable)1373 void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
1374 {
1375     Q_D(QNativeSocketEngine);
1376     if (d->exceptNotifier) {
1377         d->exceptNotifier->setEnabled(enable);
1378     } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
1379         d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
1380         d->exceptNotifier->setEnabled(true);
1381     }
1382 }
1383 
1384 QT_END_NAMESPACE
1385