1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtNetwork module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QNATIVESOCKETENGINE_P_H 43 #define QNATIVESOCKETENGINE_P_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists for the convenience 50 // of the QLibrary class. This header file may change from 51 // version to version without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 #include "QtNetwork/qhostaddress.h" 56 #include "private/qabstractsocketengine_p.h" 57 #ifndef Q_OS_WIN 58 # include "qplatformdefs.h" 59 #else 60 # include <winsock2.h> 61 #endif 62 63 QT_BEGIN_NAMESPACE 64 65 // Use our own defines and structs which we know are correct 66 # define QT_SS_MAXSIZE 128 67 # define QT_SS_ALIGNSIZE (sizeof(qint64)) 68 # define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short)) 69 # define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE)) 70 struct qt_sockaddr_storage { 71 short ss_family; 72 char __ss_pad1[QT_SS_PAD1SIZE]; 73 qint64 __ss_align; 74 char __ss_pad2[QT_SS_PAD2SIZE]; 75 }; 76 77 // sockaddr_in6 size changed between old and new SDK 78 // Only the new version is the correct one, so always 79 // use this structure. 80 struct qt_in6_addr { 81 quint8 qt_s6_addr[16]; 82 }; 83 struct qt_sockaddr_in6 { 84 short sin6_family; /* AF_INET6 */ 85 quint16 sin6_port; /* Transport level port number */ 86 quint32 sin6_flowinfo; /* IPv6 flow information */ 87 struct qt_in6_addr sin6_addr; /* IPv6 address */ 88 quint32 sin6_scope_id; /* set of interfaces for a scope */ 89 }; 90 91 union qt_sockaddr { 92 sockaddr a; 93 sockaddr_in a4; 94 qt_sockaddr_in6 a6; 95 qt_sockaddr_storage storage; 96 }; 97 98 class QNativeSocketEnginePrivate; 99 #ifndef QT_NO_NETWORKINTERFACE 100 class QNetworkInterface; 101 #endif 102 103 class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine 104 { 105 Q_OBJECT 106 public: 107 QNativeSocketEngine(QObject *parent = 0); 108 ~QNativeSocketEngine(); 109 110 bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol); 111 bool initialize(int socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState); 112 113 int socketDescriptor() const; 114 115 bool isValid() const; 116 117 bool connectToHost(const QHostAddress &address, quint16 port); 118 bool connectToHostByName(const QString &name, quint16 port); 119 bool bind(const QHostAddress &address, quint16 port); 120 bool listen(); 121 int accept(); 122 void close(); 123 124 #ifndef QT_NO_NETWORKINTERFACE 125 bool joinMulticastGroup(const QHostAddress &groupAddress, 126 const QNetworkInterface &iface); 127 bool leaveMulticastGroup(const QHostAddress &groupAddress, 128 const QNetworkInterface &iface); 129 QNetworkInterface multicastInterface() const; 130 bool setMulticastInterface(const QNetworkInterface &iface); 131 #endif 132 133 qint64 bytesAvailable() const; 134 135 qint64 read(char *data, qint64 maxlen); 136 qint64 write(const char *data, qint64 len); 137 138 qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0, 139 quint16 *port = 0); 140 qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr, 141 quint16 port); 142 bool hasPendingDatagrams() const; 143 qint64 pendingDatagramSize() const; 144 145 qint64 bytesToWrite() const; 146 147 qint64 receiveBufferSize() const; 148 void setReceiveBufferSize(qint64 bufferSize); 149 150 qint64 sendBufferSize() const; 151 void setSendBufferSize(qint64 bufferSize); 152 153 int option(SocketOption option) const; 154 bool setOption(SocketOption option, int value); 155 156 bool waitForRead(int msecs = 30000, bool *timedOut = 0); 157 bool waitForWrite(int msecs = 30000, bool *timedOut = 0); 158 bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, 159 bool checkRead, bool checkWrite, 160 int msecs = 30000, bool *timedOut = 0); 161 162 bool isReadNotificationEnabled() const; 163 void setReadNotificationEnabled(bool enable); 164 bool isWriteNotificationEnabled() const; 165 void setWriteNotificationEnabled(bool enable); 166 bool isExceptionNotificationEnabled() const; 167 void setExceptionNotificationEnabled(bool enable); 168 169 public Q_SLOTS: 170 // non-virtual override; 171 void connectionNotification(); 172 173 private: 174 Q_DECLARE_PRIVATE(QNativeSocketEngine) 175 Q_DISABLE_COPY(QNativeSocketEngine) 176 }; 177 178 #ifdef Q_OS_WIN 179 class QWindowsSockInit 180 { 181 public: 182 QWindowsSockInit(); 183 ~QWindowsSockInit(); 184 int version; 185 }; 186 #endif 187 188 class QSocketNotifier; 189 190 class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate 191 { 192 Q_DECLARE_PUBLIC(QNativeSocketEngine) 193 public: 194 QNativeSocketEnginePrivate(); 195 ~QNativeSocketEnginePrivate(); 196 197 int socketDescriptor; 198 199 QSocketNotifier *readNotifier, *writeNotifier, *exceptNotifier; 200 201 #ifdef Q_OS_WIN 202 QWindowsSockInit winSock; 203 #endif 204 205 enum ErrorString { 206 NonBlockingInitFailedErrorString, 207 BroadcastingInitFailedErrorString, 208 NoIpV6ErrorString, 209 RemoteHostClosedErrorString, 210 TimeOutErrorString, 211 ResourceErrorString, 212 OperationUnsupportedErrorString, 213 ProtocolUnsupportedErrorString, 214 InvalidSocketErrorString, 215 HostUnreachableErrorString, 216 NetworkUnreachableErrorString, 217 AccessErrorString, 218 ConnectionTimeOutErrorString, 219 ConnectionRefusedErrorString, 220 AddressInuseErrorString, 221 AddressNotAvailableErrorString, 222 AddressProtectedErrorString, 223 DatagramTooLargeErrorString, 224 SendDatagramErrorString, 225 ReceiveDatagramErrorString, 226 WriteErrorString, 227 ReadErrorString, 228 PortInuseErrorString, 229 NotSocketErrorString, 230 InvalidProxyTypeString, 231 232 UnknownSocketErrorString = -1 233 }; 234 235 void setError(QAbstractSocket::SocketError error, ErrorString errorString) const; 236 237 // native functions 238 int option(QNativeSocketEngine::SocketOption option) const; 239 bool setOption(QNativeSocketEngine::SocketOption option, int value); 240 241 bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol); 242 243 bool nativeConnect(const QHostAddress &address, quint16 port); 244 bool nativeBind(const QHostAddress &address, quint16 port); 245 bool nativeListen(int backlog); 246 int nativeAccept(); 247 #ifndef QT_NO_NETWORKINTERFACE 248 bool nativeJoinMulticastGroup(const QHostAddress &groupAddress, 249 const QNetworkInterface &iface); 250 bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress, 251 const QNetworkInterface &iface); 252 QNetworkInterface nativeMulticastInterface() const; 253 bool nativeSetMulticastInterface(const QNetworkInterface &iface); 254 #endif 255 qint64 nativeBytesAvailable() const; 256 257 bool nativeHasPendingDatagrams() const; 258 qint64 nativePendingDatagramSize() const; 259 qint64 nativeReceiveDatagram(char *data, qint64 maxLength, 260 QHostAddress *address, quint16 *port); 261 qint64 nativeSendDatagram(const char *data, qint64 length, 262 const QHostAddress &host, quint16 port); 263 qint64 nativeRead(char *data, qint64 maxLength); 264 qint64 nativeWrite(const char *data, qint64 length); 265 int nativeSelect(int timeout, bool selectForRead) const; 266 int nativeSelect(int timeout, bool checkRead, bool checkWrite, 267 bool *selectForRead, bool *selectForWrite) const; 268 269 void nativeClose(); 270 271 bool checkProxy(const QHostAddress &address); 272 bool fetchConnectionParameters(); 273 }; 274 275 QT_END_NAMESPACE 276 277 #endif // QNATIVESOCKETENGINE_P_H 278