Changeset View
Changeset View
Standalone View
Standalone View
src/irc/server.cpp
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | |||||
58 | 58 | | |||
59 | Server::Server(QObject* parent, ConnectionSettings& settings) : QObject(parent) | 59 | Server::Server(QObject* parent, ConnectionSettings& settings) : QObject(parent) | ||
60 | { | 60 | { | ||
61 | m_connectionId = m_availableConnectionId; | 61 | m_connectionId = m_availableConnectionId; | ||
62 | m_availableConnectionId++; | 62 | m_availableConnectionId++; | ||
63 | 63 | | |||
64 | setConnectionSettings(settings); | 64 | setConnectionSettings(settings); | ||
65 | 65 | | |||
66 | m_connectionState = Konversation::SSNeverConnected; | 66 | m_connectionState = Server::SSNeverConnected; | ||
67 | 67 | | |||
68 | m_recreationScheduled = false; | 68 | m_recreationScheduled = false; | ||
69 | 69 | | |||
70 | m_delayedConnectTimer = new QTimer(this); | 70 | m_delayedConnectTimer = new QTimer(this); | ||
71 | m_delayedConnectTimer->setSingleShot(true); | 71 | m_delayedConnectTimer->setSingleShot(true); | ||
72 | connect(m_delayedConnectTimer, SIGNAL(timeout()), this, SLOT(connectToIRCServer())); | 72 | connect(m_delayedConnectTimer, SIGNAL(timeout()), this, SLOT(connectToIRCServer())); | ||
73 | 73 | | |||
74 | m_reconnectImmediately = false; | 74 | m_reconnectImmediately = false; | ||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Line(s) | |||||
143 | else | 143 | else | ||
144 | QTimer::singleShot(0, this, SLOT(connectToIRCServer())); | 144 | QTimer::singleShot(0, this, SLOT(connectToIRCServer())); | ||
145 | 145 | | |||
146 | initTimers(); | 146 | initTimers(); | ||
147 | 147 | | |||
148 | if (getIdentity()->getShellCommand().isEmpty()) | 148 | if (getIdentity()->getShellCommand().isEmpty()) | ||
149 | connectSignals(); | 149 | connectSignals(); | ||
150 | // TODO FIXME this disappeared in a merge, ensure it should have | 150 | // TODO FIXME this disappeared in a merge, ensure it should have | ||
151 | updateConnectionState(Konversation::SSNeverConnected); | 151 | updateConnectionState(Server::SSNeverConnected); | ||
152 | 152 | | |||
153 | m_nickInfoChangedTimer = new QTimer(this); | 153 | m_nickInfoChangedTimer = new QTimer(this); | ||
154 | m_nickInfoChangedTimer->setSingleShot(true); | 154 | m_nickInfoChangedTimer->setSingleShot(true); | ||
155 | m_nickInfoChangedTimer->setInterval(3000); | 155 | m_nickInfoChangedTimer->setInterval(3000); | ||
156 | connect(m_nickInfoChangedTimer, SIGNAL(timeout()), this, SLOT(sendNickInfoChangedSignals())); | 156 | connect(m_nickInfoChangedTimer, SIGNAL(timeout()), this, SLOT(sendNickInfoChangedSignals())); | ||
157 | 157 | | |||
158 | m_channelNickChangedTimer = new QTimer(this); | 158 | m_channelNickChangedTimer = new QTimer(this); | ||
159 | m_channelNickChangedTimer->setSingleShot(true); | 159 | m_channelNickChangedTimer->setSingleShot(true); | ||
▲ Show 20 Lines • Show All 290 Lines • ▼ Show 20 Line(s) | 449 | { | |||
450 | qDebug() << "Refusing to connect while SSL lock from previous connection attempt is being held."; | 450 | qDebug() << "Refusing to connect while SSL lock from previous connection attempt is being held."; | ||
451 | 451 | | |||
452 | return; | 452 | return; | ||
453 | } | 453 | } | ||
454 | 454 | | |||
455 | // Reenable check when it works reliably for all backends | 455 | // Reenable check when it works reliably for all backends | ||
456 | // if(Solid::Networking::status() != Solid::Networking::Connected) | 456 | // if(Solid::Networking::status() != Solid::Networking::Connected) | ||
457 | // { | 457 | // { | ||
458 | // updateConnectionState(Konversation::SSInvoluntarilyDisconnected); | 458 | // updateConnectionState(Server::SSInvoluntarilyDisconnected); | ||
459 | // return; | 459 | // return; | ||
460 | // } | 460 | // } | ||
461 | 461 | | |||
462 | updateConnectionState(Konversation::SSConnecting); | 462 | updateConnectionState(Server::SSConnecting); | ||
463 | 463 | | |||
464 | m_ownIpByUserhost.clear(); | 464 | m_ownIpByUserhost.clear(); | ||
465 | 465 | | |||
466 | resetQueues(); | 466 | resetQueues(); | ||
467 | 467 | | |||
468 | // This is needed to support server groups with mixed SSL and nonSSL servers | 468 | // This is needed to support server groups with mixed SSL and nonSSL servers | ||
469 | delete m_socket; | 469 | delete m_socket; | ||
470 | m_socket = nullptr; | 470 | m_socket = nullptr; | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 524 | else | |||
525 | qDebug() << "connectToIRCServer() called while already connected: This should never happen. (" << (isConnecting() << 1) + isConnected() << ')'; | 525 | qDebug() << "connectToIRCServer() called while already connected: This should never happen. (" << (isConnecting() << 1) + isConnected() << ')'; | ||
526 | } | 526 | } | ||
527 | 527 | | |||
528 | void Server::connectToIRCServerIn(uint delay) | 528 | void Server::connectToIRCServerIn(uint delay) | ||
529 | { | 529 | { | ||
530 | m_delayedConnectTimer->setInterval(delay * 1000); | 530 | m_delayedConnectTimer->setInterval(delay * 1000); | ||
531 | m_delayedConnectTimer->start(); | 531 | m_delayedConnectTimer->start(); | ||
532 | 532 | | |||
533 | updateConnectionState(Konversation::SSScheduledToConnect); | 533 | updateConnectionState(Server::SSScheduledToConnect); | ||
534 | } | 534 | } | ||
535 | 535 | | |||
536 | void Server::showSSLDialog() | 536 | void Server::showSSLDialog() | ||
537 | { | 537 | { | ||
538 | //TODO | 538 | //TODO | ||
539 | /* | 539 | /* | ||
540 | SSLSocket* sslsocket = dynamic_cast<SSLSocket*>(m_socket); | 540 | SSLSocket* sslsocket = dynamic_cast<SSLSocket*>(m_socket); | ||
541 | 541 | | |||
▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Line(s) | 879 | { | |||
884 | } else { | 884 | } else { | ||
885 | queue(QStringLiteral("AUTHENTICATE ") + message, HighPriority); | 885 | queue(QStringLiteral("AUTHENTICATE ") + message, HighPriority); | ||
886 | } | 886 | } | ||
887 | } | 887 | } | ||
888 | 888 | | |||
889 | void Server::broken(KTcpSocket::Error error) | 889 | void Server::broken(KTcpSocket::Error error) | ||
890 | { | 890 | { | ||
891 | Q_UNUSED(error); | 891 | Q_UNUSED(error); | ||
892 | qDebug() << "Connection broken with state" << m_connectionState << "and error:" << m_socket->errorString(); | 892 | qDebug() << "Connection broken with state" << static_cast<int>(m_connectionState) << "and error:" << m_socket->errorString(); | ||
893 | 893 | | |||
894 | m_socket->blockSignals(true); | 894 | m_socket->blockSignals(true); | ||
895 | 895 | | |||
896 | resetQueues(); | 896 | resetQueues(); | ||
897 | 897 | | |||
898 | m_notifyTimer.stop(); | 898 | m_notifyTimer.stop(); | ||
899 | m_pingSendTimer.stop(); | 899 | m_pingSendTimer.stop(); | ||
900 | m_pingResponseTimer.stop(); | 900 | m_pingResponseTimer.stop(); | ||
Show All 18 Lines | 914 | { | |||
919 | // reaffirm this. | 919 | // reaffirm this. | ||
920 | 920 | | |||
921 | getStatusView()->appendServerMessage(i18n("SSL Connection Error"), | 921 | getStatusView()->appendServerMessage(i18n("SSL Connection Error"), | ||
922 | i18n("Connection to server %1 (port %2) lost while waiting for user response to an SSL error. " | 922 | i18n("Connection to server %1 (port %2) lost while waiting for user response to an SSL error. " | ||
923 | "Will automatically reconnect if error is ignored.", | 923 | "Will automatically reconnect if error is ignored.", | ||
924 | getConnectionSettings().server().host(), | 924 | getConnectionSettings().server().host(), | ||
925 | QString::number(getConnectionSettings().server().port()))); | 925 | QString::number(getConnectionSettings().server().port()))); | ||
926 | 926 | | |||
927 | updateConnectionState(SSDeliberatelyDisconnected); | 927 | updateConnectionState(Server::SSDeliberatelyDisconnected); | ||
928 | } | 928 | } | ||
929 | else if (getConnectionState() == Konversation::SSDeliberatelyDisconnected) | 929 | else if (getConnectionState() == Server::SSDeliberatelyDisconnected) | ||
930 | { | 930 | { | ||
931 | if (m_reconnectImmediately) | 931 | if (m_reconnectImmediately) | ||
932 | { | 932 | { | ||
933 | m_reconnectImmediately = false; | 933 | m_reconnectImmediately = false; | ||
934 | 934 | | |||
935 | QMetaObject::invokeMethod(this, "connectToIRCServer", Qt::QueuedConnection); | 935 | QMetaObject::invokeMethod(this, "connectToIRCServer", Qt::QueuedConnection); | ||
936 | } | 936 | } | ||
937 | } | 937 | } | ||
938 | else | 938 | else | ||
939 | { | 939 | { | ||
940 | Application::instance()->notificationHandler()->connectionFailure(getStatusView(), getServerName()); | 940 | Application::instance()->notificationHandler()->connectionFailure(getStatusView(), getServerName()); | ||
941 | 941 | | |||
942 | QString error = i18n("Connection to server %1 (port %2) lost: %3.", | 942 | QString error = i18n("Connection to server %1 (port %2) lost: %3.", | ||
943 | getConnectionSettings().server().host(), | 943 | getConnectionSettings().server().host(), | ||
944 | QString::number(getConnectionSettings().server().port()), | 944 | QString::number(getConnectionSettings().server().port()), | ||
945 | m_socket->errorString()); | 945 | m_socket->errorString()); | ||
946 | 946 | | |||
947 | getStatusView()->appendServerMessage(i18n("Error"), error); | 947 | getStatusView()->appendServerMessage(i18n("Error"), error); | ||
948 | 948 | | |||
949 | updateConnectionState(Konversation::SSInvoluntarilyDisconnected); | 949 | updateConnectionState(Server::SSInvoluntarilyDisconnected); | ||
950 | } | 950 | } | ||
951 | 951 | | |||
952 | // HACK Only show one nick change dialog at connection time. | 952 | // HACK Only show one nick change dialog at connection time. | ||
953 | // This hack is a bit nasty as it assumes that the only QInputDialog | 953 | // This hack is a bit nasty as it assumes that the only QInputDialog | ||
954 | // child of the statusview will be the nick change dialog. | 954 | // child of the statusview will be the nick change dialog. | ||
955 | if (getStatusView()) | 955 | if (getStatusView()) | ||
956 | { | 956 | { | ||
957 | QInputDialog* nickChangeDialog = getStatusView()->findChild<QInputDialog*>(); | 957 | QInputDialog* nickChangeDialog = getStatusView()->findChild<QInputDialog*>(); | ||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | 1004 | { | |||
1007 | // any old socket) and crash. | 1007 | // any old socket) and crash. | ||
1008 | QMetaObject::invokeMethod(this, "connectToIRCServer", Qt::QueuedConnection); | 1008 | QMetaObject::invokeMethod(this, "connectToIRCServer", Qt::QueuedConnection); | ||
1009 | } | 1009 | } | ||
1010 | } | 1010 | } | ||
1011 | else | 1011 | else | ||
1012 | { | 1012 | { | ||
1013 | // Don't auto-reconnect if the user chose to ignore the SSL errors -- | 1013 | // Don't auto-reconnect if the user chose to ignore the SSL errors -- | ||
1014 | // treat it as a deliberate disconnect. | 1014 | // treat it as a deliberate disconnect. | ||
1015 | updateConnectionState(Konversation::SSDeliberatelyDisconnected); | 1015 | updateConnectionState(Server::SSDeliberatelyDisconnected); | ||
1016 | 1016 | | |||
1017 | QString errorReason; | 1017 | QString errorReason; | ||
1018 | 1018 | | |||
1019 | for (const auto & error : errors) | 1019 | for (const auto & error : errors) | ||
1020 | { | 1020 | { | ||
1021 | errorReason += error.errorString() + QLatin1Char(' '); | 1021 | errorReason += error.errorString() + QLatin1Char(' '); | ||
1022 | } | 1022 | } | ||
1023 | 1023 | | |||
Show All 11 Lines | |||||
1035 | // Will be called from InputFilter as soon as the Welcome message was received | 1035 | // Will be called from InputFilter as soon as the Welcome message was received | ||
1036 | void Server::connectionEstablished(const QString& ownHost) | 1036 | void Server::connectionEstablished(const QString& ownHost) | ||
1037 | { | 1037 | { | ||
1038 | // Some servers don't include the userhost in RPL_WELCOME, so we | 1038 | // Some servers don't include the userhost in RPL_WELCOME, so we | ||
1039 | // need to use RPL_USERHOST to get ahold of our IP later on | 1039 | // need to use RPL_USERHOST to get ahold of our IP later on | ||
1040 | if (!ownHost.isEmpty()) | 1040 | if (!ownHost.isEmpty()) | ||
1041 | QHostInfo::lookupHost(ownHost, this, SLOT(gotOwnResolvedHostByWelcome(QHostInfo))); | 1041 | QHostInfo::lookupHost(ownHost, this, SLOT(gotOwnResolvedHostByWelcome(QHostInfo))); | ||
1042 | 1042 | | |||
1043 | updateConnectionState(Konversation::SSConnected); | 1043 | updateConnectionState(Server::SSConnected); | ||
1044 | 1044 | | |||
1045 | // Make a helper object to build ISON (notify) list. | 1045 | // Make a helper object to build ISON (notify) list. | ||
1046 | // TODO: Give the object a kick to get it started? | 1046 | // TODO: Give the object a kick to get it started? | ||
1047 | delete m_serverISON; | 1047 | delete m_serverISON; | ||
1048 | m_serverISON = new ServerISON(this); | 1048 | m_serverISON = new ServerISON(this); | ||
1049 | 1049 | | |||
1050 | // get first notify very early | 1050 | // get first notify very early | ||
1051 | startNotifyTimer(1000); | 1051 | startNotifyTimer(1000); | ||
Show All 38 Lines | |||||
1090 | 1090 | | |||
1091 | bool Server::isSocketConnected() const | 1091 | bool Server::isSocketConnected() const | ||
1092 | { | 1092 | { | ||
1093 | if (!m_socket) return false; | 1093 | if (!m_socket) return false; | ||
1094 | 1094 | | |||
1095 | return (m_socket->state() == KTcpSocket::ConnectedState); | 1095 | return (m_socket->state() == KTcpSocket::ConnectedState); | ||
1096 | } | 1096 | } | ||
1097 | 1097 | | |||
1098 | void Server::updateConnectionState(Konversation::ConnectionState state) | 1098 | void Server::updateConnectionState(Server::ConnectionState state) | ||
1099 | { | 1099 | { | ||
1100 | if (state != m_connectionState) | 1100 | if (state != m_connectionState) | ||
1101 | { | 1101 | { | ||
1102 | m_connectionState = state; | 1102 | m_connectionState = state; | ||
1103 | 1103 | | |||
1104 | if (m_connectionState == Konversation::SSConnected) | 1104 | if (m_connectionState == Server::SSConnected) | ||
1105 | emit serverOnline(true); | 1105 | emit serverOnline(true); | ||
1106 | else if (m_connectionState != Konversation::SSConnecting) | 1106 | else if (m_connectionState != Server::SSConnecting) | ||
1107 | emit serverOnline(false); | 1107 | emit serverOnline(false); | ||
1108 | 1108 | | |||
1109 | emit connectionStateChanged(this, state); | 1109 | emit connectionStateChanged(state); | ||
1110 | } | 1110 | } | ||
1111 | } | 1111 | } | ||
1112 | 1112 | | |||
1113 | void Server::reconnectServer(const QString& quitMessage) | 1113 | void Server::reconnectServer(const QString& quitMessage) | ||
1114 | { | 1114 | { | ||
1115 | if (isConnecting() || isSocketConnected()) | 1115 | if (isConnecting() || isSocketConnected()) | ||
1116 | { | 1116 | { | ||
1117 | m_reconnectImmediately = true; | 1117 | m_reconnectImmediately = true; | ||
Show All 17 Lines | 1126 | { | |||
1135 | if (isSocketConnected()) quitServer(quitMessage); | 1135 | if (isSocketConnected()) quitServer(quitMessage); | ||
1136 | } | 1136 | } | ||
1137 | 1137 | | |||
1138 | void Server::quitServer(const QString& quitMessage) | 1138 | void Server::quitServer(const QString& quitMessage) | ||
1139 | { | 1139 | { | ||
1140 | // Make clear this is deliberate even if the QUIT never actually goes through the queue | 1140 | // Make clear this is deliberate even if the QUIT never actually goes through the queue | ||
1141 | // (i.e. this is not redundant with _send_internal()'s updateConnectionState() call for | 1141 | // (i.e. this is not redundant with _send_internal()'s updateConnectionState() call for | ||
1142 | // a QUIT). | 1142 | // a QUIT). | ||
1143 | updateConnectionState(Konversation::SSDeliberatelyDisconnected); | 1143 | updateConnectionState(Server::SSDeliberatelyDisconnected); | ||
1144 | 1144 | | |||
1145 | if (!m_socket) return; | 1145 | if (!m_socket) return; | ||
1146 | 1146 | | |||
1147 | QString toServer = QStringLiteral("QUIT :"); | 1147 | QString toServer = QStringLiteral("QUIT :"); | ||
1148 | 1148 | | |||
1149 | if (quitMessage.isEmpty()) | 1149 | if (quitMessage.isEmpty()) | ||
1150 | toServer += getIdentity()->getQuitReason(); | 1150 | toServer += getIdentity()->getQuitReason(); | ||
1151 | else | 1151 | else | ||
▲ Show 20 Lines • Show All 413 Lines • ▼ Show 20 Line(s) | 1564 | { | |||
1565 | qDebug() << "found \\n on " << outboundCommand; | 1565 | qDebug() << "found \\n on " << outboundCommand; | ||
1566 | outputLine.resize(outputLine.length()-1); | 1566 | outputLine.resize(outputLine.length()-1); | ||
1567 | } | 1567 | } | ||
1568 | 1568 | | |||
1569 | // remember the first arg of /WHO to identify responses | 1569 | // remember the first arg of /WHO to identify responses | ||
1570 | if (outboundCommand == 0 && outputLineSplit.count() >= 2) //"WHO" | 1570 | if (outboundCommand == 0 && outputLineSplit.count() >= 2) //"WHO" | ||
1571 | m_inputFilter.addWhoRequest(outputLineSplit[1]); | 1571 | m_inputFilter.addWhoRequest(outputLineSplit[1]); | ||
1572 | else if (outboundCommand == 1) //"QUIT" | 1572 | else if (outboundCommand == 1) //"QUIT" | ||
1573 | updateConnectionState(Konversation::SSDeliberatelyDisconnected); | 1573 | updateConnectionState(Server::SSDeliberatelyDisconnected); | ||
1574 | 1574 | | |||
1575 | // set channel encoding if specified | 1575 | // set channel encoding if specified | ||
1576 | QString channelCodecName; | 1576 | QString channelCodecName; | ||
1577 | 1577 | | |||
1578 | //[ PRIVMSG | NOTICE | KICK | PART | TOPIC ] target :message | 1578 | //[ PRIVMSG | NOTICE | KICK | PART | TOPIC ] target :message | ||
1579 | if (outputLineSplit.count() > 2 && outboundCommand > 1) | 1579 | if (outputLineSplit.count() > 2 && outboundCommand > 1) | ||
1580 | { | 1580 | { | ||
1581 | if(getServerGroup()) // if we're connecting via a servergroup | 1581 | if(getServerGroup()) // if we're connecting via a servergroup | ||
▲ Show 20 Lines • Show All 2848 Lines • ▼ Show 20 Line(s) | 4418 | { | |||
4430 | } | 4430 | } | ||
4431 | } | 4431 | } | ||
4432 | 4432 | | |||
4433 | m_changedChannels.clear(); | 4433 | m_changedChannels.clear(); | ||
4434 | } | 4434 | } | ||
4435 | 4435 | | |||
4436 | void Server::involuntaryQuit() | 4436 | void Server::involuntaryQuit() | ||
4437 | { | 4437 | { | ||
4438 | if((m_connectionState == Konversation::SSConnected || m_connectionState == Konversation::SSConnecting) && | 4438 | if((m_connectionState == Server::SSConnected || m_connectionState == Server::SSConnecting) && | ||
4439 | (m_socket->peerAddress() != QHostAddress(QHostAddress::LocalHost) && m_socket->peerAddress() != QHostAddress(QHostAddress::LocalHostIPv6))) | 4439 | (m_socket->peerAddress() != QHostAddress(QHostAddress::LocalHost) && m_socket->peerAddress() != QHostAddress(QHostAddress::LocalHostIPv6))) | ||
4440 | { | 4440 | { | ||
4441 | quitServer(); | 4441 | quitServer(); | ||
4442 | updateConnectionState(Konversation::SSInvoluntarilyDisconnected); | 4442 | updateConnectionState(Server::SSInvoluntarilyDisconnected); | ||
4443 | } | 4443 | } | ||
4444 | } | 4444 | } | ||
4445 | 4445 | | |||
4446 | void Server::reconnectInvoluntary() | 4446 | void Server::reconnectInvoluntary() | ||
4447 | { | 4447 | { | ||
4448 | if(m_connectionState == Konversation::SSInvoluntarilyDisconnected) | 4448 | if(m_connectionState == Server::SSInvoluntarilyDisconnected) | ||
4449 | reconnectServer(); | 4449 | reconnectServer(); | ||
4450 | } | 4450 | } | ||
4451 | 4451 | | |||
4452 | 4452 | | |||
4453 | 4453 | | |||
4454 | // kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on; | 4454 | // kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on; | ||
4455 | // vim: set et sw=4 ts=4 cino=l1,cs,U1: | 4455 | // vim: set et sw=4 ts=4 cino=l1,cs,U1: |