| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2016 Intel Corporation. | 
|---|
| 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 "qnetworkdatagram.h" | 
|---|
| 41 | #include "qnetworkdatagram_p.h" | 
|---|
| 42 |  | 
|---|
| 43 | #ifndef QT_NO_UDPSOCKET | 
|---|
| 44 |  | 
|---|
| 45 | QT_BEGIN_NAMESPACE | 
|---|
| 46 |  | 
|---|
| 47 | /*! | 
|---|
| 48 | \class QNetworkDatagram | 
|---|
| 49 | \brief The QNetworkDatagram class provides the data and metadata of a UDP datagram. | 
|---|
| 50 | \since 5.8 | 
|---|
| 51 | \ingroup network | 
|---|
| 52 | \inmodule QtNetwork | 
|---|
| 53 | \reentrant | 
|---|
| 54 |  | 
|---|
| 55 | QNetworkDatagram can be used with the \l QUdpSocket class to represent the full | 
|---|
| 56 | information contained in a UDP (User Datagram Protocol) datagram. | 
|---|
| 57 | QNetworkDatagram encapsulates the following information of a datagram: | 
|---|
| 58 | \list | 
|---|
| 59 | \li the payload data; | 
|---|
| 60 | \li the sender address and port number; | 
|---|
| 61 | \li the destination address and port number; | 
|---|
| 62 | \li the remaining hop count limit (on IPv4, this field is usually called "time to live" - TTL); | 
|---|
| 63 | \li the network interface index the datagram was received on or to be sent on. | 
|---|
| 64 | \endlist | 
|---|
| 65 |  | 
|---|
| 66 | QUdpSocket will try to match a common behavior as much as possible on all | 
|---|
| 67 | operating systems, but not all of the metadata above can be obtained in | 
|---|
| 68 | some operating systems. Metadata that cannot be set on the datagram when | 
|---|
| 69 | sending with QUdpSocket::writeDatagram() will be silently discarded. | 
|---|
| 70 |  | 
|---|
| 71 | Upon reception, the senderAddress() and senderPort() properties contain the | 
|---|
| 72 | address and port of the peer that sent the datagram, while | 
|---|
| 73 | destinationAddress() and destinationPort() contain the target that was | 
|---|
| 74 | contained in the datagram. That is usually an address local to the current | 
|---|
| 75 | machine, but it can also be an IPv4 broadcast address (such as | 
|---|
| 76 | "255.255.255.255") or an IPv4 or IPv6 multicast address. Applications may | 
|---|
| 77 | find it useful to determine if the datagram was sent specifically to this | 
|---|
| 78 | machine via unicast addressing or whether it was sent to multiple destinations. | 
|---|
| 79 |  | 
|---|
| 80 | When sending, the senderAddress() and senderPort() should contain the local | 
|---|
| 81 | address to be used when sending. The sender address must be an address that | 
|---|
| 82 | is assigned to this machine, which can be obtained using | 
|---|
| 83 | \l{QNetworkInterface}, and the port number must be the port number that the | 
|---|
| 84 | socket is bound to. Either field can be left unset and will be filled in by | 
|---|
| 85 | the operating system with default values. The destinationAddress() and | 
|---|
| 86 | destinationPort() fields may be set to a target address different from the | 
|---|
| 87 | one the UDP socket is currently associated with. | 
|---|
| 88 |  | 
|---|
| 89 | Usually, when sending a datagram in reply to a datagram previously | 
|---|
| 90 | received, one will set the destinationAddress() to be the senderAddress() | 
|---|
| 91 | of the incoming datagram and similarly for the port numbers. To facilitate | 
|---|
| 92 | this common process, QNetworkDatagram provides the function makeReply(). | 
|---|
| 93 |  | 
|---|
| 94 | The hopCount() function contains, for a received datagram, the remaining | 
|---|
| 95 | hop count limit for the packet. When sending, it contains the hop count | 
|---|
| 96 | limit to be set. Most protocols will leave this value set to the default | 
|---|
| 97 | and let the operating system decide on the best value to be used. | 
|---|
| 98 | Multicasting over IPv4 often uses this field to indicate the scope of the | 
|---|
| 99 | multicast group (link-local, local to an organization or global). | 
|---|
| 100 |  | 
|---|
| 101 | The interfaceIndex() function contains the index of the operating system's | 
|---|
| 102 | interface that received the packet. This value is the same one that can be | 
|---|
| 103 | set on a QHostAddress::scopeId() property and matches the | 
|---|
| 104 | QNetworkInterface::index() property. When sending packets to global | 
|---|
| 105 | addresses, it is not necessary to set the interface index as the operating | 
|---|
| 106 | system will choose the correct one using the system routing table. This | 
|---|
| 107 | property is important when sending datagrams to link-local destinations, | 
|---|
| 108 | whether unicast or multicast. | 
|---|
| 109 |  | 
|---|
| 110 | \section1 Feature support | 
|---|
| 111 |  | 
|---|
| 112 | Some features of QNetworkDatagram are not supported in all operating systems. | 
|---|
| 113 | Only the address and ports of the remote host (sender in received packets | 
|---|
| 114 | and destination for outgoing packets) are supported in all systems. On most | 
|---|
| 115 | operating systems, the other features are supported only for IPv6. Software | 
|---|
| 116 | should check at runtime whether the rest could be determined for IPv4 | 
|---|
| 117 | addresses. | 
|---|
| 118 |  | 
|---|
| 119 | The current feature support is as follows: | 
|---|
| 120 |  | 
|---|
| 121 | \table | 
|---|
| 122 | \header   \li Operating system    \li Local address   \li Hop count       \li Interface index | 
|---|
| 123 | \row      \li FreeBSD             \li Supported       \li Supported       \li Only for IPv6 | 
|---|
| 124 | \row      \li Linux               \li Supported       \li Supported       \li Supported | 
|---|
| 125 | \row      \li OS X                \li Supported       \li Supported       \li Only for IPv6 | 
|---|
| 126 | \row      \li Other Unix supporting RFC 3542 \li Only for IPv6 \li Only for IPv6 \li Only for IPv6 | 
|---|
| 127 | \row      \li Windows (desktop)   \li Supported       \li Supported       \li Supported | 
|---|
| 128 | \row      \li Windows RT          \li Not supported   \li Not supported   \li Not supported | 
|---|
| 129 | \endtable | 
|---|
| 130 |  | 
|---|
| 131 | \sa QUdpSocket, QNetworkInterface | 
|---|
| 132 | */ | 
|---|
| 133 |  | 
|---|
| 134 | /*! | 
|---|
| 135 | Creates a QNetworkDatagram object with no payload data and undefined destination address. | 
|---|
| 136 |  | 
|---|
| 137 | The payload can be modified by using setData() and the destination address | 
|---|
| 138 | can be set with setDestination(). | 
|---|
| 139 |  | 
|---|
| 140 | If the destination address is left undefined, QUdpSocket::writeDatagram() | 
|---|
| 141 | will attempt to send the datagram to the address last associated with, by | 
|---|
| 142 | using QUdpSocket::connectToHost(). | 
|---|
| 143 | */ | 
|---|
| 144 | QNetworkDatagram::QNetworkDatagram() | 
|---|
| 145 | : d(new QNetworkDatagramPrivate) | 
|---|
| 146 | { | 
|---|
| 147 | } | 
|---|
| 148 |  | 
|---|
| 149 | /*! | 
|---|
| 150 | Creates a QNetworkDatagram object and sets \a data as the payload data, along with | 
|---|
| 151 | \a destinationAddress and \a port as the destination address of the datagram. | 
|---|
| 152 | */ | 
|---|
| 153 | QNetworkDatagram::QNetworkDatagram(const QByteArray &data, const QHostAddress &destinationAddress, quint16 port) | 
|---|
| 154 | : d(new QNetworkDatagramPrivate(data, destinationAddress, port)) | 
|---|
| 155 | { | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | /*! | 
|---|
| 159 | Creates a copy of the \a other datagram, including the payload and metadata. | 
|---|
| 160 |  | 
|---|
| 161 | To create a datagram suitable for sending in a reply, use QNetworkDatagram::makeReply(); | 
|---|
| 162 | */ | 
|---|
| 163 | QNetworkDatagram::QNetworkDatagram(const QNetworkDatagram &other) | 
|---|
| 164 | : d(new QNetworkDatagramPrivate(*other.d)) | 
|---|
| 165 | { | 
|---|
| 166 | } | 
|---|
| 167 |  | 
|---|
| 168 | /*! \internal */ | 
|---|
| 169 | QNetworkDatagram::QNetworkDatagram(QNetworkDatagramPrivate &dd) | 
|---|
| 170 | : d(&dd) | 
|---|
| 171 | { | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 | /*! | 
|---|
| 175 | Copies the \a other datagram, including the payload and metadata. | 
|---|
| 176 |  | 
|---|
| 177 | To create a datagram suitable for sending in a reply, use QNetworkDatagram::makeReply(); | 
|---|
| 178 | */ | 
|---|
| 179 | QNetworkDatagram &QNetworkDatagram::operator=(const QNetworkDatagram &other) | 
|---|
| 180 | { | 
|---|
| 181 | *d = *other.d; | 
|---|
| 182 | return *this; | 
|---|
| 183 | } | 
|---|
| 184 |  | 
|---|
| 185 | /*! | 
|---|
| 186 | Clears the payload data and metadata in this QNetworkDatagram object, resetting | 
|---|
| 187 | them to their default values. | 
|---|
| 188 | */ | 
|---|
| 189 | void QNetworkDatagram::clear() | 
|---|
| 190 | { | 
|---|
| 191 | d->data.clear(); | 
|---|
| 192 | d->header.senderAddress.clear(); | 
|---|
| 193 | d->header.destinationAddress.clear(); | 
|---|
| 194 | d->header.hopLimit = -1; | 
|---|
| 195 | d->header.ifindex = 0; | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | /*! | 
|---|
| 199 | \fn QNetworkDatagram::isNull() const | 
|---|
| 200 | Returns true if this QNetworkDatagram object is null. This function is the | 
|---|
| 201 | opposite of isValid(). | 
|---|
| 202 | */ | 
|---|
| 203 |  | 
|---|
| 204 | /*! | 
|---|
| 205 | Returns true if this QNetworkDatagram object is valid. A valid QNetworkDatagram | 
|---|
| 206 | object contains at least one sender or receiver address. Valid datagrams | 
|---|
| 207 | can contain empty payloads. | 
|---|
| 208 | */ | 
|---|
| 209 | bool QNetworkDatagram::isValid() const | 
|---|
| 210 | { | 
|---|
| 211 | return d->header.senderAddress.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol || | 
|---|
| 212 | d->header.destinationAddress.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol; | 
|---|
| 213 | } | 
|---|
| 214 |  | 
|---|
| 215 | /*! | 
|---|
| 216 | Returns the sender address associated with this datagram. For a datagram | 
|---|
| 217 | received from the network, it is the address of the peer node that sent the | 
|---|
| 218 | datagram. For an outgoing datagrams, it is the local address to be used | 
|---|
| 219 | when sending. | 
|---|
| 220 |  | 
|---|
| 221 | If no sender address was set on this datagram, the returned object will | 
|---|
| 222 | report true to QHostAddress::isNull(). | 
|---|
| 223 |  | 
|---|
| 224 | \sa destinationAddress(), senderPort(), setSender() | 
|---|
| 225 | */ | 
|---|
| 226 | QHostAddress QNetworkDatagram::senderAddress() const | 
|---|
| 227 | { | 
|---|
| 228 | return d->header.senderAddress; | 
|---|
| 229 | } | 
|---|
| 230 |  | 
|---|
| 231 | /*! | 
|---|
| 232 | Returns the destination address associated with this datagram. For a | 
|---|
| 233 | datagram received from the network, it is the address the peer node sent | 
|---|
| 234 | the datagram to, which can either be a local address of this machine or a | 
|---|
| 235 | multicast or broadcast address. For an outgoing datagrams, it is the | 
|---|
| 236 | address the datagram should be sent to. | 
|---|
| 237 |  | 
|---|
| 238 | If no destination address was set on this datagram, the returned object | 
|---|
| 239 | will report true to QHostAddress::isNull(). | 
|---|
| 240 |  | 
|---|
| 241 | \sa senderAddress(), destinationPort(), setDestination() | 
|---|
| 242 | */ | 
|---|
| 243 | QHostAddress QNetworkDatagram::destinationAddress() const | 
|---|
| 244 | { | 
|---|
| 245 | return d->header.destinationAddress; | 
|---|
| 246 | } | 
|---|
| 247 |  | 
|---|
| 248 | /*! | 
|---|
| 249 | Returns the port number of the sender associated with this datagram. For a | 
|---|
| 250 | datagram received from the network, it is the port number that the peer | 
|---|
| 251 | node sent the datagram from. For an outgoing datagram, it is the local port | 
|---|
| 252 | the datagram should be sent from. | 
|---|
| 253 |  | 
|---|
| 254 | If no sender address was associated with this datagram, this function | 
|---|
| 255 | returns -1. | 
|---|
| 256 |  | 
|---|
| 257 | \sa senderAddress(), destinationPort(), setSender() | 
|---|
| 258 | */ | 
|---|
| 259 | int QNetworkDatagram::senderPort() const | 
|---|
| 260 | { | 
|---|
| 261 | return d->header.senderAddress.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol | 
|---|
| 262 | ? -1 : d->header.senderPort; | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 | /*! | 
|---|
| 266 | Returns the port number of the destination associated with this datagram. | 
|---|
| 267 | For a datagram received from the network, it is the local port number that | 
|---|
| 268 | the peer node sent the datagram to. For an outgoing datagram, it is the | 
|---|
| 269 | peer port the datagram should be sent to. | 
|---|
| 270 |  | 
|---|
| 271 | If no destination address was associated with this datagram, this function | 
|---|
| 272 | returns -1. | 
|---|
| 273 |  | 
|---|
| 274 | \sa destinationAddress(), senderPort(), setDestination() | 
|---|
| 275 | */ | 
|---|
| 276 | int QNetworkDatagram::destinationPort() const | 
|---|
| 277 | { | 
|---|
| 278 | return d->header.destinationAddress.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol | 
|---|
| 279 | ? -1 : d->header.destinationPort; | 
|---|
| 280 | } | 
|---|
| 281 |  | 
|---|
| 282 | /*! | 
|---|
| 283 | Sets the sender address associated with this datagram to be the address \a | 
|---|
| 284 | address and port number \a port. The sender address and port numbers are | 
|---|
| 285 | usually set by \l QUdpSocket upon reception, so there's no need to call | 
|---|
| 286 | this function on a received datagram. | 
|---|
| 287 |  | 
|---|
| 288 | For outgoing datagrams, this function can be used to set the address the | 
|---|
| 289 | datagram should carry. The address \a address must usually be one of the | 
|---|
| 290 | local addresses assigned to this machine, which can be obtained using \l | 
|---|
| 291 | QNetworkInterface. If left unset, the operating system will choose the most | 
|---|
| 292 | appropriate address to use given the destination in question. | 
|---|
| 293 |  | 
|---|
| 294 | The port number \a port must be the port number associated with the socket, | 
|---|
| 295 | if there is one. The value of 0 can be used to indicate that the operating | 
|---|
| 296 | system should choose the port number. | 
|---|
| 297 |  | 
|---|
| 298 | \sa QUdpSocket::writeDatagram(), senderAddress(), senderPort(), setDestination() | 
|---|
| 299 | */ | 
|---|
| 300 | void QNetworkDatagram::setSender(const QHostAddress &address, quint16 port) | 
|---|
| 301 | { | 
|---|
| 302 | d->header.senderAddress = address; | 
|---|
| 303 | d->header.senderPort = port; | 
|---|
| 304 | } | 
|---|
| 305 |  | 
|---|
| 306 | /*! | 
|---|
| 307 | Sets the destination address associated with this datagram to be the | 
|---|
| 308 | address \a address and port number \a port. The destination address and | 
|---|
| 309 | port numbers are usually set by \l QUdpSocket upon reception, so there's no | 
|---|
| 310 | need to call this function on a received datagram. | 
|---|
| 311 |  | 
|---|
| 312 | For outgoing datagrams, this function can be used to set the address the | 
|---|
| 313 | datagram should be sent to. It can be the unicast address used to | 
|---|
| 314 | communicate with the peer or a broadcast or multicast address to send to a | 
|---|
| 315 | group of devices. | 
|---|
| 316 |  | 
|---|
| 317 | \sa QUdpSocket::writeDatagram(), destinationAddress(), destinationPort(), setSender() | 
|---|
| 318 | */ | 
|---|
| 319 | void QNetworkDatagram::setDestination(const QHostAddress &address, quint16 port) | 
|---|
| 320 | { | 
|---|
| 321 | d->header.destinationAddress = address; | 
|---|
| 322 | d->header.destinationPort = port; | 
|---|
| 323 | } | 
|---|
| 324 |  | 
|---|
| 325 | /*! | 
|---|
| 326 | Returns the hop count limit associated with this datagram. The hop count | 
|---|
| 327 | limit is the number of nodes that are allowed to forward the IP packet | 
|---|
| 328 | before it expires and an error is sent back to the sender of the datagram. | 
|---|
| 329 | In IPv4, this value is usually known as "time to live" (TTL). | 
|---|
| 330 |  | 
|---|
| 331 | If this datagram was received from the network, this is the remaining hop | 
|---|
| 332 | count of the datagram after reception and was decremented by 1 by each node | 
|---|
| 333 | that forwarded the packet. A value of -1 indicates that the hop limit count | 
|---|
| 334 | not be obtained. | 
|---|
| 335 |  | 
|---|
| 336 | If this is an outgoing datagram, this is the value to be set in the IP header | 
|---|
| 337 | upon sending. A value of -1 indicates the operating system should choose | 
|---|
| 338 | the value. | 
|---|
| 339 |  | 
|---|
| 340 | \sa setHopLimit() | 
|---|
| 341 | */ | 
|---|
| 342 | int QNetworkDatagram::hopLimit() const | 
|---|
| 343 | { | 
|---|
| 344 | return d->header.hopLimit; | 
|---|
| 345 | } | 
|---|
| 346 |  | 
|---|
| 347 | /*! | 
|---|
| 348 | Sets the hop count limit associated with this datagram to \a count. The hop | 
|---|
| 349 | count limit is the number of nodes that are allowed to forward the IP | 
|---|
| 350 | packet before it expires and an error is sent back to the sender of the | 
|---|
| 351 | datagram. In IPv4, this value is usually known as "time to live" (TTL). | 
|---|
| 352 |  | 
|---|
| 353 | It is usually not necessary to call this function on datagrams received | 
|---|
| 354 | from the network. | 
|---|
| 355 |  | 
|---|
| 356 | If this is an outgoing packet, this is the value to be set in the IP header | 
|---|
| 357 | upon sending. The valid range for the value is 1 to 255. This function also | 
|---|
| 358 | accepts a value of -1 to indicate that the operating system should choose | 
|---|
| 359 | the value. | 
|---|
| 360 |  | 
|---|
| 361 | \sa hopLimit() | 
|---|
| 362 | */ | 
|---|
| 363 | void QNetworkDatagram::setHopLimit(int count) | 
|---|
| 364 | { | 
|---|
| 365 | d->header.hopLimit = count; | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 | /*! | 
|---|
| 369 | Returns the interface index this datagram is associated with. The interface | 
|---|
| 370 | index is a positive number that uniquely identifies the network interface | 
|---|
| 371 | in the operating system. This number matches the value returned by | 
|---|
| 372 | QNetworkInterface::index() for the interface. | 
|---|
| 373 |  | 
|---|
| 374 | If this datagram was received from the network, this is the index of the | 
|---|
| 375 | interface that the packet was received from. If this is an outgoing | 
|---|
| 376 | datagram, this is the index of the interface that the datagram should be | 
|---|
| 377 | sent on. | 
|---|
| 378 |  | 
|---|
| 379 | A value of 0 indicates that the interface index is unknown. | 
|---|
| 380 |  | 
|---|
| 381 | \sa setInterfaceIndex() | 
|---|
| 382 | */ | 
|---|
| 383 | uint QNetworkDatagram::interfaceIndex() const | 
|---|
| 384 | { | 
|---|
| 385 | return d->header.ifindex; | 
|---|
| 386 | } | 
|---|
| 387 |  | 
|---|
| 388 | /*! | 
|---|
| 389 | Sets the interface index this datagram is associated with to \a index. The | 
|---|
| 390 | interface index is a positive number that uniquely identifies the network | 
|---|
| 391 | interface in the operating system. This number matches the value returned | 
|---|
| 392 | by QNetworkInterface::index() for the interface. | 
|---|
| 393 |  | 
|---|
| 394 | It is usually not necessary to call this function on datagrams received | 
|---|
| 395 | from the network. | 
|---|
| 396 |  | 
|---|
| 397 | If this is an outgoing packet, this is the index of the interface the | 
|---|
| 398 | datagram should be sent on. A value of 0 indicates that the operating | 
|---|
| 399 | system should choose the interface based on other factors. | 
|---|
| 400 |  | 
|---|
| 401 | Note that the interface index can also be set with | 
|---|
| 402 | QHostAddress::setScopeId() for IPv6 destination addresses and then with | 
|---|
| 403 | setDestination(). If the scope ID set in the destination address and \a | 
|---|
| 404 | index are different and neither is zero, it is undefined which interface | 
|---|
| 405 | the operating system will send the datagram on. | 
|---|
| 406 |  | 
|---|
| 407 | \sa setInterfaceIndex() | 
|---|
| 408 | */ | 
|---|
| 409 | void QNetworkDatagram::setInterfaceIndex(uint index) | 
|---|
| 410 | { | 
|---|
| 411 | d->header.ifindex = index; | 
|---|
| 412 | } | 
|---|
| 413 |  | 
|---|
| 414 | /*! | 
|---|
| 415 | Returns the data payload of this datagram. For a datagram received from the | 
|---|
| 416 | network, it contains the payload of the datagram. For an outgoing datagram, | 
|---|
| 417 | it is the datagram to be sent. | 
|---|
| 418 |  | 
|---|
| 419 | Note that datagrams can be transmitted with no data, so the returned | 
|---|
| 420 | QByteArray may be empty. | 
|---|
| 421 |  | 
|---|
| 422 | \sa setData() | 
|---|
| 423 | */ | 
|---|
| 424 | QByteArray QNetworkDatagram::data() const | 
|---|
| 425 | { | 
|---|
| 426 | return d->data; | 
|---|
| 427 | } | 
|---|
| 428 |  | 
|---|
| 429 | /*! | 
|---|
| 430 | Sets the data payload of this datagram to \a data. It is usually not | 
|---|
| 431 | necessary to call this function on received datagrams. For outgoing | 
|---|
| 432 | datagrams, this function sets the data to be sent on the network. | 
|---|
| 433 |  | 
|---|
| 434 | Since datagrams can empty, an empty QByteArray is a valid value for \a | 
|---|
| 435 | data. | 
|---|
| 436 |  | 
|---|
| 437 | \sa data() | 
|---|
| 438 | */ | 
|---|
| 439 | void QNetworkDatagram::setData(const QByteArray &data) | 
|---|
| 440 | { | 
|---|
| 441 | d->data = data; | 
|---|
| 442 | } | 
|---|
| 443 |  | 
|---|
| 444 | /*! | 
|---|
| 445 | \fn QNetworkDatagram QNetworkDatagram::makeReply(const QByteArray &payload) const & | 
|---|
| 446 | \fn QNetworkDatagram QNetworkDatagram::makeReply(const QByteArray &payload) && | 
|---|
| 447 |  | 
|---|
| 448 | Creates a new QNetworkDatagram representing a reply to this incoming datagram | 
|---|
| 449 | and sets the payload data to \a payload. This function is a very convenient | 
|---|
| 450 | way of responding to a datagram back to the original sender. | 
|---|
| 451 |  | 
|---|
| 452 | Example: | 
|---|
| 453 | \snippet code/src_network_kernel_qnetworkdatagram.cpp 0 | 
|---|
| 454 |  | 
|---|
| 455 | This function is especially convenient since it will automatically copy | 
|---|
| 456 | parameters from this datagram to the new datagram as appropriate: | 
|---|
| 457 |  | 
|---|
| 458 | \list | 
|---|
| 459 | \li this datagram's sender address and port are copied to the new | 
|---|
| 460 | datagram's destination address and port; | 
|---|
| 461 | \li this datagram's interface index, if any, is copied to the new | 
|---|
| 462 | datagram's interface index; | 
|---|
| 463 | \li this datagram's destination address and port are copied to the new | 
|---|
| 464 | datagram's sender address and port only if the address is IPv6 | 
|---|
| 465 | global (non-multicast) address; | 
|---|
| 466 | \li the hop count limit on the new datagram is reset to the default (-1); | 
|---|
| 467 | \endlist | 
|---|
| 468 |  | 
|---|
| 469 | If QNetworkDatagram is modified in a future version of Qt to carry further | 
|---|
| 470 | metadata, this function will copy that metadata as appropriate. | 
|---|
| 471 |  | 
|---|
| 472 | This datagram's destination address is not copied if it is an IPv4 address | 
|---|
| 473 | because it is not possible to tell an IPv4 broadcast address apart from a | 
|---|
| 474 | regular IPv4 address without an exhaustive search of all addresses assigned | 
|---|
| 475 | to this machine. Attempting to send a datagram with the sender address | 
|---|
| 476 | equal to the broadcast address is likely to fail. However, this should not | 
|---|
| 477 | affect the communication as network interfaces with multiple IPv4 addresses | 
|---|
| 478 | are uncommon, so the address the operating system will select will likely | 
|---|
| 479 | be one the peer will understand. | 
|---|
| 480 |  | 
|---|
| 481 | \note This function comes with both rvalue- and lvalue-reference qualifier | 
|---|
| 482 | overloads, so it is a good idea to make sure this object is rvalue, if | 
|---|
| 483 | possible, before calling makeReply, so as to make better use of move | 
|---|
| 484 | semantics. To achieve that, the example above would use: | 
|---|
| 485 | \snippet code/src_network_kernel_qnetworkdatagram.cpp 1 | 
|---|
| 486 | */ | 
|---|
| 487 |  | 
|---|
| 488 |  | 
|---|
| 489 | static bool isNonMulticast(const QHostAddress &addr) | 
|---|
| 490 | { | 
|---|
| 491 | // is it a multicast address? | 
|---|
| 492 | return !addr.isMulticast(); | 
|---|
| 493 | } | 
|---|
| 494 |  | 
|---|
| 495 | QNetworkDatagram QNetworkDatagram::makeReply_helper(const QByteArray &data) const | 
|---|
| 496 | { | 
|---|
| 497 | QNetworkDatagramPrivate *x = new QNetworkDatagramPrivate(data, d->header.senderAddress, d->header.senderPort); | 
|---|
| 498 | x->header.ifindex = d->header.ifindex; | 
|---|
| 499 | if (isNonMulticast(d->header.destinationAddress)) { | 
|---|
| 500 | x->header.senderAddress = d->header.destinationAddress; | 
|---|
| 501 | x->header.senderPort = d->header.destinationPort; | 
|---|
| 502 | } | 
|---|
| 503 | return QNetworkDatagram(*x); | 
|---|
| 504 | } | 
|---|
| 505 |  | 
|---|
| 506 | void QNetworkDatagram::makeReply_helper_inplace(const QByteArray &data) | 
|---|
| 507 | { | 
|---|
| 508 | d->data = data; | 
|---|
| 509 | d->header.hopLimit = -1; | 
|---|
| 510 | qSwap(d->header.destinationPort, d->header.senderPort); | 
|---|
| 511 | qSwap(d->header.destinationAddress, d->header.senderAddress); | 
|---|
| 512 | if (!isNonMulticast(d->header.senderAddress)) | 
|---|
| 513 | d->header.senderAddress.clear(); | 
|---|
| 514 | } | 
|---|
| 515 |  | 
|---|
| 516 | void QNetworkDatagram::destroy(QNetworkDatagramPrivate *d) | 
|---|
| 517 | { | 
|---|
| 518 | Q_ASSUME(d); | 
|---|
| 519 | delete d; | 
|---|
| 520 | } | 
|---|
| 521 |  | 
|---|
| 522 | /*! \fn  void QNetworkDatagram::swap(QNetworkDatagram &other) | 
|---|
| 523 | Swaps this instance with \a other. | 
|---|
| 524 | */ | 
|---|
| 525 |  | 
|---|
| 526 |  | 
|---|
| 527 | QT_END_NAMESPACE | 
|---|
| 528 |  | 
|---|
| 529 | #endif // QT_NO_UDPSOCKET | 
|---|
| 530 |  | 
|---|