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