summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/socket/qabstractsocketengine_p.h38
-rw-r--r--src/network/socket/qhttpsocketengine.cpp6
-rw-r--r--src/network/socket/qhttpsocketengine_p.h7
-rw-r--r--src/network/socket/qnativesocketengine.cpp48
-rw-r--r--src/network/socket/qnativesocketengine_p.h14
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp16
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp14
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp21
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h9
-rw-r--r--src/network/socket/qsocks5socketengine.cpp18
-rw-r--r--src/network/socket/qsocks5socketengine_p.h7
-rw-r--r--src/network/socket/qudpsocket.cpp17
-rw-r--r--tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp33
-rw-r--r--tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp14
14 files changed, 161 insertions, 101 deletions
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index f2a3149678..c485e80f5d 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -58,6 +59,26 @@ class QNetworkInterface;
#endif
class QNetworkProxy;
+class QIpPacketHeader
+{
+public:
+ QIpPacketHeader(const QHostAddress &dstAddr = QHostAddress(), quint16 port = 0)
+ : destinationAddress(dstAddr), destinationPort(port)
+ {}
+
+ void clear()
+ {
+ senderAddress.clear();
+ destinationAddress.clear();
+ }
+
+ QHostAddress senderAddress;
+ QHostAddress destinationAddress;
+
+ quint16 senderPort;
+ quint16 destinationPort;
+};
+
class QAbstractSocketEngineReceiver {
public:
virtual ~QAbstractSocketEngineReceiver(){}
@@ -96,6 +117,14 @@ public:
TypeOfServiceOption
};
+ enum PacketHeaderOption {
+ WantNone = 0,
+ WantDatagramSender,
+
+ WantAll = 0xff
+ };
+ Q_DECLARE_FLAGS(PacketHeaderOptions, PacketHeaderOption)
+
virtual bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) = 0;
virtual bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) = 0;
@@ -126,10 +155,9 @@ public:
virtual bool setMulticastInterface(const QNetworkInterface &iface) = 0;
#endif // QT_NO_NETWORKINTERFACE
- virtual qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0) = 0;
- virtual qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port) = 0;
+ virtual qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header = 0,
+ PacketHeaderOptions = WantNone) = 0;
+ virtual qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header) = 0;
virtual bool hasPendingDatagrams() const = 0;
virtual qint64 pendingDatagramSize() const = 0;
#endif // QT_NO_UDPSOCKET
@@ -225,6 +253,8 @@ private:
friend class QAbstractSocketEngine;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSocketEngine::PacketHeaderOptions)
+
QT_END_NAMESPACE
#endif // QABSTRACTSOCKETENGINE_P_H
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 23347ce08b..1a90abd22c 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -271,14 +271,12 @@ bool QHttpSocketEngine::setMulticastInterface(const QNetworkInterface &)
}
#endif // QT_NO_NETWORKINTERFACE
-qint64 QHttpSocketEngine::readDatagram(char *, qint64, QHostAddress *,
- quint16 *)
+qint64 QHttpSocketEngine::readDatagram(char *, qint64, QIpPacketHeader *, PacketHeaderOptions)
{
return 0;
}
-qint64 QHttpSocketEngine::writeDatagram(const char *, qint64, const QHostAddress &,
- quint16)
+qint64 QHttpSocketEngine::writeDatagram(const char *, qint64, const QIpPacketHeader &)
{
return 0;
}
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index 4d90487679..41c63fe11e 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -105,10 +105,9 @@ public:
bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
#endif // QT_NO_NETWORKINTERFACE
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port) Q_DECL_OVERRIDE;
+ qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *,
+ PacketHeaderOptions) Q_DECL_OVERRIDE;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
#endif // QT_NO_UDPSOCKET
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 <qabstracteventdispatcher.h>
@@ -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);
}
/*!
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index 653309302c..fb36ce6204 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -133,10 +133,9 @@ public:
qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port) Q_DECL_OVERRIDE;
+ qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
+ PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
@@ -242,10 +241,9 @@ public:
bool nativeHasPendingDatagrams() const;
qint64 nativePendingDatagramSize() const;
- qint64 nativeReceiveDatagram(char *data, qint64 maxLength,
- QHostAddress *address, quint16 *port);
- qint64 nativeSendDatagram(const char *data, qint64 length,
- const QHostAddress &host, quint16 port);
+ qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
+ QAbstractSocketEngine::PacketHeaderOptions options);
+ qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header);
qint64 nativeRead(char *data, qint64 maxLength);
qint64 nativeWrite(const char *data, qint64 length);
int nativeSelect(int timeout, bool selectForRead) const;
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 5c4e4e885b..0e04096296 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -844,8 +844,8 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
return qint64(recvResult);
}
-qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize,
- QHostAddress *address, quint16 *port)
+qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize, QIpPacketHeader *header,
+ QAbstractSocketEngine::PacketHeaderOptions options)
{
qt_sockaddr aa;
memset(&aa, 0, sizeof(aa));
@@ -861,8 +861,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
if (recvFromResult == -1) {
setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
- } else if (port || address) {
- qt_socket_getPortAndAddress(&aa, port, address);
+ if (header)
+ header->clear();
+ } else if (options != QAbstractSocketEngine::WantNone) {
+ Q_ASSERT(header);
+ qt_socket_getPortAndAddress(&aa, &header->senderPort, &header->senderAddress);
}
#if defined (QNATIVESOCKETENGINE_DEBUG)
@@ -875,14 +878,15 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
return qint64(maxSize ? recvFromResult : recvFromResult == -1 ? -1 : 0);
}
-qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len,
- const QHostAddress &host, quint16 port)
+qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len, const QIpPacketHeader &header)
{
struct sockaddr_in sockAddrIPv4;
struct sockaddr *sockAddrPtr = 0;
QT_SOCKLEN_T sockAddrSize = 0;
struct sockaddr_in6 sockAddrIPv6;
+ const QHostAddress &host = header.destinationAddress;
+ quint16 port = header.destinationPort;
if (host.protocol() == QAbstractSocket::IPv6Protocol
|| socketProtocol == QAbstractSocket::IPv6Protocol
|| socketProtocol == QAbstractSocket::AnyIPProtocol) {
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 8c3f68f04f..ed376eed95 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -1197,8 +1197,8 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
}
-qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxLength,
- QHostAddress *address, quint16 *port)
+qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
+ QAbstractSocketEngine::PacketHeaderOptions options)
{
qint64 ret = 0;
@@ -1232,12 +1232,15 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
WS_ERROR_DEBUG(err);
setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
ret = -1;
+ if (header)
+ header->clear();
}
} else {
ret = qint64(bytesRead);
+ if (options & QNativeSocketEngine::WantDatagramSender)
+ qt_socket_getPortAndAddress(socketDescriptor, &aa, &header->senderPort, &header->senderAddress);
}
- qt_socket_getPortAndAddress(socketDescriptor, &aa, port, address);
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li",
@@ -1251,7 +1254,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len,
- const QHostAddress &address, quint16 port)
+ const QIpPacketHeader &header)
{
qint64 ret = -1;
struct sockaddr_in sockAddrIPv4;
@@ -1259,7 +1262,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
struct sockaddr *sockAddrPtr = 0;
QT_SOCKLEN_T sockAddrSize = 0;
- setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
+ setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, header.destinationPort,
+ header.destinationAddress, &sockAddrPtr, &sockAddrSize);
WSABUF buf;
#if !defined(Q_OS_WINCE)
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 2d04946601..4a92ca5a95 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -538,18 +538,19 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 len)
return bytesWritten;
}
-qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr, quint16 *port)
+qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header,
+ PacketHeaderOptions options)
{
Q_D(QNativeSocketEngine);
- if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty())
+ if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) {
+ if (header)
+ header->clear();
return -1;
+ }
WinRtDatagram datagram = d->pendingDatagrams.takeFirst();
- if (addr)
- *addr = datagram.address;
-
- if (port)
- *port = datagram.port;
+ if (header)
+ *header = datagram.header;
QByteArray readOrigin;
// Do not read the whole datagram. Put the rest of it back into the "queue"
@@ -564,7 +565,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress
return readOrigin.length();
}
-qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QHostAddress &addr, quint16 port)
+qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header)
{
Q_D(QNativeSocketEngine);
if (d->socketType != QAbstractSocket::UdpSocket)
@@ -1230,11 +1231,11 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I
remoteHost->get_CanonicalName(remoteHostString.GetAddressOf());
RETURN_OK_IF_FAILED("Could not obtain remote host's canonical name");
returnAddress.setAddress(qt_QStringFromHString(remoteHostString));
- datagram.address = returnAddress;
+ datagram.header.senderAddress = returnAddress;
HString remotePort;
hr = args->get_RemotePort(remotePort.GetAddressOf());
RETURN_OK_IF_FAILED("Could not obtain remote port");
- datagram.port = qt_QStringFromHString(remotePort).toInt();
+ datagram.header.senderPort = qt_QStringFromHString(remotePort).toInt();
ComPtr<IDataReader> reader;
hr = args->GetDataReader(&reader);
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
index eb032bc977..4286ff6373 100644
--- a/src/network/socket/qnativesocketengine_winrt_p.h
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -58,8 +58,7 @@ class QNativeSocketEnginePrivate;
struct WinRtDatagram {
QByteArray data;
- int port;
- QHostAddress address;
+ QIpPacketHeader header;
};
class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
@@ -97,10 +96,8 @@ public:
qint64 read(char *data, qint64 maxlen);
qint64 write(const char *data, qint64 len);
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0);
- qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port);
+ qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *, PacketHeaderOptions);
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header);
bool hasPendingDatagrams() const;
qint64 pendingDatagramSize() const;
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index a6eafd2601..26543883cc 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -1383,7 +1383,7 @@ bool QSocks5SocketEngine::bind(const QHostAddress &addr, quint16 port)
#endif
dummy.setProxy(QNetworkProxy::NoProxy);
if (!dummy.bind()
- || writeDatagram(0,0, d->data->controlSocket->localAddress(), dummy.localPort()) != 0
+ || writeDatagram(0,0, QIpPacketHeader(d->data->controlSocket->localAddress(), dummy.localPort())) != 0
|| !dummy.waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))
|| dummy.readDatagram(0,0, &d->localAddress, &d->localPort) != 0) {
QSOCKS5_DEBUG << "udp actual address and port lookup failed";
@@ -1555,7 +1555,7 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len)
#ifndef QT_NO_UDPSOCKET
} else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
// send to connected address
- return writeDatagram(data, len, d->peerAddress, d->peerPort);
+ return writeDatagram(data, len, QIpPacketHeader(d->peerAddress, d->peerPort));
#endif
}
//### set an error ???
@@ -1594,8 +1594,7 @@ bool QSocks5SocketEngine::setMulticastInterface(const QNetworkInterface &)
}
#endif // QT_NO_NETWORKINTERFACE
-qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr,
- quint16 *port)
+qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header, PacketHeaderOptions)
{
Q_D(QSocks5SocketEngine);
@@ -1607,15 +1606,12 @@ qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress
QSocks5RevivedDatagram datagram = d->udpData->pendingDatagrams.dequeue();
int copyLen = qMin<int>(maxlen, datagram.data.size());
memcpy(data, datagram.data.constData(), copyLen);
- if (addr)
- *addr = datagram.address;
- if (port)
- *port = datagram.port;
+ header->senderAddress = datagram.address;
+ header->senderPort = datagram.port;
return copyLen;
}
-qint64 QSocks5SocketEngine::writeDatagram(const char *data, qint64 len, const QHostAddress &address,
- quint16 port)
+qint64 QSocks5SocketEngine::writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header)
{
Q_D(QSocks5SocketEngine);
@@ -1634,7 +1630,7 @@ qint64 QSocks5SocketEngine::writeDatagram(const char *data, qint64 len, const QH
outBuf[0] = 0x00;
outBuf[1] = 0x00;
outBuf[2] = 0x00;
- if (!qt_socks5_set_host_address_and_port(address, port, &outBuf)) {
+ if (!qt_socks5_set_host_address_and_port(header.destinationAddress, header.destinationPort, &outBuf)) {
}
outBuf += QByteArray(data, len);
QSOCKS5_DEBUG << "sending" << dump(outBuf);
diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h
index c97b0e89ce..de20e0ef0e 100644
--- a/src/network/socket/qsocks5socketengine_p.h
+++ b/src/network/socket/qsocks5socketengine_p.h
@@ -93,10 +93,9 @@ public:
bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
#endif // QT_NO_NETWORKINTERFACE
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port) Q_DECL_OVERRIDE;
+ qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
+ PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
#endif // QT_NO_UDPSOCKET
diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index 87686f94e1..f4e7d20b03 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -333,7 +333,7 @@ qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddre
if (state() == UnconnectedState)
bind();
- qint64 sent = d->socketEngine->writeDatagram(data, size, address, port);
+ qint64 sent = d->socketEngine->writeDatagram(data, size, QIpPacketHeader(address, port));
d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
if (sent >= 0) {
@@ -379,7 +379,20 @@ qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *addres
qDebug("QUdpSocket::readDatagram(%p, %llu, %p, %p)", data, maxSize, address, port);
#endif
QT_CHECK_BOUND("QUdpSocket::readDatagram()", -1);
- qint64 readBytes = d->socketEngine->readDatagram(data, maxSize, address, port);
+
+ qint64 readBytes;
+ if (address || port) {
+ QIpPacketHeader header;
+ readBytes = d->socketEngine->readDatagram(data, maxSize, &header,
+ QAbstractSocketEngine::WantDatagramSender);
+ if (address)
+ *address = header.senderAddress;
+ if (port)
+ *port = header.senderPort;
+ } else {
+ readBytes = d->socketEngine->readDatagram(data, maxSize);
+ }
+
d_func()->socketEngine->setReadNotificationEnabled(true);
if (readBytes < 0) {
d->socketError = d->socketEngine->error();
diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
index 44081d474f..7669aff66a 100644
--- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
+++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
@@ -243,13 +243,13 @@ void tst_PlatformSocketEngine::udpLoopbackTest()
QVERIFY(available > 0);
QByteArray answer;
answer.resize(available);
- QHostAddress senderAddress;
- quint16 senderPort = 0;
- QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(),
- &senderAddress,
- &senderPort) == message1.size());
- QCOMPARE(senderAddress, QHostAddress("127.0.0.1"));
- QVERIFY(senderPort != 0);
+ QIpPacketHeader header;
+ QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
+ &header, QAbstractSocketEngine::WantDatagramSender),
+ qint64(message1.size()));
+ QVERIFY(header.senderAddress == QHostAddress("127.0.0.1"));
+ QCOMPARE(header.senderAddress, QHostAddress("127.0.0.1"));
+ QVERIFY(header.senderPort != 0);
}
//---------------------------------------------------------------------------
@@ -291,13 +291,13 @@ void tst_PlatformSocketEngine::udpIPv6LoopbackTest()
QVERIFY(available > 0);
QByteArray answer;
answer.resize(available);
- QHostAddress senderAddress;
- quint16 senderPort = 0;
- QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(),
- &senderAddress,
- &senderPort) == message1.size());
- QCOMPARE(senderAddress, QHostAddress("::1"));
- QVERIFY(senderPort != 0);
+ QIpPacketHeader header;
+ QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
+ &header, QAbstractSocketEngine::WantDatagramSender),
+ qint64(message1.size()));
+ QVERIFY(header.senderAddress == QHostAddress("::1"));
+ QCOMPARE(header.senderAddress, QHostAddress("::1"));
+ QVERIFY(header.senderPort != 0);
}
}
@@ -323,8 +323,7 @@ void tst_PlatformSocketEngine::broadcastTest()
= "MOOT wtf is a MOOT? talk english not your sutpiD ENGLISH.";
qint64 written = broadcastSocket.writeDatagram(trollMessage.data(),
trollMessage.size(),
- QHostAddress::Broadcast,
- port);
+ QIpPacketHeader(QHostAddress::Broadcast, port));
QCOMPARE((int)written, trollMessage.size());
@@ -636,7 +635,7 @@ void tst_PlatformSocketEngine::invalidSend()
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::writeDatagram() was"
" called by a socket other than QAbstractSocket::UdpSocket");
- QCOMPARE(socket.writeDatagram("hei", 3, QHostAddress::LocalHost, 143),
+ QCOMPARE(socket.writeDatagram("hei", 3, QIpPacketHeader(QHostAddress::LocalHost, 143)),
(qlonglong) -1);
}
diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp
index 66fd74017e..8da656aab7 100644
--- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp
+++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp
@@ -591,13 +591,13 @@ void tst_QSocks5SocketEngine::udpTest()
QVERIFY(available > 0);
QByteArray answer;
answer.resize(available);
- QHostAddress senderAddress;
- quint16 senderPort = 0;
- QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(),
- &senderAddress,
- &senderPort) == message1.size());
- QCOMPARE(senderAddress, udpSocket2.localAddress());
- QCOMPARE(senderPort, udpSocket2.localPort());
+ QIpPacketHeader header;
+ QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
+ &header, QAbstractSocketEngine::WantDatagramSender),
+ qint64(message1.size()));
+ QVERIFY(header.senderAddress == udpSocket2.localAddress());
+ QCOMPARE(header.senderAddress, udpSocket2.localAddress());
+ QCOMPARE(header.senderPort, udpSocket2.localPort());
}
void tst_QSocks5SocketEngine::tcpSocketBlockingTest()