X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcorenetwork.cpp;h=8655b110b9ef3c5167285c9cde4382c58ab06f85;hp=512ac104787dfb434e9de0cea4aff62fa4092e99;hb=51b46e3bdedd82eed34844c372efe432ec51d95d;hpb=3146ad01b5b29c30adcf0044a52b39aa7e5796d0 diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index 512ac104..8655b110 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2012 by the Quassel Project * + * Copyright (C) 2005-2014 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -18,6 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ +#include + #include "corenetwork.h" #include "core.h" @@ -40,10 +42,10 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) _lastPingTime(0), _pingCount(0), + _sendPings(false), _requestedUserModes('-') { _autoReconnectTimer.setSingleShot(true); - _socketCloseTimer.setSingleShot(true); connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout())); setPingInterval(networkConfig()->pingInterval()); @@ -80,7 +82,7 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) connect(this, SIGNAL(newEvent(Event *)), coreSession()->eventManager(), SLOT(postEvent(Event *))); if (Quassel::isOptionSet("oidentd")) { - connect(this, SIGNAL(socketInitialized(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16)), Core::instance()->oidentdConfigGenerator(), SLOT(addSocket(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16)), Qt::BlockingQueuedConnection); + connect(this, SIGNAL(socketOpen(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16)), Core::instance()->oidentdConfigGenerator(), SLOT(addSocket(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16)), Qt::BlockingQueuedConnection); connect(this, SIGNAL(socketDisconnected(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16)), Core::instance()->oidentdConfigGenerator(), SLOT(removeSocket(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16))); } } @@ -182,8 +184,13 @@ void CoreNetwork::connectToIrc(bool reconnecting) socket.setProxy(QNetworkProxy::NoProxy); } + enablePingTimeout(); + + // Qt caches DNS entries for a minute, resulting in round-robin (e.g. for chat.freenode.net) not working if several users + // connect at a similar time. QHostInfo::fromName(), however, always performs a fresh lookup, overwriting the cache entry. + QHostInfo::fromName(server.host); + #ifdef HAVE_SSL - socket.setProtocol((QSsl::SslProtocol)server.sslVersion); if (server.useSsl) { CoreIdentity *identity = identityPtr(); if (identity) { @@ -225,17 +232,18 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool _quitReason = reason; displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason)); - switch (socket.state()) { - case QAbstractSocket::ConnectedState: - userInputHandler()->issueQuit(_quitReason); + if (socket.state() == QAbstractSocket::UnconnectedState) { + socketDisconnected(); + } else { + if (socket.state() == QAbstractSocket::ConnectedState) { + userInputHandler()->issueQuit(_quitReason); + } else { + socket.close(); + } if (requested || withReconnect) { // the irc server has 10 seconds to close the socket _socketCloseTimer.start(10000); - break; } - default: - socket.close(); - socketDisconnected(); } } @@ -261,13 +269,16 @@ void CoreNetwork::putCmd(const QString &cmd, const QList ¶ms, co if (!prefix.isEmpty()) msg += ":" + prefix + " "; - msg += cmd.toUpper().toAscii(); + msg += cmd.toUpper().toLatin1(); + + for (int i = 0; i < params.size(); i++) { + msg += " "; - for (int i = 0; i < params.size() - 1; i++) { - msg += " " + params[i]; + if (i == params.size() - 1 && (params[i].contains(' ') || (!params[i].isEmpty() && params[i][0] == ':'))) + msg += ":"; + + msg += params[i]; } - if (!params.isEmpty()) - msg += " :" + params.last(); putRawLine(msg); } @@ -363,6 +374,19 @@ void CoreNetwork::setCipherKey(const QString &target, const QByteArray &key) return; } } + + +bool CoreNetwork::cipherUsesCBC(const QString &target) +{ + CoreIrcChannel *c = qobject_cast(ircChannel(target)); + if (c) + return c->cipher()->usesCBC(); + CoreIrcUser *u = qobject_cast(ircUser(target)); + if (u) + return u->cipher()->usesCBC(); + + return false; +} #endif /* HAVE_QCA2 */ bool CoreNetwork::setAutoWhoDone(const QString &channel) @@ -388,7 +412,10 @@ void CoreNetwork::socketHasData() { while (socket.canReadLine()) { QByteArray s = socket.readLine(); - s.chop(2); + if (s.endsWith("\r\n")) + s.chop(2); + else if (s.endsWith("\n")) + s.chop(1); NetworkDataEvent *event = new NetworkDataEvent(EventManager::NetworkIncoming, this, s); #if QT_VERSION >= 0x040700 event->setTimestamp(QDateTime::currentDateTimeUtc()); @@ -418,18 +445,23 @@ void CoreNetwork::socketError(QAbstractSocket::SocketError error) void CoreNetwork::socketInitialized() { - Server server = usedServer(); -#ifdef HAVE_SSL - if (server.useSsl && !socket.isEncrypted()) - return; -#endif - CoreIdentity *identity = identityPtr(); if (!identity) { qCritical() << "Identity invalid!"; disconnectFromIrc(); return; } + + emit socketOpen(identity, localAddress(), localPort(), peerAddress(), peerPort()); + + Server server = usedServer(); +#ifdef HAVE_SSL + if (server.useSsl && !socket.isEncrypted()) + return; +#endif +#if QT_VERSION >= 0x040600 + socket.setSocketOption(QAbstractSocket::KeepAliveOption, true); +#endif emit socketInitialized(identity, localAddress(), localPort(), peerAddress(), peerPort()); @@ -538,7 +570,7 @@ void CoreNetwork::networkInitialized() sendPerform(); - enablePingTimeout(); + _sendPings = true; if (networkConfig()->autoWhoEnabled()) { _autoWhoCycleTimer.start(); @@ -782,7 +814,9 @@ void CoreNetwork::sendPing() else { _lastPingTime = now; _pingCount++; - userInputHandler()->handlePing(BufferInfo(), QString()); + // Don't send pings until the network is initialized + if(_sendPings) + userInputHandler()->handlePing(BufferInfo(), QString()); } } @@ -802,6 +836,7 @@ void CoreNetwork::enablePingTimeout(bool enable) void CoreNetwork::disablePingTimeout() { _pingTimer.stop(); + _sendPings = false; resetPingTimeout(); }