Browse Source

Fix access violation

pull/45/head 0.6.8
adityapk00 5 years ago
parent
commit
48bef601de
  1. 34
      src/websockets.cpp
  2. 27
      src/websockets.h

34
src/websockets.cpp

@ -5,6 +5,19 @@
#include "ui_mobileappconnector.h"
#include "version.h"
// Weap the sendTextMessage to check if the connection is valid and that the parent WebServer didn't close this connection
// for some reason.
void ClientWebSocket::sendTextMessage(QString m) {
if (client) {
if (server && !server->isValidConnection(client)) {
return;
}
if (client->isValid())
client->sendTextMessage(m);
}
}
WSServer::WSServer(quint16 port, bool debug, QObject *parent) :
QObject(parent),
m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Direct Connection Server"),
@ -46,7 +59,8 @@ void WSServer::processTextMessage(QString message)
qDebug() << "Message received:" << message;
if (pClient) {
AppDataServer::getInstance()->processMessage(message, m_mainWindow, pClient, AppConnectionType::DIRECT);
std::shared_ptr<ClientWebSocket> client = std::make_shared<ClientWebSocket>(pClient, this);
AppDataServer::getInstance()->processMessage(message, m_mainWindow, client, AppConnectionType::DIRECT);
}
}
@ -153,7 +167,7 @@ void WormholeClient::onConnected()
void WormholeClient::onTextMessageReceived(QString message)
{
AppDataServer::getInstance()->processMessage(message, parent, m_webSocket, AppConnectionType::INTERNET);
AppDataServer::getInstance()->processMessage(message, parent, std::make_shared<ClientWebSocket>(m_webSocket), AppConnectionType::INTERNET);
}
@ -508,7 +522,7 @@ QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex, QStr
}
// Process an incoming text message. The message has to be encrypted with the secret key (or the temporary secret key)
void AppDataServer::processMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient, AppConnectionType connType) {
void AppDataServer::processMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient, AppConnectionType connType) {
auto replyWithError = [=]() {
auto r = QJsonDocument(QJsonObject{
{"error", "Encryption error"},
@ -591,7 +605,7 @@ void AppDataServer::processMessage(QString message, MainWindow* mainWindow, QWeb
}
// Decrypted method will be executed here.
void AppDataServer::processDecryptedMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient) {
void AppDataServer::processDecryptedMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
// First, extract the command from the message
auto msg = QJsonDocument::fromJson(message.toUtf8());
@ -623,7 +637,7 @@ void AppDataServer::processDecryptedMessage(QString message, MainWindow* mainWin
}
// "sendTx" command. This method will actually send money, so be careful with everything
void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QWebSocket* pClient) {
void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, std::shared_ptr<ClientWebSocket> pClient) {
auto error = [=](QString reason) {
auto r = QJsonDocument(QJsonObject{
{"errorCode", -1},
@ -693,8 +707,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QW
{"command", "sendTxSubmitted"},
{"txid", txid}
}).toJson();
if (pClient->isValid())
pClient->sendTextMessage(encryptOutgoing(r));
pClient->sendTextMessage(encryptOutgoing(r));
},
// Errored while submitting Tx
[=] (QString, QString errStr) {
@ -703,8 +716,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QW
{"command", "sendTxFailed"},
{"err", errStr}
}).toJson();
if (pClient->isValid())
pClient->sendTextMessage(encryptOutgoing(r));
pClient->sendTextMessage(encryptOutgoing(r));
}
);
@ -717,7 +729,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QW
}
// "getInfo" command
void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, QWebSocket* pClient) {
void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
auto connectedName = jobj["name"].toString();
if (mainWindow == nullptr || mainWindow->getRPC() == nullptr ||
@ -758,7 +770,7 @@ void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, QWe
pClient->sendTextMessage(encryptOutgoing(r));
}
void AppDataServer::processGetTransactions(MainWindow* mainWindow, QWebSocket* pClient) {
void AppDataServer::processGetTransactions(MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
QJsonArray txns;
auto model = mainWindow->getRPC()->getTransactionsModel();

27
src/websockets.h

@ -10,11 +10,28 @@
QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)
class WSServer;
// We're going to wrap the websocket in this class, because the underlying QWebSocket might get closed
// or deleted while a callback is waiting to get the data back. Therefore, we write a custom "sendTextMessage"
// class that checks all this before sending.
class ClientWebSocket {
public:
ClientWebSocket(QWebSocket* c, WSServer* s = nullptr) { client = c; server = s; }
void sendTextMessage(QString m);
void close(QWebSocketProtocol::CloseCode code, const QString& msg) { client->close(code, msg); }
private:
QWebSocket* client;
WSServer* server;
};
class WSServer : public QObject
{
Q_OBJECT
public:
explicit WSServer(quint16 port, bool debug = false, QObject *parent = nullptr);
bool isValidConnection(QWebSocket* c) { return m_clients.contains(c); }
~WSServer();
Q_SIGNALS:
@ -82,11 +99,11 @@ public:
void updateConnectedUI();
void updateUIWithNewQRCode(MainWindow* mainwindow);
void processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QWebSocket* pClient);
void processMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient, AppConnectionType connType);
void processGetInfo(QJsonObject jobj, MainWindow* mainWindow, QWebSocket* pClient);
void processDecryptedMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient);
void processGetTransactions(MainWindow* mainWindow, QWebSocket* pClient);
void processSendTx(QJsonObject sendTx, MainWindow* mainwindow, std::shared_ptr<ClientWebSocket> pClient);
void processMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient, AppConnectionType connType);
void processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
void processDecryptedMessage(QString message, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
void processGetTransactions(MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient);
QString decryptMessage(QJsonDocument msg, QString secretHex, QString lastRemoteNonceHex);
QString encryptOutgoing(QString msg);

Loading…
Cancel
Save