diff --git a/src/bridge/BridgeConnection.cpp b/src/bridge/BridgeConnection.cpp index 428678e..c3f80d1 100644 --- a/src/bridge/BridgeConnection.cpp +++ b/src/bridge/BridgeConnection.cpp @@ -10,7 +10,7 @@ #define DEBUG 0 #define IDLETIMEOUTMINS 30 -BridgeConnection::BridgeConnection(QWebSocket *sock, QString ID){ +BridgeConnection::BridgeConnection(QObject *parent, QWebSocket *sock, QString ID) : QObject(parent){ SockID = ID; SockAuthToken.clear(); //nothing set initially SOCKET = sock; diff --git a/src/bridge/BridgeConnection.h b/src/bridge/BridgeConnection.h index d5bbec3..dc22a5f 100644 --- a/src/bridge/BridgeConnection.h +++ b/src/bridge/BridgeConnection.h @@ -11,7 +11,7 @@ class BridgeConnection : public QObject{ Q_OBJECT public: - BridgeConnection(QWebSocket*, QString ID); + BridgeConnection(QObject *parent, QWebSocket*, QString ID); ~BridgeConnection(); QString ID(); diff --git a/src/bridge/BridgeServer.cpp b/src/bridge/BridgeServer.cpp index 1289a2e..619d57c 100644 --- a/src/bridge/BridgeServer.cpp +++ b/src/bridge/BridgeServer.cpp @@ -120,7 +120,7 @@ void BridgeServer::NewSocketConnection(){ if(allowConnection(ws->peerAddress()) ){ QString name = ws->peerName(); if(name.isEmpty()){ name = ws->peerAddress().toString(); } - sock = new BridgeConnection( ws, generateID(name) ); + sock = new BridgeConnection( this, ws, generateID(name) ); }else{ ws->abort(); } diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 367505a..0dfd3b8 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -142,7 +142,7 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru // === SYSADM SSL SETTINGS === RestOutputStruct::ExitCode WebSocket::EvaluateSysadmSettingsRequest(const QJsonValue in_args, QJsonObject *out){ - qDebug() << "sysadm/settings Request:" << in_args; + //qDebug() << "sysadm/settings Request:" << in_args; if(!in_args.isObject()){ return RestOutputStruct::BADREQUEST; } QJsonObject argsO = in_args.toObject(); QStringList keys = argsO.keys(); diff --git a/src/server/WebServer.cpp b/src/server/WebServer.cpp index 671d860..37a8fa0 100644 --- a/src/server/WebServer.cpp +++ b/src/server/WebServer.cpp @@ -16,7 +16,7 @@ WebServer::WebServer(){ WSServer = 0; TCPServer = 0; bridgeTimer = new QTimer(this); - bridgeTimer->setInterval(5*60*1000); //5 minutes + bridgeTimer->setInterval(60000); //1 minute connect(bridgeTimer, SIGNAL(timeout()), this, SLOT(checkBridges()) ); AUTH = new AuthorizationManager(); connect(AUTH, SIGNAL(BlockHost(QHostAddress)), this, SLOT(BlackListConnection(QHostAddress)) ); @@ -145,13 +145,13 @@ void WebServer::NewSocketConnection(){ if(WSServer->hasPendingConnections()){ QWebSocket *ws = WSServer->nextPendingConnection(); if( !allowConnection(ws->peerAddress()) ){ ws->close(); } - else{ sock = new WebSocket( ws, generateID(), AUTH); } + else{ sock = new WebSocket( this, ws, generateID(), AUTH); } } }else if(TCPServer!=0){ if(TCPServer->hasPendingConnections()){ QSslSocket *ss = TCPServer->nextPendingConnection(); if( !allowConnection(ss->peerAddress()) ){ ss->close(); } - else{ sock = new WebSocket( ss, generateID(), AUTH); } + else{ sock = new WebSocket( this, ss, generateID(), AUTH); } } } if(sock==0){ return; } //no new connection @@ -211,6 +211,7 @@ void WebServer::SslErrors(const QList &list){ // - More Functions for all socket interactions void WebServer::SocketClosed(QString ID){ + qDebug() << "Socket Closed:" << ID; for(int i=0; iID()==ID){ delete OpenSockets.takeAt(i); break; } } @@ -219,7 +220,7 @@ void WebServer::SocketClosed(QString ID){ // BRIDGE Connection checks void WebServer::checkBridges(){ - qDebug() << "Check Bridges:" << WS_MODE; + //qDebug() << "Check Bridges:" << WS_MODE << QDateTime::currentDateTime().toString(Qt::ISODate); if(!WS_MODE){ return; } //Get all the unique bridge URL's we need connections to @@ -229,17 +230,18 @@ void WebServer::checkBridges(){ } //Now browse through all the current connections and see if any are already active for(int i=0; iID() ) ){ + bool active = OpenSockets[i]->isActive(); + if( bridgeKeys.contains( OpenSockets[i]->ID() ) && active){ bridgeKeys.removeAll( OpenSockets[i]->ID() ); //already running - remove from the temporary list - }else if( OpenSockets[i]->ID().toInt()==0 ){ + }else if( OpenSockets[i]->ID().toInt()==0 || !active){ //non-integer ID - another bridge connection which must have been removed from the server settings OpenSockets[i]->closeConnection(); } } //Now startup any connections which are missing for(int i=0; istart(); QTimer::singleShot(30000, this, SLOT(checkAuth())); + connCheckTimer = new QTimer(this); + connCheckTimer->setInterval(60000); //1 minute check for connection validity + connect(connCheckTimer, SIGNAL(timeout()), this, SLOT(checkConnection()) ); + connCheckTimer->start(); } -WebSocket::WebSocket(QSslSocket *sock, QString ID, AuthorizationManager *auth){ +WebSocket::WebSocket(QObject *parent, QSslSocket *sock, QString ID, AuthorizationManager *auth) : QObject(parent){ SockID = ID; SockAuthToken.clear(); //nothing set initially TSOCKET = sock; @@ -57,9 +61,13 @@ WebSocket::WebSocket(QSslSocket *sock, QString ID, AuthorizationManager *auth){ //qDebug() << " - Socket Encrypted:" << TSOCKET->isEncrypted(); idletimer->start(); QTimer::singleShot(30000, this, SLOT(checkAuth())); + connCheckTimer = new QTimer(this); + connCheckTimer->setInterval(60000); //1 minute check for connection validity + connect(connCheckTimer, SIGNAL(timeout()), this, SLOT(checkConnection()) ); + connCheckTimer->start(); } -WebSocket::WebSocket(QString url, QString ID, AuthorizationManager *auth){ +WebSocket::WebSocket(QObject *parent, QString url, QString ID, AuthorizationManager *auth) : QObject(parent){ //sets up a bridge connection (websocket only) SockID = ID; isBridge = true; @@ -82,7 +90,6 @@ WebSocket::WebSocket(QString url, QString ID, AuthorizationManager *auth){ //connect(SOCKET, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)) ); connect(SOCKET, SIGNAL(sslErrors(const QList&)), this, SLOT(SslError(const QList&)) ); //idletimer->start(); //do not idle out on a bridge connection - /*QTimer::singleShot(30000, this, SLOT(checkAuth()));*/ //Assemble the URL as needed if(!url.startsWith("wss://")){ url.prepend("wss://"); } bool hasport = false; @@ -91,8 +98,11 @@ WebSocket::WebSocket(QString url, QString ID, AuthorizationManager *auth){ //Now setup/init the connection qDebug() << "Connecting to bridge:" << url; SOCKET->setSslConfiguration(QSslConfiguration::defaultConfiguration()); - //QTimer::singleShot(0,SOCKET, SLOT(ignoreSslErrors()) ); SOCKET->open(QUrl(url)); + connCheckTimer = new QTimer(this); + connCheckTimer->setInterval(60000); //1 minute check for connection validity + connect(connCheckTimer, SIGNAL(timeout()), this, SLOT(checkConnection()) ); + connCheckTimer->start(); } WebSocket::~WebSocket(){ @@ -121,6 +131,16 @@ void WebSocket::closeConnection(){ } } +bool WebSocket::isActive(){ + bool ok = false; + if(SOCKET!=0){ + ok = SOCKET->isValid(); + }else if(TSOCKET!=0){ + ok = TSOCKET->isValid(); + } + return ok; +} + //======================= // PRIVATE //======================= @@ -448,6 +468,14 @@ QStringList WebSocket::JsonArrayToStringList(QJsonArray array){ // ===================== // PRIVATE SLOTS // ===================== +void WebSocket::checkConnection(){ + if(SOCKET !=0 && !SOCKET->isValid()){ + emit SocketClosed(SockID); + } + else if(TSOCKET !=0 && !TSOCKET->isValid() ){ + emit SocketClosed(SockID); + } +} void WebSocket::checkIdle(){ if(SOCKET !=0 && SOCKET->isValid()){ LogManager::log(LogManager::HOST,"Connection Idle: "+SockPeerIP); @@ -578,7 +606,7 @@ void WebSocket::SslError(const QList &err){ //sslErrors() signal } void WebSocket::startBridgeAuth(){ - qDebug() << "Init Bridge Auth..."; + //qDebug() << "Init Bridge Auth..."; QJsonObject obj; obj.insert("id", "server_to_bridge_auth"); obj.insert("namespace","rpc"); diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index c7d611f..1143edc 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -19,16 +19,17 @@ struct bridge_data{ class WebSocket : public QObject{ Q_OBJECT public: - WebSocket(QWebSocket*, QString ID, AuthorizationManager *auth); - WebSocket(QSslSocket*, QString ID, AuthorizationManager *auth); - WebSocket(QString url, QString ID, AuthorizationManager *auth); //sets up a bridge connection (websocket only) + WebSocket(QObject *parent, QWebSocket*, QString ID, AuthorizationManager *auth); + WebSocket(QObject *parent, QSslSocket*, QString ID, AuthorizationManager *auth); + WebSocket(QObject *parent, QString url, QString ID, AuthorizationManager *auth); //sets up a bridge connection (websocket only) ~WebSocket(); QString ID(); void closeConnection(); + bool isActive(); //check if the connection is still active/valid private: - QTimer *idletimer; + QTimer *idletimer, *connCheckTimer; QWebSocket *SOCKET; QSslSocket *TSOCKET; QString SockID, SockAuthToken, SockPeerIP; @@ -90,6 +91,7 @@ private: private slots: void sendReply(QString msg); + void checkConnection(); //see if the current connection is still open/valid void checkIdle(); //see if the currently-connected client is idle void checkAuth(); //see if the currently-connected client has authed yet void SocketClosing();