_autoReconnectCount(0)
{
_autoReconnectTimer.setSingleShot(true);
-
+ _previousConnectionAttemptFailed = false;
+ _lastUsedServerlistIndex = 0;
// TODO make configurable
_whoTimer.setInterval(60 * 1000);
_whoTimer.setSingleShot(false);
connect(network, SIGNAL(autoReconnectIntervalSet(quint32)), this, SLOT(autoReconnectSettingsChanged()));
connect(network, SIGNAL(autoReconnectRetriesSet(quint16)), this, SLOT(autoReconnectSettingsChanged()));
+#ifndef QT_NO_OPENSSL
+ connect(&socket, SIGNAL(encrypted()), this, SLOT(socketEncrypted()));
+ connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
+#endif
connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected()));
+
connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));
connect(_ircServerHandler, SIGNAL(nickChanged(const QString &, const QString &)),
this, SLOT(nickChanged(const QString &, const QString &)));
+
+ network->proxy()->attachSignal(this, SIGNAL(sslErrors(const QVariant &)));
}
NetworkConnection::~NetworkConnection() {
qWarning() << "Invalid identity configures, ignoring connect request!";
return;
}
- // TODO implement cycling / random servers
- QString host = serverList[0].toMap()["Host"].toString();
- quint16 port = serverList[0].toMap()["Port"].toUInt();
+ // use a random server?
+ if(network()->useRandomServer()) {
+ _lastUsedServerlistIndex = qrand() % serverList.size();
+ } else if(_previousConnectionAttemptFailed) {
+ // cycle to next server if previous connection attempt failed
+ displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Connection failed. Cycling to next Server"));
+ if(++_lastUsedServerlistIndex == serverList.size()) {
+ _lastUsedServerlistIndex = 0;
+ }
+ }
+ _previousConnectionAttemptFailed = false;
+
+ QString host = serverList[_lastUsedServerlistIndex].toMap()["Host"].toString();
+ quint16 port = serverList[_lastUsedServerlistIndex].toMap()["Port"].toUInt();
displayStatusMsg(tr("Connecting to %1:%2...").arg(host).arg(port));
displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Connecting to %1:%2...").arg(host).arg(port));
socket.connectToHost(host, port);
}
void NetworkConnection::socketError(QAbstractSocket::SocketError) {
+ _previousConnectionAttemptFailed = true;
qDebug() << qPrintable(tr("Could not connect to %1 (%2)").arg(network()->networkName(), socket.errorString()));
emit connectionError(socket.errorString());
emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString()));
setConnectionState(Network::Disconnected);
socketDisconnected();
}
+ // mark last connection attempt as failed
+
//qDebug() << "exiting...";
//exit(1);
}
+#ifndef QT_NO_OPENSSL
+
+void NetworkConnection::sslErrors(const QList<QSslError> &errors) {
+ socket.ignoreSslErrors();
+ /* TODO errorhandling
+ QVariantMap errmsg;
+ QVariantList errnums;
+ foreach(QSslError err, errors) errnums << err.error();
+ errmsg["SslErrors"] = errnums;
+ errmsg["SslCert"] = socket.peerCertificate().toPem();
+ errmsg["PeerAddress"] = socket.peerAddress().toString();
+ errmsg["PeerPort"] = socket.peerPort();
+ errmsg["PeerName"] = socket.peerName();
+ emit sslErrors(errmsg);
+ disconnectFromIrc();
+ */
+}
+
+void NetworkConnection::socketEncrypted() {
+ //qDebug() << "encrypted!";
+ socketInitialized();
+}
+
+#endif // QT_NO_OPENSSL
+
void NetworkConnection::socketConnected() {
+#ifdef QT_NO_OPENSSL
+ socketInitialized();
+ return;
+#else
+ if(!network()->serverList()[_lastUsedServerlistIndex].toMap()["UseSSL"].toBool()) {
+ socketInitialized();
+ return;
+ }
+ //qDebug() << "starting handshake";
+ socket.startClientEncryption();
+#endif
+}
+
+void NetworkConnection::socketInitialized() {
//emit connected(networkId()); initialize first!
Identity *identity = coreSession()->identity(network()->identity());
if(!identity) {
disconnectFromIrc();
return;
}
+ QString passwd = network()->serverList()[_lastUsedServerlistIndex].toMap()["Password"].toString();
+ if(!passwd.isEmpty()) {
+ putRawLine(serverEncode(QString("PASS %1").arg(passwd)));
+ }
putRawLine(serverEncode(QString("NICK :%1").arg(identity->nicks()[0]))); // FIXME: try more nicks if error occurs
putRawLine(serverEncode(QString("USER %1 8 * :%2").arg(identity->ident(), identity->realName())));
}