1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/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 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
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
63QT_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))
70struct 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.
80struct qt_in6_addr {
81 quint8 qt_s6_addr[16];
82};
83struct 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
91union qt_sockaddr {
92 sockaddr a;
93 sockaddr_in a4;
94 qt_sockaddr_in6 a6;
95 qt_sockaddr_storage storage;
96};
97
98class QNativeSocketEnginePrivate;
99#ifndef QT_NO_NETWORKINTERFACE
100class QNetworkInterface;
101#endif
102
103class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
104{
105 Q_OBJECT
106public:
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
169public Q_SLOTS:
170 // non-virtual override;
171 void connectionNotification();
172
173private:
174 Q_DECLARE_PRIVATE(QNativeSocketEngine)
175 Q_DISABLE_COPY(QNativeSocketEngine)
176};
177
178#ifdef Q_OS_WIN
179class QWindowsSockInit
180{
181public:
182 QWindowsSockInit();
183 ~QWindowsSockInit();
184 int version;
185};
186#endif
187
188class QSocketNotifier;
189
190class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
191{
192 Q_DECLARE_PUBLIC(QNativeSocketEngine)
193public:
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
275QT_END_NAMESPACE
276
277#endif // QNATIVESOCKETENGINE_P_H
278