Add local sockets
parent
4683f4888e
commit
b255e52396
|
|
@ -77,6 +77,7 @@ void Engine::start(ProxyConfiguration *configuration)
|
|||
m_proxyServer = new ProxyServer(this);
|
||||
m_webSocketServerProxy = new WebSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this);
|
||||
m_tcpSocketServerProxy = new TcpSocketServer(m_configuration->sslEnabled(), m_configuration->sslConfiguration(), this);
|
||||
m_unixSocketServerProxy = new UnixSocketServer(m_configuration->localSocketFileName(), this);
|
||||
|
||||
// Configure websocket server
|
||||
QUrl websocketServerUrl;
|
||||
|
|
@ -95,6 +96,7 @@ void Engine::start(ProxyConfiguration *configuration)
|
|||
// Register the transport interfaces in the proxy server
|
||||
m_proxyServer->registerTransportInterface(m_webSocketServerProxy);
|
||||
m_proxyServer->registerTransportInterface(m_tcpSocketServerProxy);
|
||||
m_proxyServer->registerTransportInterface(m_unixSocketServerProxy);
|
||||
|
||||
// Start the server
|
||||
qCDebug(dcEngine()) << "Starting the proxy servers...";
|
||||
|
|
@ -211,6 +213,11 @@ WebSocketServer *Engine::webSocketServerProxy() const
|
|||
return m_webSocketServerProxy;
|
||||
}
|
||||
|
||||
UnixSocketServer *Engine::unixSocketServerProxy() const
|
||||
{
|
||||
return m_unixSocketServerProxy;
|
||||
}
|
||||
|
||||
TcpSocketServer *Engine::tcpSocketServerTunnelProxy() const
|
||||
{
|
||||
return m_tcpSocketServerTunnelProxy;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "server/jsonrpcserver.h"
|
||||
#include "server/tcpsocketserver.h"
|
||||
#include "server/websocketserver.h"
|
||||
#include "server/unixsocketserver.h"
|
||||
#include "authentication/authenticator.h"
|
||||
#include "tunnelproxy/tunnelproxyserver.h"
|
||||
|
||||
|
|
@ -75,6 +76,7 @@ public:
|
|||
|
||||
TcpSocketServer *tcpSocketServerProxy() const;
|
||||
WebSocketServer *webSocketServerProxy() const;
|
||||
UnixSocketServer *unixSocketServerProxy() const;
|
||||
|
||||
TcpSocketServer *tcpSocketServerTunnelProxy() const;
|
||||
WebSocketServer *webSocketServerTunnelProxy() const;
|
||||
|
|
@ -103,6 +105,7 @@ private:
|
|||
|
||||
TcpSocketServer *m_tcpSocketServerProxy = nullptr;
|
||||
WebSocketServer *m_webSocketServerProxy = nullptr;
|
||||
UnixSocketServer *m_unixSocketServerProxy = nullptr;
|
||||
|
||||
TcpSocketServer *m_tcpSocketServerTunnelProxy = nullptr;
|
||||
WebSocketServer *m_webSocketServerTunnelProxy = nullptr;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ HEADERS += \
|
|||
proxy/tunnelconnection.h \
|
||||
server/tcpsocketserver.h \
|
||||
server/transportinterface.h \
|
||||
server/unixsocketserver.h \
|
||||
server/websocketserver.h \
|
||||
server/jsonrpcserver.h \
|
||||
server/transportclient.h \
|
||||
|
|
@ -60,6 +61,7 @@ SOURCES += \
|
|||
server/tcpsocketserver.cpp \
|
||||
server/transportinterface.cpp \
|
||||
server/transportclient.cpp \
|
||||
server/unixsocketserver.cpp \
|
||||
server/websocketserver.cpp \
|
||||
server/jsonrpcserver.cpp \
|
||||
server/monitorserver.cpp \
|
||||
|
|
|
|||
|
|
@ -43,5 +43,7 @@ Q_LOGGING_CATEGORY(dcProxyServerTraffic, "ProxyServerTraffic")
|
|||
Q_LOGGING_CATEGORY(dcTunnelProxyServer, "TunnelProxyServer")
|
||||
Q_LOGGING_CATEGORY(dcTunnelProxyServerTraffic, "TunnelProxyServerTraffic")
|
||||
Q_LOGGING_CATEGORY(dcMonitorServer, "MonitorServer")
|
||||
Q_LOGGING_CATEGORY(dcUnixSocketServer, "UnixSocketServer")
|
||||
Q_LOGGING_CATEGORY(dcUnixSocketServerTraffic, "UnixSocketServerTraffic")
|
||||
Q_LOGGING_CATEGORY(dcAwsCredentialsProvider, "AwsCredentialsProvider")
|
||||
Q_LOGGING_CATEGORY(dcAwsCredentialsProviderTraffic, "AwsCredentialsProviderTraffic")
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ Q_DECLARE_LOGGING_CATEGORY(dcProxyServerTraffic)
|
|||
Q_DECLARE_LOGGING_CATEGORY(dcTunnelProxyServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcTunnelProxyServerTraffic)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcMonitorServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcUnixSocketServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcUnixSocketServerTraffic)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcAwsCredentialsProvider)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcAwsCredentialsProviderTraffic)
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,10 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName)
|
|||
setTcpServerPort(static_cast<quint16>(settings.value("port", 1213).toInt()));
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("LocalSocketServer");
|
||||
setTcpServerHost(QHostAddress(settings.value("localSocketFileName", "/run/nymea-remoteproxy.socket").toString()));
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("WebSocketServerTunnelProxy");
|
||||
setWebSocketServerTunnelProxyHost(QHostAddress(settings.value("host", "127.0.0.1").toString()));
|
||||
setWebSocketServerTunnelProxyPort(static_cast<quint16>(settings.value("port", 2212).toInt()));
|
||||
|
|
@ -352,6 +356,11 @@ void ProxyConfiguration::setTcpServerPort(quint16 port)
|
|||
m_tcpServerPort = port;
|
||||
}
|
||||
|
||||
QString ProxyConfiguration::localSocketFileName() const
|
||||
{
|
||||
return m_localSocketFileName;
|
||||
}
|
||||
|
||||
QHostAddress ProxyConfiguration::webSocketServerTunnelProxyHost() const
|
||||
{
|
||||
return m_webSocketServerTunnelProxyHost;
|
||||
|
|
@ -436,6 +445,8 @@ QDebug operator<<(QDebug debug, ProxyConfiguration *configuration)
|
|||
debug.nospace() << "TcpServer Proxy" << endl;
|
||||
debug.nospace() << " - Host:" << configuration->tcpServerHost().toString() << endl;
|
||||
debug.nospace() << " - Port:" << configuration->tcpServerPort() << endl;
|
||||
debug.nospace() << "LocalSocket Proxy" << endl;
|
||||
debug.nospace() << " - Socket file:" << configuration->localSocketFileName() << endl;
|
||||
debug.nospace() << "WebSocketServer TunnelProxy" << endl;
|
||||
debug.nospace() << " - Host:" << configuration->webSocketServerTunnelProxyHost().toString() << endl;
|
||||
debug.nospace() << " - Port:" << configuration->webSocketServerTunnelProxyPort() << endl;
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ public:
|
|||
quint16 tcpServerPort() const;
|
||||
void setTcpServerPort(quint16 port);
|
||||
|
||||
// LocalServer
|
||||
QString localSocketFileName() const;
|
||||
|
||||
// WebSocketServer (tunnel)
|
||||
QHostAddress webSocketServerTunnelProxyHost() const;
|
||||
void setWebSocketServerTunnelProxyHost(const QHostAddress &address);
|
||||
|
|
@ -127,7 +130,6 @@ public:
|
|||
quint16 tcpServerTunnelProxyPort() const;
|
||||
void setTcpServerTunnelProxyPort(quint16 port);
|
||||
|
||||
|
||||
private:
|
||||
// ProxyServer
|
||||
QString m_fileName;
|
||||
|
|
@ -162,11 +164,14 @@ private:
|
|||
QHostAddress m_tcpServerHost = QHostAddress::LocalHost;
|
||||
quint16 m_tcpServerPort = 1213;
|
||||
|
||||
// WebSocketServer (proxy)
|
||||
// LocalSocketServer (proxy)
|
||||
QString m_localSocketFileName = "/run/nymea-remoteproxy.socket";
|
||||
|
||||
// WebSocketServer (tunnel)
|
||||
QHostAddress m_webSocketServerTunnelProxyHost = QHostAddress::LocalHost;
|
||||
quint16 m_webSocketServerTunnelProxyPort = 2212;
|
||||
|
||||
// TcpServer (proxy)
|
||||
// TcpServer (tunnel)
|
||||
QHostAddress m_tcpServerTunnelProxyHost = QHostAddress::LocalHost;
|
||||
quint16 m_tcpServerTunnelProxyPort = 2213;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License as published by the Free Software Foundation,
|
||||
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "unixsocketserver.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include "loggingcategories.h"
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
UnixSocketServer::UnixSocketServer(QString socketFileName, QObject *parent) :
|
||||
TransportInterface(parent),
|
||||
m_socketFileName(socketFileName)
|
||||
{
|
||||
m_serverName = "LOCAL";
|
||||
}
|
||||
|
||||
UnixSocketServer::~UnixSocketServer()
|
||||
{
|
||||
stopServer();
|
||||
}
|
||||
|
||||
void UnixSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
|
||||
{
|
||||
QLocalSocket *client = nullptr;
|
||||
client = m_clientList.value(clientId);
|
||||
if (!client) {
|
||||
qCWarning(dcUnixSocketServer()) << "Client" << clientId << "unknown to this transport";
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcUnixSocketServerTraffic()) << "Send data to" << clientId.toString() << data;
|
||||
if (client->write(data) < 0) {
|
||||
qCWarning(dcUnixSocketServer()) << "Could not write data to client socket" << clientId.toString();
|
||||
}
|
||||
client->flush();
|
||||
}
|
||||
|
||||
void UnixSocketServer::killClientConnection(const QUuid &clientId, const QString &killReason)
|
||||
{
|
||||
QLocalSocket *client = m_clientList.value(clientId);
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
if (client->state() == QLocalSocket::ConnectedState) {
|
||||
qCWarning(dcUnixSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason;
|
||||
client->close();
|
||||
}
|
||||
}
|
||||
|
||||
bool UnixSocketServer::running() const
|
||||
{
|
||||
if (!m_server)
|
||||
return false;
|
||||
|
||||
return m_server->isListening();
|
||||
}
|
||||
|
||||
bool UnixSocketServer::startServer()
|
||||
{
|
||||
qCDebug(dcUnixSocketServer()) << "Starting server on" << m_socketFileName;
|
||||
|
||||
// Make sure the monitor can be created
|
||||
if (QFile::exists(m_socketFileName)) {
|
||||
qCDebug(dcUnixSocketServer()) << "Clean up old unix socket";
|
||||
QFile::remove(m_socketFileName);
|
||||
}
|
||||
|
||||
m_server = new QLocalServer(this);
|
||||
m_server->setSocketOptions(QLocalServer::UserAccessOption | QLocalServer::GroupAccessOption | QLocalServer::OtherAccessOption);
|
||||
if (!m_server->listen(m_socketFileName)) {
|
||||
qCWarning(dcUnixSocketServer()) << "Could not start local server for monitor on" << m_serverName << m_server->errorString();
|
||||
delete m_server;
|
||||
m_server = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_server, &QLocalServer::newConnection, this, &UnixSocketServer::onClientConnected);
|
||||
qCDebug(dcUnixSocketServer()) << "Started successfully on" << m_serverName;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnixSocketServer::stopServer()
|
||||
{
|
||||
if (!m_server)
|
||||
return true;
|
||||
|
||||
qCDebug(dcUnixSocketServer()) << "Stopping server" << m_serverName;
|
||||
foreach (QLocalSocket *clientConnection, m_clientList) {
|
||||
clientConnection->close();
|
||||
}
|
||||
|
||||
m_server->close();
|
||||
delete m_server;
|
||||
m_server = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UnixSocketServer::onClientConnected()
|
||||
{
|
||||
QLocalSocket *client = m_server->nextPendingConnection();
|
||||
QUuid clientId = QUuid::createUuid();
|
||||
qCDebug(dcUnixSocketServer()) << "New client connected" << clientId.toString();
|
||||
m_clientList.insert(clientId, client);
|
||||
|
||||
connect(client, &QLocalSocket::disconnected, this, [=](){
|
||||
QUuid clientId = m_clientList.key(client);
|
||||
qCDebug(dcUnixSocketServer()) << "Client disconnected:" << clientId.toString();
|
||||
if (m_clientList.take(clientId)) {
|
||||
emit clientDisconnected(clientId);
|
||||
}
|
||||
});
|
||||
connect(client, &QLocalSocket::readyRead, this, [=](){
|
||||
QByteArray data = client->readAll();
|
||||
qCDebug(dcUnixSocketServerTraffic()) << "Incomming data from" << clientId.toString() << data;
|
||||
emit dataAvailable(clientId, data);
|
||||
});
|
||||
|
||||
emit clientConnected(clientId, QHostAddress::LocalHost);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License as published by the Free Software Foundation,
|
||||
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef UNIXSOCKETSERVER_H
|
||||
#define UNIXSOCKETSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUuid>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include "transportinterface.h"
|
||||
|
||||
namespace remoteproxy {
|
||||
|
||||
class UnixSocketServer : public TransportInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit UnixSocketServer(QString socketFileName, QObject *parent = nullptr);
|
||||
~UnixSocketServer() override;
|
||||
|
||||
void sendData(const QUuid &clientId, const QByteArray &data) override;
|
||||
void killClientConnection(const QUuid &clientId, const QString &killReason) override;
|
||||
|
||||
bool running() const override;
|
||||
|
||||
public slots:
|
||||
bool startServer() override;
|
||||
bool stopServer() override;
|
||||
|
||||
private:
|
||||
QString m_socketFileName;
|
||||
QLocalServer *m_server = nullptr;
|
||||
QHash<QUuid, QLocalSocket *> m_clientList;
|
||||
|
||||
private slots:
|
||||
void onClientConnected();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // UNIXSOCKETSERVER_H
|
||||
|
|
@ -7,10 +7,16 @@ JsonRpc.debug=true
|
|||
JsonRpcTraffic.debug=false
|
||||
WebSocketServer.debug=true
|
||||
WebSocketServerTraffic.debug=false
|
||||
TcpSocketServer.debug=true
|
||||
TcpSocketServerTraffic.debug=false
|
||||
UnixSocketServer.debug=true
|
||||
UnixSocketServerTraffic.debug=false
|
||||
Authentication.debug=true
|
||||
AuthenticationProcess.debug=false
|
||||
ProxyServer.debug=true
|
||||
ProxyServerTraffic.debug=false
|
||||
TunnelProxyServer.debug=true
|
||||
TunnelProxyServerTraffic.debug=false
|
||||
MonitorServer.debug=true
|
||||
AwsCredentialsProvider.debug=false
|
||||
AwsCredentialsProviderTraffic.debug=false
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ port=443
|
|||
host=127.0.0.1
|
||||
port=80
|
||||
|
||||
[LocalSocketServer]
|
||||
localSocketFileName=/run/nymea-remoteproxy.socket
|
||||
|
||||
[WebSocketServerTunnelProxy]
|
||||
host=127.0.0.1
|
||||
port=2212
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ int main(int argc, char *argv[])
|
|||
"registered nymea deamons to establish a tunnel connection.\n\n"
|
||||
"Version: %1\n"
|
||||
"API version: %2\n\n"
|
||||
"Copyright %3 2021 nymea GmbH <developer@nymea.io>\n")
|
||||
"Copyright %3 2022 nymea GmbH <developer@nymea.io>\n")
|
||||
.arg(SERVER_VERSION_STRING)
|
||||
.arg(API_VERSION_STRING)
|
||||
.arg(QChar(0xA9)));
|
||||
|
|
@ -175,18 +175,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
// Verify webserver configuration
|
||||
if (configuration->webSocketServerProxyHost().isNull()) {
|
||||
qCCritical(dcApplication()) << "Invalid web socket host address passed.";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Verify tcp server configuration
|
||||
if (configuration->tcpServerHost().isNull()) {
|
||||
qCCritical(dcApplication()) << "Invalid TCP server host address passed.";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Verify SSL configuration
|
||||
if (configuration->sslEnabled() && configuration->sslConfiguration().isNull()) {
|
||||
qCCritical(dcApplication()) << "SSL is enabled but no SSL configuration specified.";
|
||||
|
|
|
|||
Loading…
Reference in New Issue