OpenVpn runtime error codes handling

This commit is contained in:
pokamest 2021-01-08 16:51:58 +03:00
parent f45fb442de
commit 861c71e3a8
11 changed files with 59 additions and 26 deletions

View file

@ -45,7 +45,7 @@ void Communicator::onLineAvailable(const QString& line)
emit messageReceived(message); emit messageReceived(message);
} }
bool Communicator::connected() const bool Communicator::isConnected() const
{ {
if (!m_localClient) { if (!m_localClient) {
return false; return false;
@ -66,7 +66,7 @@ bool Communicator::writeData(const QString& data)
void Communicator::sendMessage(const Message& message) void Communicator::sendMessage(const Message& message)
{ {
if (!connected()) { if (!isConnected()) {
return; return;
} }
const QString data = message.toString(); const QString data = message.toString();

View file

@ -16,7 +16,7 @@ public:
explicit Communicator(QObject* parent = nullptr); explicit Communicator(QObject* parent = nullptr);
~Communicator(); ~Communicator();
bool connected() const; bool isConnected() const;
void sendMessage(const Message& message); void sendMessage(const Message& message);
signals: signals:

View file

@ -47,9 +47,13 @@ enum ErrorCode
EasyRsaError, EasyRsaError,
// Distro errors // Distro errors
AmneziaServiceConnectionFailed,
OpenVpnExecutableMissing, OpenVpnExecutableMissing,
EasyRsaExecutableMissing EasyRsaExecutableMissing,
AmneziaServiceConnectionFailed,
// VPN errors
OpenVpnAdaptersInUseError,
OpenVpnUnknownError
}; };
} // namespace amnezia } // namespace amnezia

View file

@ -31,12 +31,17 @@ QString errorString(ErrorCode code){
// Local errors // Local errors
case (FailedToSaveConfigData): return QObject::tr("Failed to save config to disk"); case (FailedToSaveConfigData): return QObject::tr("Failed to save config to disk");
case (OpenVpnConfigMissing): return QObject::tr("OpenVPN config missing"); case (OpenVpnConfigMissing): return QObject::tr("OpenVPN config missing");
case (OpenVpnManagementServerError): return QObject::tr("OpenVpn management server error"); case (OpenVpnManagementServerError): return QObject::tr("OpenVPN management server error");
case (EasyRsaError): return QObject::tr("EasyRSA runtime error");
// Distro errors
case (OpenVpnExecutableMissing): return QObject::tr("OpenVPN executable missing"); case (OpenVpnExecutableMissing): return QObject::tr("OpenVPN executable missing");
case (EasyRsaExecutableMissing): return QObject::tr("EasyRsa executable missing"); case (EasyRsaExecutableMissing): return QObject::tr("EasyRsa executable missing");
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error"); case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
// VPN errors
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
case(InternalError): case(InternalError):
default: default:
return QObject::tr("Internal error"); return QObject::tr("Internal error");

View file

@ -119,7 +119,7 @@ ErrorCode OpenVpnProtocol::start()
m_openVpnStateSigTermHandlerTimer.stop(); m_openVpnStateSigTermHandlerTimer.stop();
stop(); stop();
if (communicator() && !communicator()->connected()) { if (communicator() && !communicator()->isConnected()) {
setLastError(ErrorCode::AmneziaServiceConnectionFailed); setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return lastError(); return lastError();
} }
@ -213,6 +213,16 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer()
} }
} }
if (line.contains("FATAL")) {
if (line.contains("tap-windows6 adapters on this system are currently in use or disabled")) {
emit protocolError(ErrorCode::OpenVpnAdaptersInUseError);
}
else {
emit protocolError(ErrorCode::OpenVpnUnknownError);
}
}
QByteArray data(line.toStdString().c_str()); QByteArray data(line.toStdString().c_str());
if (data.contains(">BYTECOUNT:")) { if (data.contains(">BYTECOUNT:")) {
int beg = data.lastIndexOf(">BYTECOUNT:"); int beg = data.lastIndexOf(">BYTECOUNT:");

View file

@ -93,14 +93,14 @@ void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state)
QString VpnProtocol::textConnectionState(ConnectionState connectionState) QString VpnProtocol::textConnectionState(ConnectionState connectionState)
{ {
switch (connectionState) { switch (connectionState) {
case ConnectionState::Unknown: return "Unknown"; case ConnectionState::Unknown: return tr("Unknown");
case ConnectionState::Disconnected: return "Disconnected"; case ConnectionState::Disconnected: return tr("Disconnected");
case ConnectionState::Preparing: return "Preparing"; case ConnectionState::Preparing: return tr("Preparing");
case ConnectionState::Connecting: return "Connecting"; case ConnectionState::Connecting: return tr("Connecting");
case ConnectionState::Connected: return "Connected"; case ConnectionState::Connected: return tr("Connected");
case ConnectionState::Disconnecting: return "Disconnecting"; case ConnectionState::Disconnecting: return tr("Disconnecting");
case ConnectionState::TunnelReconnecting: return "TunnelReconnecting"; case ConnectionState::TunnelReconnecting: return tr("TunnelReconnecting");
case ConnectionState::Error: return "Error"; case ConnectionState::Error: return tr("Error");
default: default:
; ;
} }
@ -113,12 +113,12 @@ QString VpnProtocol::textConnectionState() const
return textConnectionState(m_connectionState); return textConnectionState(m_connectionState);
} }
bool VpnProtocol::connected() const bool VpnProtocol::onConnected() const
{ {
return m_connectionState == ConnectionState::Connected; return m_connectionState == ConnectionState::Connected;
} }
bool VpnProtocol::disconnected() const bool VpnProtocol::onDisconnected() const
{ {
return m_connectionState == ConnectionState::Disconnected; return m_connectionState == ConnectionState::Disconnected;
} }

View file

@ -25,8 +25,8 @@ public:
static void initializeCommunicator(QObject* parent = nullptr); static void initializeCommunicator(QObject* parent = nullptr);
virtual bool connected() const; virtual bool onConnected() const;
virtual bool disconnected() const; virtual bool onDisconnected() const;
virtual ErrorCode start() = 0; virtual ErrorCode start() = 0;
virtual void stop() = 0; virtual void stop() = 0;
@ -39,6 +39,7 @@ signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
void connectionStateChanged(VpnProtocol::ConnectionState state); void connectionStateChanged(VpnProtocol::ConnectionState state);
void timeoutTimerEvent(); void timeoutTimerEvent();
void protocolError(amnezia::ErrorCode e);
protected slots: protected slots:
virtual void onTimeout(); virtual void onTimeout();

View file

@ -76,6 +76,7 @@ MainWindow::MainWindow(QWidget *parent) :
m_vpnConnection = new VpnConnection(this); m_vpnConnection = new VpnConnection(this);
connect(m_vpnConnection, SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64))); connect(m_vpnConnection, SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
connect(m_vpnConnection, SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState))); connect(m_vpnConnection, SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
connect(m_vpnConnection, SIGNAL(vpnProtocolError(amnezia::ErrorCode)), this, SLOT(onVpnProtocolError(amnezia::ErrorCode)));
onConnectionStateChanged(VpnProtocol::ConnectionState::Disconnected); onConnectionStateChanged(VpnProtocol::ConnectionState::Disconnected);
@ -90,7 +91,7 @@ MainWindow::~MainWindow()
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
qApp->processEvents(QEventLoop::ExcludeUserInputEvents); qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
QThread::msleep(100); QThread::msleep(100);
if (m_vpnConnection->disconnected()) { if (m_vpnConnection->onDisconnected()) {
break; break;
} }
} }
@ -297,6 +298,11 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
ui->pushButton_connect->setEnabled(pushButtonConnectEnabled); ui->pushButton_connect->setEnabled(pushButtonConnectEnabled);
} }
void MainWindow::onVpnProtocolError(ErrorCode errorCode)
{
QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode));
}
void MainWindow::onPushButtonConnectToggled(bool checked) void MainWindow::onPushButtonConnectToggled(bool checked)
{ {
if (checked) { if (checked) {

View file

@ -34,6 +34,8 @@ public:
private slots: private slots:
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
void onConnectionStateChanged(VpnProtocol::ConnectionState state); void onConnectionStateChanged(VpnProtocol::ConnectionState state);
void onVpnProtocolError(amnezia::ErrorCode errorCode);
void onPushButtonBackFromNewServerClicked(bool clicked); void onPushButtonBackFromNewServerClicked(bool clicked);
void onPushButtonBackFromSettingsClicked(bool clicked); void onPushButtonBackFromSettingsClicked(bool clicked);
void onPushButtonBackFromSitesClicked(bool clicked); void onPushButtonBackFromSitesClicked(bool clicked);

View file

@ -69,7 +69,11 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot
if (e) { if (e) {
return e; return e;
} }
if (m_vpnProtocol) {
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
}
m_vpnProtocol.reset(new OpenVpnProtocol()); m_vpnProtocol.reset(new OpenVpnProtocol());
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
} }
else if (protocol == Protocol::ShadowSocks) { else if (protocol == Protocol::ShadowSocks) {
return ErrorCode::NotImplementedError; return ErrorCode::NotImplementedError;
@ -96,20 +100,20 @@ void VpnConnection::disconnectFromVpn()
m_vpnProtocol.data()->stop(); m_vpnProtocol.data()->stop();
} }
bool VpnConnection::connected() const bool VpnConnection::onConnected() const
{ {
if (!m_vpnProtocol.data()) { if (!m_vpnProtocol.data()) {
return false; return false;
} }
return m_vpnProtocol.data()->connected(); return m_vpnProtocol.data()->onConnected();
} }
bool VpnConnection::disconnected() const bool VpnConnection::onDisconnected() const
{ {
if (!m_vpnProtocol.data()) { if (!m_vpnProtocol.data()) {
return true; return true;
} }
return m_vpnProtocol.data()->disconnected(); return m_vpnProtocol.data()->onDisconnected();
} }

View file

@ -23,13 +23,14 @@ public:
ErrorCode lastError() const; ErrorCode lastError() const;
ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol); ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol);
ErrorCode connectToVpn(const ServerCredentials &credentials, Protocol protocol = Protocol::Any); ErrorCode connectToVpn(const ServerCredentials &credentials, Protocol protocol = Protocol::Any);
bool connected() const; bool onConnected() const;
bool disconnected() const; bool onDisconnected() const;
void disconnectFromVpn(); void disconnectFromVpn();
signals: signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
void connectionStateChanged(VpnProtocol::ConnectionState state); void connectionStateChanged(VpnProtocol::ConnectionState state);
void vpnProtocolError(amnezia::ErrorCode error);
protected slots: protected slots:
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);