X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fprotocols%2Fdatastream%2Fdatastreampeer.cpp;h=6a21a169b1586cca70582033bcf31939ed0733fe;hp=a1b4e910ef3ed0c0e216838a3660f8441693c75d;hb=258d157a228d2b2b46b01d3b33ab932b9979436a;hpb=89aa3d278f7b5fac996f0b9480737e5932d54c41 diff --git a/src/common/protocols/datastream/datastreampeer.cpp b/src/common/protocols/datastream/datastreampeer.cpp index a1b4e910..6a21a169 100644 --- a/src/common/protocols/datastream/datastreampeer.cpp +++ b/src/common/protocols/datastream/datastreampeer.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2014 by the Quassel Project * + * Copyright (C) 2005-2016 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -19,23 +19,18 @@ ***************************************************************************/ #include - +#include #include #include #include "datastreampeer.h" -#include "quassel.h" using namespace Protocol; -DataStreamPeer::DataStreamPeer(::AuthHandler *authHandler, QTcpSocket *socket, quint16 features, QObject *parent) - : RemotePeer(authHandler, socket, parent), - _blockSize(0) +DataStreamPeer::DataStreamPeer(::AuthHandler *authHandler, QTcpSocket *socket, quint16 features, Compressor::CompressionLevel level, QObject *parent) + : RemotePeer(authHandler, socket, level, parent) { Q_UNUSED(features); - - _stream.setDevice(socket); - _stream.setVersion(QDataStream::Qt_4_2); } @@ -58,93 +53,26 @@ quint16 DataStreamPeer::enabledFeatures() const } -// Note that we're already preparing for readSocketData() moving into RemotePeer, thus the slightly -// cumbersome type and stream handling here. -void DataStreamPeer::onSocketDataAvailable() +void DataStreamPeer::processMessage(const QByteArray &msg) { - // don't try to read more data if we're already closing - if (socket()->state() != QAbstractSocket::ConnectedState) - return; - - QByteArray data; - while (readSocketData(data)) { - // data contains always a serialized QVector - QDataStream stream(data); - stream.setVersion(QDataStream::Qt_4_2); - QVariantList list; - stream >> list; - if (stream.status() != QDataStream::Ok) { - close("Peer sent corrupt data, closing down!"); - return; - } - - // if no sigproxy is set, we're in handshake mode - if (!signalProxy()) - handleHandshakeMessage(list); - else - handlePackedFunc(list); - } -} - - -bool DataStreamPeer::readSocketData(QByteArray &data) -{ - if (_blockSize == 0) { - if (socket()->bytesAvailable() < 4) - return false; - // the block size is part of QByteArray's serialization format, so we don't actually read it now... - socket()->peek((char*)&_blockSize, 4); - _blockSize = qFromBigEndian(_blockSize) + 4; // ... but of course we have to add its size to the total size of the block - } - - if (_blockSize > 1 << 22) { - close("Peer tried to send package larger than max package size!"); - return false; - } - - if (_blockSize == 0) { - close("Peer tried to send 0 byte package!"); - return false; - } - - if (socket()->bytesAvailable() < _blockSize) { - emit transferProgress(socket()->bytesAvailable(), _blockSize); - return false; - } - - emit transferProgress(_blockSize, _blockSize); - - _stream >> data; - _blockSize = 0; - - if (_stream.status() != QDataStream::Ok) { + QDataStream stream(msg); + stream.setVersion(QDataStream::Qt_4_2); + QVariantList list; + stream >> list; + if (stream.status() != QDataStream::Ok) { close("Peer sent corrupt data, closing down!"); - return false; - } - - return true; -} - - -void DataStreamPeer::writeSocketData(const QVariantList &list) -{ - if (!socket()->isOpen()) { - qWarning() << Q_FUNC_INFO << "Can't write to a closed socket!"; return; } - QByteArray data; - QDataStream msgStream(&data, QIODevice::WriteOnly); - msgStream.setVersion(QDataStream::Qt_4_2); - msgStream << list; - - _stream << data; // also writes the block size as part of the serialization format - if (_stream.status() != QDataStream::Ok) - close("Could not serialize data for peer!"); + // if no sigproxy is set, we're in handshake mode + if (!signalProxy()) + handleHandshakeMessage(list); + else + handlePackedFunc(list); } -void DataStreamPeer::writeSocketData(const QVariantMap &handshakeMsg) +void DataStreamPeer::writeMessage(const QVariantMap &handshakeMsg) { QVariantList list; QVariantMap::const_iterator it = handshakeMsg.begin(); @@ -153,10 +81,20 @@ void DataStreamPeer::writeSocketData(const QVariantMap &handshakeMsg) ++it; } - writeSocketData(list); + writeMessage(list); } +void DataStreamPeer::writeMessage(const QVariantList &sigProxyMsg) +{ + QByteArray data; + QDataStream msgStream(&data, QIODevice::WriteOnly); + msgStream.setVersion(QDataStream::Qt_4_2); + msgStream << sigProxyMsg; + + writeMessage(data); +} + /*** Handshake messages ***/ @@ -178,7 +116,7 @@ void DataStreamPeer::handleHandshakeMessage(const QVariantList &mapData) } if (msgType == "ClientInit") { - handle(RegisterClient(m["ClientVersion"].toString(), false)); // UseSsl obsolete + handle(RegisterClient(m["ClientVersion"].toString(), m["ClientDate"].toString(), false)); // UseSsl obsolete } else if (msgType == "ClientInitReject") { @@ -186,12 +124,12 @@ void DataStreamPeer::handleHandshakeMessage(const QVariantList &mapData) } else if (msgType == "ClientInitAck") { - handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), false, QDateTime())); // SupportsSsl and coreStartTime obsolete + handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), false, m["Authenticators"].toList())); // SupportsSsl obsolete } else if (msgType == "CoreSetupData") { QVariantMap map = m["SetupData"].toMap(); - handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["ConnectionProperties"].toMap())); + handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["ConnectionProperties"].toMap(), map["Authenticator"].toString(), map["AuthProperties"].toMap())); } else if (msgType == "CoreSetupReject") { @@ -229,9 +167,9 @@ void DataStreamPeer::dispatch(const RegisterClient &msg) { QVariantMap m; m["MsgType"] = "ClientInit"; m["ClientVersion"] = msg.clientVersion; - m["ClientDate"] = Quassel::buildInfo().buildDate; + m["ClientDate"] = msg.buildDate; - writeSocketData(m); + writeMessage(m); } @@ -240,7 +178,7 @@ void DataStreamPeer::dispatch(const ClientDenied &msg) { m["MsgType"] = "ClientInitReject"; m["Error"] = msg.errorString; - writeSocketData(m); + writeMessage(m); } @@ -249,9 +187,10 @@ void DataStreamPeer::dispatch(const ClientRegistered &msg) { m["MsgType"] = "ClientInitAck"; m["CoreFeatures"] = msg.coreFeatures; m["StorageBackends"] = msg.backendInfo; + m["Authenticators"] = msg.authenticatorInfo; m["LoginEnabled"] = m["Configured"] = msg.coreConfigured; - writeSocketData(m); + writeMessage(m); } @@ -263,10 +202,15 @@ void DataStreamPeer::dispatch(const SetupData &msg) map["Backend"] = msg.backend; map["ConnectionProperties"] = msg.setupData; + // Auth backend properties. + map["Authenticator"] = msg.authenticator; + map["AuthProperties"] = msg.authSetupData; + QVariantMap m; m["MsgType"] = "CoreSetupData"; m["SetupData"] = map; - writeSocketData(m); + + writeMessage(m); } @@ -276,7 +220,7 @@ void DataStreamPeer::dispatch(const SetupFailed &msg) m["MsgType"] = "CoreSetupReject"; m["Error"] = msg.errorString; - writeSocketData(m); + writeMessage(m); } @@ -287,7 +231,7 @@ void DataStreamPeer::dispatch(const SetupDone &msg) QVariantMap m; m["MsgType"] = "CoreSetupAck"; - writeSocketData(m); + writeMessage(m); } @@ -298,7 +242,7 @@ void DataStreamPeer::dispatch(const Login &msg) m["User"] = msg.user; m["Password"] = msg.password; - writeSocketData(m); + writeMessage(m); } @@ -308,7 +252,7 @@ void DataStreamPeer::dispatch(const LoginFailed &msg) m["MsgType"] = "ClientLoginReject"; m["Error"] = msg.errorString; - writeSocketData(m); + writeMessage(m); } @@ -319,7 +263,7 @@ void DataStreamPeer::dispatch(const LoginSuccess &msg) QVariantMap m; m["MsgType"] = "ClientLoginAck"; - writeSocketData(m); + writeMessage(m); } @@ -334,7 +278,7 @@ void DataStreamPeer::dispatch(const SessionState &msg) map["Identities"] = msg.identities; m["SessionState"] = map; - writeSocketData(m); + writeMessage(m); } @@ -383,13 +327,15 @@ void DataStreamPeer::handlePackedFunc(const QVariantList &packedFunc) break; } case InitData: { - if (params.count() != 3) { + if (params.count() < 2) { qWarning() << Q_FUNC_INFO << "Received invalid InitData:" << params; return; } - QByteArray className = params[0].toByteArray(); - QString objectName = QString::fromUtf8(params[1].toByteArray()); - QVariantMap initData = params[2].toMap(); + QByteArray className = params.takeFirst().toByteArray(); + QString objectName = QString::fromUtf8(params.takeFirst().toByteArray()); + QVariantMap initData; + for (int i = 0; i < params.count()/2; ++i) + initData[QString::fromUtf8(params[2*i].toByteArray())] = params[2*i+1]; handle(Protocol::InitData(className, objectName, initData)); break; } @@ -436,7 +382,13 @@ void DataStreamPeer::dispatch(const Protocol::InitRequest &msg) void DataStreamPeer::dispatch(const Protocol::InitData &msg) { - dispatchPackedFunc(QVariantList() << (qint16)InitData << msg.className << msg.objectName.toUtf8() << msg.initData); + QVariantList initData; + QVariantMap::const_iterator it = msg.initData.begin(); + while (it != msg.initData.end()) { + initData << it.key().toUtf8() << it.value(); + ++it; + } + dispatchPackedFunc(QVariantList() << (qint16)InitData << msg.className << msg.objectName.toUtf8() << initData); } @@ -454,5 +406,5 @@ void DataStreamPeer::dispatch(const Protocol::HeartBeatReply &msg) void DataStreamPeer::dispatchPackedFunc(const QVariantList &packedFunc) { - writeSocketData(packedFunc); + writeMessage(packedFunc); }