Custom routing done
ShadowSocks enabled by default
This commit is contained in:
parent
f91854594c
commit
a1cb4ac544
36 changed files with 482 additions and 780 deletions
|
|
@ -34,8 +34,9 @@ enum ErrorCode
|
|||
InternalError,
|
||||
NotImplementedError,
|
||||
|
||||
// Server errorz
|
||||
// Server errors
|
||||
ServerCheckFailed,
|
||||
ServerPortAlreadyAllocatedError,
|
||||
|
||||
// Ssh connection errors
|
||||
SshSocketError, SshTimeoutError, SshProtocolError,
|
||||
|
|
@ -62,6 +63,15 @@ enum ErrorCode
|
|||
OpenVpnUnknownError
|
||||
};
|
||||
|
||||
namespace config {
|
||||
// config keys
|
||||
static QString key_openvpn_config_data() { return "openvpn_config_data"; }
|
||||
static QString key_openvpn_config_path() { return "openvpn_config_path"; }
|
||||
static QString key_shadowsocks_config_data() { return "shadowsocks_config_data"; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // DEFS_H
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ static QString errorString(ErrorCode code){
|
|||
case(NoError): return QObject::tr("No error");
|
||||
case(UnknownError): return QObject::tr("Unknown Error");
|
||||
case(NotImplementedError): return QObject::tr("Function not implemented");
|
||||
|
||||
// Server errors
|
||||
case(ServerCheckFailed): return QObject::tr("Server check failed");
|
||||
case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software");
|
||||
|
||||
// Ssh connection errors
|
||||
case(SshSocketError): return QObject::tr("Ssh connection error");
|
||||
|
|
|
|||
|
|
@ -7,7 +7,18 @@ IpcClient &IpcClient::Instance()
|
|||
return s;
|
||||
}
|
||||
|
||||
QSharedPointer<IpcProcessInterfaceReplica> IpcClient::createPrivilegedProcess()
|
||||
bool IpcClient::init()
|
||||
{
|
||||
Instance().m_localSocket->waitForConnected();
|
||||
|
||||
if (!Instance().m_ipcClient) {
|
||||
qDebug() << "IpcClient::init failed";
|
||||
return false;
|
||||
}
|
||||
return Instance().m_ipcClient->isReplicaValid();
|
||||
}
|
||||
|
||||
QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
|
||||
{
|
||||
if (! Instance().m_ipcClient || ! Instance().m_ipcClient->isReplicaValid()) {
|
||||
qWarning() << "IpcClient::createPrivilegedProcess : IpcClient IpcClient replica is not valid";
|
||||
|
|
@ -18,47 +29,40 @@ QSharedPointer<IpcProcessInterfaceReplica> IpcClient::createPrivilegedProcess()
|
|||
futureResult.waitForFinished(1000);
|
||||
|
||||
int pid = futureResult.returnValue();
|
||||
QSharedPointer<QRemoteObjectNode> replicaNode(new QRemoteObjectNode);
|
||||
//Instance().m_processNodes.insert(pid, replica);
|
||||
|
||||
auto pd = QSharedPointer<ProcessDescriptor>(new ProcessDescriptor());
|
||||
Instance().m_processNodes.insert(pid, pd);
|
||||
|
||||
QSharedPointer<QLocalSocket> socket(new QLocalSocket(replicaNode.data()));
|
||||
QSharedPointer<IpcProcessInterfaceReplica> ptr;
|
||||
pd->localSocket.reset(new QLocalSocket(pd->replicaNode.data()));
|
||||
|
||||
connect(socket.data(), &QLocalSocket::connected, replicaNode.data(), [socket, replicaNode, &ptr]() {
|
||||
replicaNode->addClientSideConnection(socket.data());
|
||||
connect(pd->localSocket.data(), &QLocalSocket::connected, pd->replicaNode.data(), [pd]() {
|
||||
pd->replicaNode->addClientSideConnection(pd->localSocket.data());
|
||||
|
||||
ptr.reset(replicaNode->acquire<IpcProcessInterfaceReplica>());
|
||||
pd->ipcProcess.reset(pd->replicaNode->acquire<IpcProcessInterfaceReplica>());
|
||||
if (!pd->ipcProcess) {
|
||||
qWarning() << "Acquire IpcProcessInterfaceReplica failed";
|
||||
}
|
||||
else {
|
||||
pd->ipcProcess->waitForSource(1000);
|
||||
if (!pd->ipcProcess->isReplicaValid()) {
|
||||
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
|
||||
}
|
||||
|
||||
ptr->waitForSource(1000);
|
||||
|
||||
if (!ptr->isReplicaValid()) {
|
||||
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
|
||||
connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
|
||||
pd->replicaNode->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
socket->connectToServer(amnezia::getIpcProcessUrl(pid));
|
||||
socket->waitForConnected();
|
||||
|
||||
auto proccessReplica = QSharedPointer<IpcProcessInterfaceReplica>(ptr);
|
||||
|
||||
|
||||
|
||||
// replica->connectToNode(QUrl(amnezia::getIpcProcessUrl(pid)));
|
||||
// auto ptr = QSharedPointer<IpcProcessInterfaceReplica>(replica->acquire<IpcProcessInterfaceReplica>());
|
||||
connect(proccessReplica.data(), &IpcProcessInterfaceReplica::destroyed, proccessReplica.data(), [replicaNode](){
|
||||
replicaNode->deleteLater();
|
||||
});
|
||||
pd->localSocket->connectToServer(amnezia::getIpcProcessUrl(pid));
|
||||
pd->localSocket->waitForConnected();
|
||||
|
||||
auto proccessReplica = QSharedPointer<IpcProcessInterfaceReplica>(pd->ipcProcess);
|
||||
return proccessReplica;
|
||||
}
|
||||
|
||||
IpcClient::IpcClient(QObject *parent) : QObject(parent)
|
||||
{
|
||||
// m_ClientNode.connectToNode(QUrl(amnezia::getIpcServiceUrl()));
|
||||
// qDebug() << QUrl(amnezia::getIpcServiceUrl());
|
||||
|
||||
|
||||
m_localSocket.reset(new QLocalSocket(this));
|
||||
connect(m_localSocket.data(), &QLocalSocket::connected, &m_ClientNode, [this]() {
|
||||
m_ClientNode.addClientSideConnection(m_localSocket.data());
|
||||
|
|
@ -72,20 +76,4 @@ IpcClient::IpcClient(QObject *parent) : QObject(parent)
|
|||
|
||||
});
|
||||
m_localSocket->connectToServer(amnezia::getIpcServiceUrl());
|
||||
|
||||
|
||||
|
||||
// connect(m_ipcClient.data(), &IpcInterfaceReplica::stateChanged, [&](QRemoteObjectReplica::State state, QRemoteObjectReplica::State oldState){
|
||||
|
||||
//// qDebug() << "state" << state;
|
||||
//// for (int i = 0; i < 10; ++i) {
|
||||
//// QRemoteObjectPendingReply<qint64> future = m_ipcClient->createPrivilegedProcess("", QStringList());
|
||||
|
||||
//// future.waitForFinished();
|
||||
//// qDebug() << "QRemoteObjectPendingReply" << QDateTime::currentMSecsSinceEpoch() - future.returnValue();
|
||||
|
||||
//// }
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,21 +12,31 @@ class IpcClient : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
static IpcClient &Instance();
|
||||
static bool init() { return Instance().m_ipcClient->isReplicaValid(); }
|
||||
static QSharedPointer<IpcInterfaceReplica> ipcClient() { return Instance().m_ipcClient; }
|
||||
|
||||
static QSharedPointer<IpcProcessInterfaceReplica> createPrivilegedProcess();
|
||||
static bool init();
|
||||
static QSharedPointer<IpcInterfaceReplica> Interface() { return Instance().m_ipcClient; }
|
||||
static QSharedPointer<IpcProcessInterfaceReplica> CreatePrivilegedProcess();
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
explicit IpcClient(QObject *parent = nullptr);
|
||||
|
||||
QRemoteObjectNode m_ClientNode; // create remote object node
|
||||
QRemoteObjectNode m_ClientNode;
|
||||
QSharedPointer<IpcInterfaceReplica> m_ipcClient;
|
||||
QSharedPointer<QLocalSocket> m_localSocket;
|
||||
|
||||
//QMap<int, QSharedPointer<QRemoteObjectNode>> m_processNodes;
|
||||
struct ProcessDescriptor {
|
||||
ProcessDescriptor () {
|
||||
replicaNode = QSharedPointer<QRemoteObjectNode>(new QRemoteObjectNode());
|
||||
ipcProcess = QSharedPointer<IpcProcessInterfaceReplica>();
|
||||
localSocket = QSharedPointer<QLocalSocket>();
|
||||
}
|
||||
QSharedPointer<IpcProcessInterfaceReplica> ipcProcess;
|
||||
QSharedPointer<QRemoteObjectNode> replicaNode;
|
||||
QSharedPointer<QLocalSocket> localSocket;
|
||||
};
|
||||
|
||||
QMap<int, QSharedPointer<ProcessDescriptor>> m_processNodes;
|
||||
};
|
||||
|
||||
#endif // IPCCLIENT_H
|
||||
|
|
|
|||
|
|
@ -195,6 +195,12 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||
return connData;
|
||||
}
|
||||
|
||||
Settings &OpenVpnConfigurator::m_settings()
|
||||
{
|
||||
static Settings s;
|
||||
return s;
|
||||
}
|
||||
|
||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
|
||||
Protocol proto, ErrorCode *errorCode)
|
||||
{
|
||||
|
|
@ -217,6 +223,13 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||
config.replace("$LOCAL_PROXY_PORT", QString::number(ServerController::ssContainerPort()));
|
||||
}
|
||||
|
||||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||
|
||||
if (m_settings().customRouting()) {
|
||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||
}
|
||||
|
||||
config.replace("$REMOTE_HOST", connData.host);
|
||||
config.replace("$REMOTE_PORT", "1194");
|
||||
config.replace("$CA_CERT", connData.caCert);
|
||||
|
|
@ -224,5 +237,6 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||
config.replace("$PRIV_KEY", connData.privKey);
|
||||
config.replace("$TA_KEY", connData.taKey);
|
||||
|
||||
//qDebug().noquote() << config;
|
||||
return config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <QProcessEnvironment>
|
||||
|
||||
#include "defs.h"
|
||||
#include "settings.h"
|
||||
#include "servercontroller.h"
|
||||
|
||||
|
||||
|
|
@ -37,6 +38,8 @@ private:
|
|||
|
||||
static ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||
Protocol proto, ErrorCode *errorCode = nullptr);
|
||||
|
||||
static Settings &m_settings();
|
||||
};
|
||||
|
||||
#endif // OPENVPNCONFIGURATOR_H
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QApplication>
|
||||
|
||||
#include "sshconnectionmanager.h"
|
||||
|
||||
|
|
@ -23,7 +24,9 @@ QString ServerController::getContainerName(DockerContainer container)
|
|||
}
|
||||
|
||||
ErrorCode ServerController::runScript(DockerContainer container,
|
||||
const SshConnectionParameters &sshParams, QString script)
|
||||
const SshConnectionParameters &sshParams, QString script,
|
||||
const std::function<void(const QString &)> &cbReadStdOut,
|
||||
const std::function<void(const QString &)> &cbReadStdErr)
|
||||
{
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
|
||||
|
||||
|
|
@ -66,18 +69,20 @@ ErrorCode ServerController::runScript(DockerContainer container,
|
|||
wait.quit();
|
||||
});
|
||||
|
||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, &wait, [proc, cbReadStdOut](){
|
||||
QString s = proc->readAllStandardOutput();
|
||||
if (s != "." && !s.isEmpty()) {
|
||||
qDebug().noquote() << s;
|
||||
qDebug().noquote() << "stdout" << s;
|
||||
}
|
||||
if (cbReadStdOut) cbReadStdOut(s);
|
||||
});
|
||||
|
||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
|
||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, &wait, [proc, cbReadStdErr](){
|
||||
QString s = proc->readAllStandardError();
|
||||
if (s != "." && !s.isEmpty()) {
|
||||
qDebug().noquote() << s;
|
||||
qDebug().noquote() << "stderr" << s;
|
||||
}
|
||||
if (cbReadStdErr) cbReadStdErr(s);
|
||||
});
|
||||
|
||||
proc->start();
|
||||
|
|
@ -272,11 +277,12 @@ ErrorCode ServerController::removeServer(const ServerCredentials &credentials, P
|
|||
QString scriptFileName;
|
||||
DockerContainer container;
|
||||
|
||||
ErrorCode errorCode;
|
||||
if (proto == Protocol::Any) {
|
||||
removeServer(credentials, Protocol::OpenVpn);
|
||||
removeServer(credentials, Protocol::ShadowSocks);
|
||||
return ErrorCode::NoError;
|
||||
ErrorCode e = removeServer(credentials, Protocol::OpenVpn);
|
||||
if (e) {
|
||||
return e;
|
||||
}
|
||||
return removeServer(credentials, Protocol::ShadowSocks);
|
||||
}
|
||||
else if (proto == Protocol::OpenVpn) {
|
||||
scriptFileName = ":/server_scripts/remove_container.sh";
|
||||
|
|
@ -309,14 +315,14 @@ ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Pr
|
|||
return setupShadowSocksServer(credentials);
|
||||
}
|
||||
else if (proto == Protocol::Any) {
|
||||
return ErrorCode::NotImplementedError;
|
||||
//return ErrorCode::NotImplementedError;
|
||||
|
||||
// TODO: run concurently
|
||||
// return setupOpenVpnServer(credentials);
|
||||
//setupShadowSocksServer(credentials);
|
||||
setupOpenVpnServer(credentials);
|
||||
setupShadowSocksServer(credentials);
|
||||
}
|
||||
|
||||
return ErrorCode::NotImplementedError;
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials)
|
||||
|
|
@ -329,8 +335,20 @@ ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credenti
|
|||
scriptData = file.readAll();
|
||||
if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
||||
|
||||
ErrorCode e = runScript(DockerContainer::OpenVpn, sshParams(credentials), scriptData);
|
||||
QString stdOut;
|
||||
auto cbReadStdOut = [&](const QString &data) {
|
||||
stdOut += data + "\n";
|
||||
};
|
||||
auto cbReadStdErr = [&](const QString &data) {
|
||||
stdOut += data + "\n";
|
||||
};
|
||||
|
||||
ErrorCode e = runScript(DockerContainer::OpenVpn, sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
||||
if (e) return e;
|
||||
QApplication::processEvents();
|
||||
|
||||
if (stdOut.contains("port is already allocated")) return ErrorCode::ServerPortAlreadyAllocatedError;
|
||||
if (stdOut.contains("Error response from daemon")) return ErrorCode::ServerCheckFailed;
|
||||
|
||||
return checkOpenVpnServer(DockerContainer::OpenVpn, credentials);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ public:
|
|||
private:
|
||||
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||
static ErrorCode runScript(DockerContainer container,
|
||||
const QSsh::SshConnectionParameters &sshParams, QString script);
|
||||
const QSsh::SshConnectionParameters &sshParams, QString script,
|
||||
const std::function<void(const QString &)> &cbReadStdOut = nullptr,
|
||||
const std::function<void(const QString &)> &cbReadStdErr = nullptr);
|
||||
|
||||
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials);
|
||||
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue