aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppSocks.cpp
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2015-08-15 01:17:55 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2015-08-15 01:17:55 +0200
commitc7edb89abbb38c432667de15181b4cee6f14577e (patch)
tree942d5c2ff728375b6d6320c62b85dd98f8c4f2cf /src/base/QXmppSocks.cpp
parentad1cf20d2ad46099d4de8dbeda1db51e91efcd7a (diff)
downloadqxmpp-c7edb89abbb38c432667de15181b4cee6f14577e.tar.gz
correctly receive data immediately following a SOCKS5 message (closes #64)
The SOCKS5 client and server would discard any currently buffered received data when processing a SOCKS5 command as they used readAll(). Now they only consume the SOCKS5 command's bytes, preserving any buffered data. Why this situation should occur is a different matter, I would be surprised to see it happen during file transfer, due to the sequence in which the handshake is performed.
Diffstat (limited to 'src/base/QXmppSocks.cpp')
-rw-r--r--src/base/QXmppSocks.cpp31
1 files changed, 15 insertions, 16 deletions
diff --git a/src/base/QXmppSocks.cpp b/src/base/QXmppSocks.cpp
index 905b7a1b..13f040c3 100644
--- a/src/base/QXmppSocks.cpp
+++ b/src/base/QXmppSocks.cpp
@@ -79,26 +79,23 @@ static QByteArray encodeHostAndPort(quint8 type, const QByteArray &host, quint16
return buffer;
}
-static bool parseHostAndPort(const QByteArray buffer, quint8 &type, QByteArray &host, quint16 &port)
+static bool parseHostAndPort(QDataStream &stream, quint8 &type, QByteArray &host, quint16 &port)
{
- if (buffer.size() < 4)
- return false;
-
- QDataStream stream(buffer);
// get host name
quint8 hostLength;
stream >> type;
stream >> hostLength;
- if (buffer.size() < hostLength + 4)
- {
+ if (stream.status() != QDataStream::Ok)
+ return false;
+ host.resize(hostLength);
+ if (stream.readRawData(host.data(), hostLength) != hostLength) {
qWarning("Invalid host length");
return false;
}
- host.resize(hostLength);
- stream.readRawData(host.data(), hostLength);
+
// get port
stream >> port;
- return true;
+ return stream.status() == QDataStream::Ok;
}
QXmppSocksClient::QXmppSocksClient(const QString &proxyHost, quint16 proxyPort, QObject *parent)
@@ -166,8 +163,8 @@ void QXmppSocksClient::slotReadyRead()
disconnect(this, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
// receive CONNECT response
- QByteArray buffer = readAll();
- if (buffer.size() < 6 ||
+ QByteArray buffer = read(3);
+ if (buffer.size() != 3 ||
buffer.at(0) != SocksVersion ||
buffer.at(1) != Succeeded ||
buffer.at(2) != 0)
@@ -181,7 +178,8 @@ void QXmppSocksClient::slotReadyRead()
quint8 hostType;
QByteArray hostName;
quint16 hostPort;
- if (!parseHostAndPort(buffer.mid(3), hostType, hostName, hostPort))
+ QDataStream stream(this);
+ if (!parseHostAndPort(stream, hostType, hostName, hostPort))
{
qWarning("QXmppSocksClient could not parse type/host/port");
close();
@@ -297,8 +295,8 @@ void QXmppSocksServer::slotReadyRead()
disconnect(socket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
// receive command
- QByteArray buffer = socket->readAll();
- if (buffer.size() < 4 ||
+ QByteArray buffer = socket->read(3);
+ if (buffer.size() != 3 ||
buffer.at(0) != SocksVersion ||
buffer.at(1) != ConnectCommand ||
buffer.at(2) != 0x00)
@@ -312,7 +310,8 @@ void QXmppSocksServer::slotReadyRead()
quint8 hostType;
QByteArray hostName;
quint16 hostPort;
- if (!parseHostAndPort(buffer.mid(3), hostType, hostName, hostPort))
+ QDataStream stream(socket);
+ if (!parseHostAndPort(stream, hostType, hostName, hostPort))
{
qWarning("QXmppSocksServer could not parse type/host/port");
socket->close();