1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://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 https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qabstractsocketengine_p.h"
41 
42 #ifndef Q_OS_WINRT
43 #include "qnativesocketengine_p.h"
44 #else
45 #include "qnativesocketengine_winrt_p.h"
46 #endif
47 
48 #include "qmutex.h"
49 #include "qnetworkproxy.h"
50 
51 QT_BEGIN_NAMESPACE
52 
53 class QSocketEngineHandlerList : public QList<QSocketEngineHandler*>
54 {
55 public:
56     QMutex mutex;
57 };
58 
Q_GLOBAL_STATIC(QSocketEngineHandlerList,socketHandlers)59 Q_GLOBAL_STATIC(QSocketEngineHandlerList, socketHandlers)
60 
61 QSocketEngineHandler::QSocketEngineHandler()
62 {
63     if (!socketHandlers())
64         return;
65     QMutexLocker locker(&socketHandlers()->mutex);
66     socketHandlers()->prepend(this);
67 }
68 
~QSocketEngineHandler()69 QSocketEngineHandler::~QSocketEngineHandler()
70 {
71     if (!socketHandlers())
72         return;
73     QMutexLocker locker(&socketHandlers()->mutex);
74     socketHandlers()->removeAll(this);
75 }
76 
QAbstractSocketEnginePrivate()77 QAbstractSocketEnginePrivate::QAbstractSocketEnginePrivate()
78     : socketError(QAbstractSocket::UnknownSocketError)
79     , hasSetSocketError(false)
80     , socketErrorString(QLatin1String(QT_TRANSLATE_NOOP(QSocketLayer, "Unknown error")))
81     , socketState(QAbstractSocket::UnconnectedState)
82     , socketType(QAbstractSocket::UnknownSocketType)
83     , socketProtocol(QAbstractSocket::UnknownNetworkLayerProtocol)
84     , localPort(0)
85     , peerPort(0)
86     , inboundStreamCount(0)
87     , outboundStreamCount(0)
88     , receiver(nullptr)
89 {
90 }
91 
QAbstractSocketEngine(QObject * parent)92 QAbstractSocketEngine::QAbstractSocketEngine(QObject *parent)
93     : QObject(*new QAbstractSocketEnginePrivate(), parent)
94 {
95 }
96 
QAbstractSocketEngine(QAbstractSocketEnginePrivate & dd,QObject * parent)97 QAbstractSocketEngine::QAbstractSocketEngine(QAbstractSocketEnginePrivate &dd, QObject* parent)
98     : QObject(dd, parent)
99 {
100 }
101 
createSocketEngine(QAbstractSocket::SocketType socketType,const QNetworkProxy & proxy,QObject * parent)102 QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &proxy, QObject *parent)
103 {
104 #ifndef QT_NO_NETWORKPROXY
105     // proxy type must have been resolved by now
106     if (proxy.type() == QNetworkProxy::DefaultProxy)
107         return nullptr;
108 #endif
109 
110     QMutexLocker locker(&socketHandlers()->mutex);
111     for (int i = 0; i < socketHandlers()->size(); i++) {
112         if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketType, proxy, parent))
113             return ret;
114     }
115 
116 #ifndef QT_NO_NETWORKPROXY
117     // only NoProxy can have reached here
118     if (proxy.type() != QNetworkProxy::NoProxy)
119         return nullptr;
120 #endif
121 
122     return new QNativeSocketEngine(parent);
123 }
124 
createSocketEngine(qintptr socketDescripter,QObject * parent)125 QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(qintptr socketDescripter, QObject *parent)
126 {
127     QMutexLocker locker(&socketHandlers()->mutex);
128     for (int i = 0; i < socketHandlers()->size(); i++) {
129         if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketDescripter, parent))
130             return ret;
131     }
132     return new QNativeSocketEngine(parent);
133 }
134 
error() const135 QAbstractSocket::SocketError QAbstractSocketEngine::error() const
136 {
137     return d_func()->socketError;
138 }
139 
errorString() const140 QString QAbstractSocketEngine::errorString() const
141 {
142     return d_func()->socketErrorString;
143 }
144 
setError(QAbstractSocket::SocketError error,const QString & errorString) const145 void QAbstractSocketEngine::setError(QAbstractSocket::SocketError error, const QString &errorString) const
146 {
147     Q_D(const QAbstractSocketEngine);
148     d->socketError = error;
149     d->socketErrorString = errorString;
150 }
151 
setReceiver(QAbstractSocketEngineReceiver * receiver)152 void QAbstractSocketEngine::setReceiver(QAbstractSocketEngineReceiver *receiver)
153 {
154     d_func()->receiver = receiver;
155 }
156 
readNotification()157 void QAbstractSocketEngine::readNotification()
158 {
159     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
160         receiver->readNotification();
161 }
162 
writeNotification()163 void QAbstractSocketEngine::writeNotification()
164 {
165     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
166         receiver->writeNotification();
167 }
168 
exceptionNotification()169 void QAbstractSocketEngine::exceptionNotification()
170 {
171     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
172         receiver->exceptionNotification();
173 }
174 
closeNotification()175 void QAbstractSocketEngine::closeNotification()
176 {
177     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
178         receiver->closeNotification();
179 }
180 
connectionNotification()181 void QAbstractSocketEngine::connectionNotification()
182 {
183     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
184         receiver->connectionNotification();
185 }
186 
187 #ifndef QT_NO_NETWORKPROXY
proxyAuthenticationRequired(const QNetworkProxy & proxy,QAuthenticator * authenticator)188 void QAbstractSocketEngine::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
189 {
190     if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
191         receiver->proxyAuthenticationRequired(proxy, authenticator);
192 }
193 #endif
194 
195 
state() const196 QAbstractSocket::SocketState QAbstractSocketEngine::state() const
197 {
198     return d_func()->socketState;
199 }
200 
setState(QAbstractSocket::SocketState state)201 void QAbstractSocketEngine::setState(QAbstractSocket::SocketState state)
202 {
203     d_func()->socketState = state;
204 }
205 
socketType() const206 QAbstractSocket::SocketType QAbstractSocketEngine::socketType() const
207 {
208     return d_func()->socketType;
209 }
210 
setSocketType(QAbstractSocket::SocketType socketType)211 void QAbstractSocketEngine::setSocketType(QAbstractSocket::SocketType socketType)
212 {
213     d_func()->socketType = socketType;
214 }
215 
protocol() const216 QAbstractSocket::NetworkLayerProtocol QAbstractSocketEngine::protocol() const
217 {
218     return d_func()->socketProtocol;
219 }
220 
setProtocol(QAbstractSocket::NetworkLayerProtocol protocol)221 void QAbstractSocketEngine::setProtocol(QAbstractSocket::NetworkLayerProtocol protocol)
222 {
223     d_func()->socketProtocol = protocol;
224 }
225 
localAddress() const226 QHostAddress QAbstractSocketEngine::localAddress() const
227 {
228     return d_func()->localAddress;
229 }
230 
setLocalAddress(const QHostAddress & address)231 void QAbstractSocketEngine::setLocalAddress(const QHostAddress &address)
232 {
233     d_func()->localAddress = address;
234 }
235 
localPort() const236 quint16 QAbstractSocketEngine::localPort() const
237 {
238     return d_func()->localPort;
239 }
240 
setLocalPort(quint16 port)241 void QAbstractSocketEngine::setLocalPort(quint16 port)
242 {
243     d_func()->localPort = port;
244 }
245 
peerAddress() const246 QHostAddress QAbstractSocketEngine::peerAddress() const
247 {
248     return d_func()->peerAddress;
249 }
250 
setPeerAddress(const QHostAddress & address)251 void QAbstractSocketEngine::setPeerAddress(const QHostAddress &address)
252 {
253    d_func()->peerAddress = address;
254 }
255 
peerPort() const256 quint16 QAbstractSocketEngine::peerPort() const
257 {
258     return d_func()->peerPort;
259 }
260 
setPeerPort(quint16 port)261 void QAbstractSocketEngine::setPeerPort(quint16 port)
262 {
263     d_func()->peerPort = port;
264 }
265 
inboundStreamCount() const266 int QAbstractSocketEngine::inboundStreamCount() const
267 {
268     return d_func()->inboundStreamCount;
269 }
270 
outboundStreamCount() const271 int QAbstractSocketEngine::outboundStreamCount() const
272 {
273     return d_func()->outboundStreamCount;
274 }
275 
276 QT_END_NAMESPACE
277