diff options
Diffstat (limited to 'src/network/socket/qnativesocketengine_p.h')
-rw-r--r-- | src/network/socket/qnativesocketengine_p.h | 222 |
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 |