/***************************************************************************
- * Copyright (C) 2005-2015 by the Quassel Project *
+ * Copyright (C) 2005-2018 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
CoreNetwork::~CoreNetwork()
{
- if (connectionState() != Disconnected && connectionState() != Network::Reconnecting)
- disconnectFromIrc(false); // clean up, but this does not count as requested disconnect!
+ // Request a proper disconnect, but don't count as user-requested disconnect
+ if (socketConnected()) {
+ // Only try if the socket's fully connected (not initializing or disconnecting).
+ // Force an immediate disconnect, jumping the command queue. Ensures the proper QUIT is
+ // shown even if other messages are queued.
+ disconnectFromIrc(false, QString(), false, true);
+ // Process the putCmd events that trigger the quit. Without this, shutting down the core
+ // results in abrubtly closing the socket rather than sending the QUIT as expected.
+ QCoreApplication::processEvents();
+ // Wait briefly for each network to disconnect. Sometimes it takes a little while to send.
+ if (!forceDisconnect()) {
+ qWarning() << "Timed out quitting network" << networkName() <<
+ "(user ID " << userId() << ")";
+ }
+ }
disconnect(&socket, 0, this, 0); // this keeps the socket from triggering events during clean up
delete _userInputHandler;
}
+bool CoreNetwork::forceDisconnect(int msecs)
+{
+ if (socket.state() == QAbstractSocket::UnconnectedState) {
+ // Socket already disconnected.
+ return true;
+ }
+ // Request a socket-level disconnect if not already happened
+ socket.disconnectFromHost();
+ // Return the result of waiting for disconnect; true if successful, otherwise false
+ return socket.waitForDisconnected(msecs);
+}
+
+
QString CoreNetwork::channelDecode(const QString &bufferName, const QByteArray &string) const
{
if (!bufferName.isEmpty()) {
}
else if (_previousConnectionAttemptFailed) {
// cycle to next server if previous connection attempt failed
+ _previousConnectionAttemptFailed = false;
displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Connection failed. Cycling to next Server"));
if (++_lastUsedServerIndex >= serverList().size()) {
_lastUsedServerIndex = 0;
}
}
- _previousConnectionAttemptFailed = false;
+ else {
+ // Start out with the top server in the list
+ _lastUsedServerIndex = 0;
+ }
Server server = usedServer();
displayStatusMsg(tr("Connecting to %1:%2...").arg(server.host).arg(server.port));
// 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);
-
+ if (! server.useProxy) {
+ //Avoid hostname lookups when a proxy is specified. The lookups won't use the proxy and may therefore leak the DNS
+ //hostname of the server. Qt's DNS cache also isn't used by the proxy so we don't need to refresh the entry.
+ QHostInfo::fromName(server.host);
+ }
#ifdef HAVE_SSL
if (server.useSsl) {
CoreIdentity *identity = identityPtr();