summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/socket/qnativesocketengine_p.h')
-rw-r--r--src/network/socket/qnativesocketengine_p.h222
1 files changed, 56 insertions, 166 deletions
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index a9c6da1977..4c185b7a4a 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -20,8 +20,9 @@
#include "QtNetwork/qhostaddress.h"
#include "QtNetwork/qnetworkinterface.h"
#include "private/qabstractsocketengine_p.h"
+#include "qplatformdefs.h"
+
#ifndef Q_OS_WIN
-# include "qplatformdefs.h"
# include <netinet/in.h>
#else
# include <winsock2.h>
@@ -34,51 +35,63 @@ QT_BEGIN_NAMESPACE
#ifdef Q_OS_WIN
# define QT_SOCKLEN_T int
# define QT_SOCKOPTLEN_T int
-
-// The following definitions are copied from the MinGW header mswsock.h which
-// was placed in the public domain. The WSASendMsg and WSARecvMsg functions
-// were introduced with Windows Vista, so some Win32 headers are lacking them.
-// There are no known versions of Windows CE or Embedded that contain them.
-# ifndef WSAID_WSARECVMSG
-typedef INT (WINAPI *LPFN_WSARECVMSG)(SOCKET s, LPWSAMSG lpMsg,
- LPDWORD lpdwNumberOfBytesRecvd,
- LPWSAOVERLAPPED lpOverlapped,
- LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
-# define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}
-# endif // !WSAID_WSARECVMSG
-# ifndef WSAID_WSASENDMSG
-typedef struct {
- LPWSAMSG lpMsg;
- DWORD dwFlags;
- LPDWORD lpNumberOfBytesSent;
- LPWSAOVERLAPPED lpOverlapped;
- LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
-} WSASENDMSG, *LPWSASENDMSG;
-
-typedef INT (WSAAPI *LPFN_WSASENDMSG)(SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags,
- LPDWORD lpNumberOfBytesSent,
- LPWSAOVERLAPPED lpOverlapped,
- LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
-
-# define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}}
-# endif // !WSAID_WSASENDMSG
-#endif // Q_OS_WIN
-
-union qt_sockaddr {
- sockaddr a;
- sockaddr_in a4;
- sockaddr_in6 a6;
-};
+#endif
namespace {
namespace SetSALen {
template <typename T> void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type len)
{ sa->sa_len = len; }
+ template <typename T> void set(T *sa, typename std::enable_if<(&T::sin_len, true), QT_SOCKLEN_T>::type len)
+ { sa->sin_len = len; }
template <typename T> void set(T *sin6, typename std::enable_if<(&T::sin6_len, true), QT_SOCKLEN_T>::type len)
{ sin6->sin6_len = len; }
template <typename T> void set(T *, ...) {}
}
+
+inline QT_SOCKLEN_T setSockaddr(sockaddr_in *sin, const QHostAddress &addr, quint16 port = 0)
+{
+ *sin = {};
+ SetSALen::set(sin, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons(port);
+ sin->sin_addr.s_addr = htonl(addr.toIPv4Address());
+ return sizeof(*sin);
+}
+
+inline QT_SOCKLEN_T setSockaddr(sockaddr_in6 *sin6, const QHostAddress &addr, quint16 port = 0)
+{
+ *sin6 = {};
+ SetSALen::set(sin6, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons(port);
+ memcpy(sin6->sin6_addr.s6_addr, addr.toIPv6Address().c, sizeof(sin6->sin6_addr));
+#if QT_CONFIG(networkinterface)
+ sin6->sin6_scope_id = QNetworkInterface::interfaceIndexFromName(addr.scopeId());
+#else
+ // it had better be a number then, if it is not empty
+ sin6->sin6_scope_id = addr.scopeId().toUInt();
+#endif
+ return sizeof(*sin6);
+}
+
+inline QT_SOCKLEN_T setSockaddr(sockaddr *sa, const QHostAddress &addr, quint16 port = 0)
+{
+ switch (addr.protocol()) {
+ case QHostAddress::IPv4Protocol:
+ return setSockaddr(reinterpret_cast<sockaddr_in *>(sa), addr, port);
+
+ case QHostAddress::IPv6Protocol:
+ case QHostAddress::AnyIPProtocol:
+ return setSockaddr(reinterpret_cast<sockaddr_in6 *>(sa), addr, port);
+
+ case QHostAddress::UnknownNetworkLayerProtocol:
+ break;
+ }
+ *sa = {};
+ sa->sa_family = AF_UNSPEC;
+ return 0;
}
+} // unnamed namespace
class QNativeSocketEnginePrivate;
#ifndef QT_NO_NETWORKINTERFACE
@@ -103,7 +116,7 @@ public:
bool connectToHostByName(const QString &name, quint16 port) override;
bool bind(const QHostAddress &address, quint16 port) override;
bool listen(int backlog) override;
- int accept() override;
+ qintptr accept() override;
void close() override;
qint64 bytesAvailable() const override;
@@ -141,11 +154,14 @@ public:
int option(SocketOption option) const override;
bool setOption(SocketOption option, int value) override;
- bool waitForRead(int msecs = 30000, bool *timedOut = nullptr) override;
- bool waitForWrite(int msecs = 30000, bool *timedOut = nullptr) override;
+ bool waitForRead(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
+ bool *timedOut = nullptr) override;
+ bool waitForWrite(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
+ bool *timedOut = nullptr) override;
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
bool checkRead, bool checkWrite,
- int msecs = 30000, bool *timedOut = nullptr) override;
+ QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
+ bool *timedOut = nullptr) override;
bool isReadNotificationEnabled() const override;
void setReadNotificationEnabled(bool enable) override;
@@ -163,132 +179,6 @@ private:
Q_DISABLE_COPY_MOVE(QNativeSocketEngine)
};
-class QSocketNotifier;
-
-class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
-{
- Q_DECLARE_PUBLIC(QNativeSocketEngine)
-public:
- QNativeSocketEnginePrivate();
- ~QNativeSocketEnginePrivate();
-
- qintptr socketDescriptor;
-
- QSocketNotifier *readNotifier, *writeNotifier, *exceptNotifier;
-
-#if defined(Q_OS_WIN)
- LPFN_WSASENDMSG sendmsg;
- LPFN_WSARECVMSG recvmsg;
-# endif
- enum ErrorString {
- NonBlockingInitFailedErrorString,
- BroadcastingInitFailedErrorString,
- NoIpV6ErrorString,
- RemoteHostClosedErrorString,
- TimeOutErrorString,
- ResourceErrorString,
- OperationUnsupportedErrorString,
- ProtocolUnsupportedErrorString,
- InvalidSocketErrorString,
- HostUnreachableErrorString,
- NetworkUnreachableErrorString,
- AccessErrorString,
- ConnectionTimeOutErrorString,
- ConnectionRefusedErrorString,
- AddressInuseErrorString,
- AddressNotAvailableErrorString,
- AddressProtectedErrorString,
- DatagramTooLargeErrorString,
- SendDatagramErrorString,
- ReceiveDatagramErrorString,
- WriteErrorString,
- ReadErrorString,
- PortInuseErrorString,
- NotSocketErrorString,
- InvalidProxyTypeString,
- TemporaryErrorString,
- NetworkDroppedConnectionErrorString,
- ConnectionResetErrorString,
-
- UnknownSocketErrorString = -1
- };
-
- void setError(QAbstractSocket::SocketError error, ErrorString errorString) const;
- QHostAddress adjustAddressProtocol(const QHostAddress &address) const;
-
- // native functions
- int option(QNativeSocketEngine::SocketOption option) const;
- bool setOption(QNativeSocketEngine::SocketOption option, int value);
-
- bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol);
-
- bool nativeConnect(const QHostAddress &address, quint16 port);
- bool nativeBind(const QHostAddress &address, quint16 port);
- bool nativeListen(int backlog);
- int nativeAccept();
-#ifndef QT_NO_NETWORKINTERFACE
- bool nativeJoinMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &iface);
- bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &iface);
- QNetworkInterface nativeMulticastInterface() const;
- bool nativeSetMulticastInterface(const QNetworkInterface &iface);
-#endif
- qint64 nativeBytesAvailable() const;
-
- bool nativeHasPendingDatagrams() const;
- qint64 nativePendingDatagramSize() const;
- qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
- QAbstractSocketEngine::PacketHeaderOptions options);
- qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header);
- qint64 nativeRead(char *data, qint64 maxLength);
- qint64 nativeWrite(const char *data, qint64 length);
- int nativeSelect(int timeout, bool selectForRead) const;
- int nativeSelect(int timeout, bool checkRead, bool checkWrite,
- bool *selectForRead, bool *selectForWrite) const;
-
- void nativeClose();
-
- bool checkProxy(const QHostAddress &address);
- bool fetchConnectionParameters();
-
-#if QT_CONFIG(networkinterface)
- static uint scopeIdFromString(const QString &scopeid)
- { return QNetworkInterface::interfaceIndexFromName(scopeid); }
-#endif
-
- /*! \internal
- Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
- The address \a is converted to IPv6 if the current socket protocol is also IPv6.
- */
- void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
- {
- if (address.protocol() == QAbstractSocket::IPv6Protocol
- || address.protocol() == QAbstractSocket::AnyIPProtocol
- || socketProtocol == QAbstractSocket::IPv6Protocol
- || socketProtocol == QAbstractSocket::AnyIPProtocol) {
- memset(&aa->a6, 0, sizeof(sockaddr_in6));
- aa->a6.sin6_family = AF_INET6;
-#if QT_CONFIG(networkinterface)
- aa->a6.sin6_scope_id = scopeIdFromString(address.scopeId());
-#endif
- aa->a6.sin6_port = htons(port);
- Q_IPV6ADDR tmp = address.toIPv6Address();
- memcpy(&aa->a6.sin6_addr, &tmp, sizeof(tmp));
- *sockAddrSize = sizeof(sockaddr_in6);
- SetSALen::set(&aa->a, sizeof(sockaddr_in6));
- } else {
- memset(&aa->a, 0, sizeof(sockaddr_in));
- aa->a4.sin_family = AF_INET;
- aa->a4.sin_port = htons(port);
- aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
- *sockAddrSize = sizeof(sockaddr_in);
- SetSALen::set(&aa->a, sizeof(sockaddr_in));
- }
- }
-
-};
-
QT_END_NAMESPACE
#endif // QNATIVESOCKETENGINE_P_H