From 89efa7333db4b5877cb58b16e511b690fe43507c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 10 Mar 2015 15:01:21 -0700 Subject: QAbstractSocketEngine: introduce QIpPacketHeader for datagrams This commit changes the readDatagram() and writeDatagram() virtual functions to take a QIpPacketHeader as meta data, instead of a QHostAddress/quint16 pair. As previously, the header is an "out" parameter for readDatagram() and an "in" parameter for writeDatagram(). The header pointer in readDatagram() is allowed to be null if the PacketHeaderOptions indicates WantNone. Otherwise, it must not be null. The extra options parameter is introduced because we may not always want all the metadata upon reception. For sending, we know what to include or not based on what's set in the incoming header parameter. QIpPacketHeader splits sender and destination because we'll be able to return both on datagram reception. Change-Id: Iee8cbc07c4434ce9b560ffff13ca4213255008c7 Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine.cpp | 48 ++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'src/network/socket/qnativesocketengine.cpp') diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 22151b8e56..901dab5473 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -88,6 +88,25 @@ errorString() can be called to determine the cause of the error. */ +/*! + \enum QAbstractSocketEngine::PacketHeaderOption + + Specifies which fields in the IP packet header are desired in the call to + readDatagram(). + + \value WantNone caller isn't interested in the packet metadata + \value WantDatagramSender caller wants the sender address and port number + \value WantDatagramDestination caller wants the packet's destination address and port number + (this option is useful to distinguish multicast packets from unicast) + \value WantDatagramHopLimit caller wants the packet's remaining hop limit or time to live + (this option is useful in IPv4 multicasting, where the TTL is used + to indicate the realm) + \value WantAll this is a catch-all value to indicate the caller is + interested in all the available information + + \sa readDatagram(), QUdpDatagram +*/ + #include "qnativesocketengine_p.h" #include @@ -759,9 +778,8 @@ qint64 QNativeSocketEngine::pendingDatagramSize() const /*! Reads up to \a maxSize bytes of a datagram from the socket, stores it in \a data and returns the number of bytes read. The - address and port of the sender are stored in \a address and \a - port. If either of these pointers is 0, the corresponding value is - discarded. + address, port, and other IP header fields are stored in \a header + according to the request in \a options. To avoid unnecessarily loss of data, call pendingDatagramSize() to determine the size of the pending message before reading it. If \a @@ -771,20 +789,23 @@ qint64 QNativeSocketEngine::pendingDatagramSize() const \sa hasPendingDatagrams() */ -qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QHostAddress *address, - quint16 *port) +qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QIpPacketHeader *header, + PacketHeaderOptions options) { Q_D(QNativeSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1); Q_CHECK_TYPE(QNativeSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, -1); - return d->nativeReceiveDatagram(data, maxSize, address, port); + return d->nativeReceiveDatagram(data, maxSize, header, options); } /*! Writes a UDP datagram of size \a size bytes to the socket from - \a data to the address \a host on port \a port, and returns the - number of bytes written, or -1 if an error occurred. + \a data to the destination contained in \a header, and returns the + number of bytes written, or -1 if an error occurred. If \a header + contains other settings like hop limit or source address, this function + will try to pass them to the operating system too, but will not + indicate an error if it could not pass them. Only one datagram is sent, and if there is too much data to fit into a single datagram, the operation will fail and error() @@ -794,18 +815,19 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QHostAddres disadvised, as even if they are sent successfully, they are likely to be fragmented before arriving at their destination. - Experience has shown that it is in general safe to send datagrams - no larger than 512 bytes. + Experience has shown that it is in general safe to send IPv4 datagrams + no larger than 512 bytes or IPv6 datagrams no larger than 1280 (the + minimum MTU). \sa readDatagram() */ -qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, - const QHostAddress &host, quint16 port) +qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, const QIpPacketHeader &header) { Q_D(QNativeSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1); Q_CHECK_TYPE(QNativeSocketEngine::writeDatagram(), QAbstractSocket::UdpSocket, -1); - return d->nativeSendDatagram(data, size, d->adjustAddressProtocol(host), port); + + return d->nativeSendDatagram(data, size, header); } /*! -- cgit v1.2.3