1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 //#define QUDPSOCKET_DEBUG
42 
43 /*! \class QUdpSocket
44 
45     \reentrant
46     \brief The QUdpSocket class provides a UDP socket.
47 
48     \ingroup network
49     \inmodule QtNetwork
50 
51     UDP (User Datagram Protocol) is a lightweight, unreliable,
52     datagram-oriented, connectionless protocol. It can be used when
53     reliability isn't important. QUdpSocket is a subclass of
54     QAbstractSocket that allows you to send and receive UDP
55     datagrams.
56 
57     The most common way to use this class is to bind to an address and port
58     using bind(), then call writeDatagram() and readDatagram() /
59     receiveDatagram() to transfer data. If you want to use the standard
60     QIODevice functions read(), readLine(), write(), etc., you must first
61     connect the socket directly to a peer by calling connectToHost().
62 
63     The socket emits the bytesWritten() signal every time a datagram
64     is written to the network. If you just want to send datagrams,
65     you don't need to call bind().
66 
67     The readyRead() signal is emitted whenever datagrams arrive. In
68     that case, hasPendingDatagrams() returns \c true. Call
69     pendingDatagramSize() to obtain the size of the first pending
70     datagram, and readDatagram() or receiveDatagram() to read it.
71 
72     \note An incoming datagram should be read when you receive the readyRead()
73     signal, otherwise this signal will not be emitted for the next datagram.
74 
75     Example:
76 
77     \snippet code/src_network_socket_qudpsocket.cpp 0
78 
79     QUdpSocket also supports UDP multicast. Use joinMulticastGroup() and
80     leaveMulticastGroup() to control group membership, and
81     QAbstractSocket::MulticastTtlOption and
82     QAbstractSocket::MulticastLoopbackOption to set the TTL and loopback socket
83     options. Use setMulticastInterface() to control the outgoing interface for
84     multicast datagrams, and multicastInterface() to query it.
85 
86     With QUdpSocket, you can also establish a virtual connection to a
87     UDP server using connectToHost() and then use read() and write()
88     to exchange datagrams without specifying the receiver for each
89     datagram.
90 
91     The \l{broadcastsender}{Broadcast Sender},
92     \l{broadcastreceiver}{Broadcast Receiver},
93     \l{multicastsender}{Multicast Sender}, and
94     \l{multicastreceiver}{Multicast Receiver} examples illustrate how
95     to use QUdpSocket in applications.
96 
97     \sa QTcpSocket, QNetworkDatagram
98 */
99 
100 #include "qudpsocket.h"
101 #include "qhostaddress.h"
102 #include "qnetworkdatagram.h"
103 #include "qnetworkinterface.h"
104 #include "qabstractsocket_p.h"
105 
106 QT_BEGIN_NAMESPACE
107 
108 #ifndef QT_NO_UDPSOCKET
109 
110 #define QT_CHECK_BOUND(function, a) do { \
111     if (!isValid()) { \
112         qWarning(function" called on a QUdpSocket when not in QUdpSocket::BoundState"); \
113         return (a); \
114     } } while (0)
115 
116 class QUdpSocketPrivate : public QAbstractSocketPrivate
117 {
118     Q_DECLARE_PUBLIC(QUdpSocket)
119 
120     bool doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,
121                              const QHostAddress &remoteAddress);
122 public:
ensureInitialized(const QHostAddress & bindAddress,quint16 bindPort)123     inline bool ensureInitialized(const QHostAddress &bindAddress, quint16 bindPort)
124     { return doEnsureInitialized(bindAddress, bindPort, QHostAddress()); }
125 
ensureInitialized(const QHostAddress & remoteAddress)126     inline bool ensureInitialized(const QHostAddress &remoteAddress)
127     { return doEnsureInitialized(QHostAddress(), 0, remoteAddress); }
128 };
129 
doEnsureInitialized(const QHostAddress & bindAddress,quint16 bindPort,const QHostAddress & remoteAddress)130 bool QUdpSocketPrivate::doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,
131                                             const QHostAddress &remoteAddress)
132 {
133     const QHostAddress *address = &bindAddress;
134     QAbstractSocket::NetworkLayerProtocol proto = address->protocol();
135     if (proto == QUdpSocket::UnknownNetworkLayerProtocol) {
136         address = &remoteAddress;
137         proto = address->protocol();
138     }
139 
140     // now check if the socket engine is initialized and to the right type
141     if (!socketEngine || !socketEngine->isValid()) {
142         resolveProxy(remoteAddress.toString(), bindPort);
143         if (!initSocketLayer(address->protocol()))
144             return false;
145     }
146 
147     return true;
148 }
149 
150 /*!
151     Creates a QUdpSocket object.
152 
153     \a parent is passed to the QObject constructor.
154 
155     \sa socketType()
156 */
QUdpSocket(QObject * parent)157 QUdpSocket::QUdpSocket(QObject *parent)
158     : QAbstractSocket(UdpSocket, *new QUdpSocketPrivate, parent)
159 {
160     d_func()->isBuffered = false;
161 }
162 
163 /*!
164     Destroys the socket, closing the connection if necessary.
165 
166     \sa close()
167 */
~QUdpSocket()168 QUdpSocket::~QUdpSocket()
169 {
170 }
171 
172 #ifndef QT_NO_NETWORKINTERFACE
173 
174 /*!
175     \since 4.8
176 
177     Joins the multicast group specified by \a groupAddress on the default
178     interface chosen by the operating system. The socket must be in BoundState,
179     otherwise an error occurs.
180 
181     Note that if you are attempting to join an IPv4 group, your socket must not
182     be bound using IPv6 (or in dual mode, using QHostAddress::Any). You must use
183     QHostAddress::AnyIPv4 instead.
184 
185     This function returns \c true if successful; otherwise it returns \c false
186     and sets the socket error accordingly.
187 
188     \note Joining IPv6 multicast groups without an interface selection is not
189     supported in all operating systems. Consider using the overload where the
190     interface is specified.
191 
192     \sa leaveMulticastGroup()
193 */
joinMulticastGroup(const QHostAddress & groupAddress)194 bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)
195 {
196     return joinMulticastGroup(groupAddress, QNetworkInterface());
197 }
198 
199 /*!
200     \since 4.8
201     \overload
202 
203     Joins the multicast group address \a groupAddress on the interface \a
204     iface.
205 
206     \sa leaveMulticastGroup()
207 */
joinMulticastGroup(const QHostAddress & groupAddress,const QNetworkInterface & iface)208 bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress,
209                                     const QNetworkInterface &iface)
210 {
211     Q_D(QUdpSocket);
212     QT_CHECK_BOUND("QUdpSocket::joinMulticastGroup()", false);
213     return d->socketEngine->joinMulticastGroup(groupAddress, iface);
214 }
215 
216 /*!
217     \since 4.8
218 
219     Leaves the multicast group specified by \a groupAddress on the default
220     interface chosen by the operating system. The socket must be in BoundState,
221     otherwise an error occurs.
222 
223    This function returns \c true if successful; otherwise it returns \c false and
224    sets the socket error accordingly.
225 
226    \note This function should be called with the same arguments as were passed
227    to joinMulticastGroup().
228 
229    \sa joinMulticastGroup()
230 */
leaveMulticastGroup(const QHostAddress & groupAddress)231 bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)
232 {
233     return leaveMulticastGroup(groupAddress, QNetworkInterface());
234 }
235 
236 /*!
237     \since 4.8
238     \overload
239 
240     Leaves the multicast group specified by \a groupAddress on the interface \a
241     iface.
242 
243     \note This function should be called with the same arguments as were passed
244     to joinMulticastGroup().
245 
246     \sa joinMulticastGroup()
247 */
leaveMulticastGroup(const QHostAddress & groupAddress,const QNetworkInterface & iface)248 bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress,
249                                      const QNetworkInterface &iface)
250 {
251     QT_CHECK_BOUND("QUdpSocket::leaveMulticastGroup()", false);
252     return d_func()->socketEngine->leaveMulticastGroup(groupAddress, iface);
253 }
254 
255 /*!
256     \since 4.8
257 
258     Returns the interface for the outgoing interface for multicast datagrams.
259     This corresponds to the IP_MULTICAST_IF socket option for IPv4 sockets and
260     the IPV6_MULTICAST_IF socket option for IPv6 sockets. If no interface has
261     been previously set, this function returns an invalid QNetworkInterface.
262     The socket must be in BoundState, otherwise an invalid QNetworkInterface is
263     returned.
264 
265     \sa setMulticastInterface()
266 */
multicastInterface() const267 QNetworkInterface QUdpSocket::multicastInterface() const
268 {
269     Q_D(const QUdpSocket);
270     QT_CHECK_BOUND("QUdpSocket::multicastInterface()", QNetworkInterface());
271     return d->socketEngine->multicastInterface();
272 }
273 
274 /*!
275     \since 4.8
276 
277     Sets the outgoing interface for multicast datagrams to the interface \a
278     iface. This corresponds to the IP_MULTICAST_IF socket option for IPv4
279     sockets and the IPV6_MULTICAST_IF socket option for IPv6 sockets. The
280     socket must be in BoundState, otherwise this function does nothing.
281 
282     \sa multicastInterface(), joinMulticastGroup(), leaveMulticastGroup()
283 */
setMulticastInterface(const QNetworkInterface & iface)284 void QUdpSocket::setMulticastInterface(const QNetworkInterface &iface)
285 {
286     Q_D(QUdpSocket);
287     if (!isValid()) {
288         qWarning("QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState");
289         return;
290     }
291     d->socketEngine->setMulticastInterface(iface);
292 }
293 
294 #endif // QT_NO_NETWORKINTERFACE
295 
296 /*!
297     Returns \c true if at least one datagram is waiting to be read;
298     otherwise returns \c false.
299 
300     \sa pendingDatagramSize(), readDatagram()
301 */
hasPendingDatagrams() const302 bool QUdpSocket::hasPendingDatagrams() const
303 {
304     QT_CHECK_BOUND("QUdpSocket::hasPendingDatagrams()", false);
305     return d_func()->socketEngine->hasPendingDatagrams();
306 }
307 
308 /*!
309     Returns the size of the first pending UDP datagram. If there is
310     no datagram available, this function returns -1.
311 
312     \sa hasPendingDatagrams(), readDatagram()
313 */
pendingDatagramSize() const314 qint64 QUdpSocket::pendingDatagramSize() const
315 {
316     QT_CHECK_BOUND("QUdpSocket::pendingDatagramSize()", -1);
317     return d_func()->socketEngine->pendingDatagramSize();
318 }
319 
320 /*!
321     Sends the datagram at \a data of size \a size to the host
322     address \a address at port \a port. Returns the number of
323     bytes sent on success; otherwise returns -1.
324 
325     Datagrams are always written as one block. The maximum size of a
326     datagram is highly platform-dependent, but can be as low as 8192
327     bytes. If the datagram is too large, this function will return -1
328     and error() will return DatagramTooLargeError.
329 
330     Sending datagrams larger than 512 bytes is in general disadvised,
331     as even if they are sent successfully, they are likely to be
332     fragmented by the IP layer before arriving at their final
333     destination.
334 
335     \warning Calling this function on a connected UDP socket may
336     result in an error and no packet being sent. If you are using a
337     connected socket, use write() to send datagrams.
338 
339     \sa readDatagram(), write()
340 */
writeDatagram(const char * data,qint64 size,const QHostAddress & address,quint16 port)341 qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address,
342                                   quint16 port)
343 {
344     Q_D(QUdpSocket);
345 #if defined QUDPSOCKET_DEBUG
346     qDebug("QUdpSocket::writeDatagram(%p, %llu, \"%s\", %i)", data, size,
347            address.toString().toLatin1().constData(), port);
348 #endif
349     if (!d->doEnsureInitialized(QHostAddress::Any, 0, address))
350         return -1;
351     if (state() == UnconnectedState)
352         bind();
353 
354     qint64 sent = d->socketEngine->writeDatagram(data, size, QIpPacketHeader(address, port));
355     d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
356 
357     if (sent >= 0) {
358         emit bytesWritten(sent);
359     } else {
360         if (sent == -2) {
361             // Socket engine reports EAGAIN. Treat as a temporary error.
362             d->setErrorAndEmit(QAbstractSocket::TemporaryError,
363                                tr("Unable to send a datagram"));
364             return -1;
365         }
366         d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
367     }
368     return sent;
369 }
370 
371 /*!
372     \fn qint64 QUdpSocket::writeDatagram(const QByteArray &datagram,
373                                              const QHostAddress &host, quint16 port)
374     \overload
375 
376     Sends the datagram \a datagram to the host address \a host and at
377     port \a port.
378 
379     The function returns the number of bytes sent if it succeeded or -1 if it
380     encountered an error.
381 */
382 
383 /*!
384     \since 5.8
385     \overload
386 
387     Sends the datagram \a datagram to the host address and port numbers
388     contained in \a datagram, using the network interface and hop count limits
389     also set there. If the destination address and port numbers are unset, this
390     function will send to the address that was passed to connectToHost().
391 
392     If the destination address is IPv6 with a non-empty
393     \l{QHostAddress::scopeId()}{scope id} but differs from the interface index
394     in \a datagram, it is undefined which interface the operating system will
395     choose to send on.
396 
397     The function returns the number of bytes sent if it succeeded or -1 if it
398     encountered an error.
399 
400     \warning Calling this function on a connected UDP socket may
401     result in an error and no packet being sent. If you are using a
402     connected socket, use write() to send datagrams.
403 
404     \sa QNetworkDatagram::setDestination(), QNetworkDatagram::setHopLimit(), QNetworkDatagram::setInterfaceIndex()
405 */
writeDatagram(const QNetworkDatagram & datagram)406 qint64 QUdpSocket::writeDatagram(const QNetworkDatagram &datagram)
407 {
408     Q_D(QUdpSocket);
409 #if defined QUDPSOCKET_DEBUG
410     qDebug("QUdpSocket::writeDatagram(%p, %i, \"%s\", %i)",
411            datagram.d->data.constData(),
412            datagram.d->data.size(),
413            datagram.destinationAddress().toString().toLatin1().constData(),
414            datagram.destinationPort());
415 #endif
416     if (!d->doEnsureInitialized(QHostAddress::Any, 0, datagram.destinationAddress()))
417         return -1;
418     if (state() == UnconnectedState)
419         bind();
420 
421     qint64 sent = d->socketEngine->writeDatagram(datagram.d->data,
422                                                  datagram.d->data.size(),
423                                                  datagram.d->header);
424     d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
425 
426     if (sent >= 0) {
427         emit bytesWritten(sent);
428     } else {
429         d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
430     }
431     return sent;
432 }
433 
434 /*!
435     \since 5.8
436 
437     Receives a datagram no larger than \a maxSize bytes and returns it in the
438     QNetworkDatagram object, along with the sender's host address and port. If
439     possible, this function will also try to determine the datagram's
440     destination address, port, and the number of hop counts at reception time.
441 
442     On failure, returns a QNetworkDatagram that reports \l
443     {QNetworkDatagram::isValid()}{not valid}.
444 
445     If \a maxSize is too small, the rest of the datagram will be lost. If \a
446     maxSize is 0, the datagram will be discarded. If \a maxSize is -1 (the
447     default), this function will attempt to read the entire datagram.
448 
449     \sa writeDatagram(), hasPendingDatagrams(), pendingDatagramSize()
450 */
receiveDatagram(qint64 maxSize)451 QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize)
452 {
453     Q_D(QUdpSocket);
454 
455 #if defined QUDPSOCKET_DEBUG
456     qDebug("QUdpSocket::receiveDatagram(%lld)", maxSize);
457 #endif
458     QT_CHECK_BOUND("QUdpSocket::receiveDatagram()", QNetworkDatagram());
459 
460     if (maxSize < 0)
461         maxSize = d->socketEngine->pendingDatagramSize();
462     if (maxSize < 0)
463         return QNetworkDatagram();
464 
465     QNetworkDatagram result(QByteArray(maxSize, Qt::Uninitialized));
466     qint64 readBytes = d->socketEngine->readDatagram(result.d->data.data(), maxSize, &result.d->header,
467                                                      QAbstractSocketEngine::WantAll);
468     d->hasPendingData = false;
469     d->socketEngine->setReadNotificationEnabled(true);
470     if (readBytes < 0) {
471         d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
472         readBytes = 0;
473     }
474 
475     result.d->data.truncate(readBytes);
476     return result;
477 }
478 
479 /*!
480     Receives a datagram no larger than \a maxSize bytes and stores
481     it in \a data. The sender's host address and port is stored in
482     *\a address and *\a port (unless the pointers are \nullptr).
483 
484     Returns the size of the datagram on success; otherwise returns
485     -1.
486 
487     If \a maxSize is too small, the rest of the datagram will be
488     lost. To avoid loss of data, call pendingDatagramSize() to
489     determine the size of the pending datagram before attempting to
490     read it. If \a maxSize is 0, the datagram will be discarded.
491 
492     \sa writeDatagram(), hasPendingDatagrams(), pendingDatagramSize()
493 */
readDatagram(char * data,qint64 maxSize,QHostAddress * address,quint16 * port)494 qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address,
495                                     quint16 *port)
496 {
497     Q_D(QUdpSocket);
498 
499 #if defined QUDPSOCKET_DEBUG
500     qDebug("QUdpSocket::readDatagram(%p, %llu, %p, %p)", data, maxSize, address, port);
501 #endif
502     QT_CHECK_BOUND("QUdpSocket::readDatagram()", -1);
503 
504     qint64 readBytes;
505     if (address || port) {
506         QIpPacketHeader header;
507         readBytes = d->socketEngine->readDatagram(data, maxSize, &header,
508                                                   QAbstractSocketEngine::WantDatagramSender);
509         if (address)
510             *address = header.senderAddress;
511         if (port)
512             *port = header.senderPort;
513     } else {
514         readBytes = d->socketEngine->readDatagram(data, maxSize);
515     }
516 
517     d->hasPendingData = false;
518     d->socketEngine->setReadNotificationEnabled(true);
519     if (readBytes < 0) {
520         if (readBytes == -2) {
521             // No pending datagram. Treat as a temporary error.
522             d->setErrorAndEmit(QAbstractSocket::TemporaryError,
523                                tr("No datagram available for reading"));
524             return -1;
525         }
526         d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
527     }
528     return readBytes;
529 }
530 
531 #endif // QT_NO_UDPSOCKET
532 
533 QT_END_NAMESPACE
534