| 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(addr: 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(value1&: d->header.destinationPort, value2&: d->header.senderPort); |
| 511 | qSwap(value1&: d->header.destinationAddress, value2&: d->header.senderAddress); |
| 512 | if (!isNonMulticast(addr: 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 | |