aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Giraldeau <francis.giraldeau@gmail.com>2018-07-26 19:10:14 -0400
committerItay Grudev <itay-grudev@users.noreply.github.com>2018-07-27 02:10:14 +0300
commitf975da90ccbb70b4dda4142be629e0b54841a71f (patch)
tree66d9f225b7aad8a6dad460286e10e8ae39ea19d3
parentreplace -lAdvapi32 with -ladvapi32 which broke the build on mxe (#43) (diff)
downloadsingleapplication-f975da90ccbb70b4dda4142be629e0b54841a71f.tar.xz
Fix sendmessage (#46)
* Fix send message example If a secondary instance sends a message immediately after connecting, the message follows the init message. This causes the slotConnectionEstablished to read and consume the tail of the message and interpret it as the checksum. The checksum fails and the connection becomes invalid. To avoid this race, we prefix the init message with its length. This way, we consume only the data relevant to the init message. This patch fixes the sending_arguments example. Signed-off-by: Francis Giraldeau <francis.giraldeau@gmail.com> * Fix include file case Signed-off-by: Francis Giraldeau <francis.giraldeau@nrc-cnrc.gc.ca>
-rwxr-xr-xexamples/basic/main.cpp2
-rw-r--r--examples/calculator/main.cpp2
-rwxr-xr-xexamples/sending_arguments/main.cpp2
-rw-r--r--singleapplication.cpp67
4 files changed, 45 insertions, 28 deletions
diff --git a/examples/basic/main.cpp b/examples/basic/main.cpp
index 4787d1c..1841902 100755
--- a/examples/basic/main.cpp
+++ b/examples/basic/main.cpp
@@ -1,4 +1,4 @@
-#include <SingleApplication.h>
+#include <singleapplication.h>
int main(int argc, char *argv[])
{
diff --git a/examples/calculator/main.cpp b/examples/calculator/main.cpp
index 32d8811..d45438f 100644
--- a/examples/calculator/main.cpp
+++ b/examples/calculator/main.cpp
@@ -50,7 +50,7 @@
#include <QApplication>
-#include <SingleApplication.h>
+#include <singleapplication.h>
#include "calculator.h"
diff --git a/examples/sending_arguments/main.cpp b/examples/sending_arguments/main.cpp
index 8368036..d90b250 100755
--- a/examples/sending_arguments/main.cpp
+++ b/examples/sending_arguments/main.cpp
@@ -1,4 +1,4 @@
-#include <SingleApplication.h>
+#include <singleapplication.h>
#include "messagereceiver.h"
int main(int argc, char *argv[])
diff --git a/singleapplication.cpp b/singleapplication.cpp
index c74d6db..a333a62 100644
--- a/singleapplication.cpp
+++ b/singleapplication.cpp
@@ -216,6 +216,13 @@ void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType conne
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
writeStream << checksum;
+ // The header indicates the message length that follows
+ QByteArray header;
+ QDataStream headerStream(&header, QIODevice::WriteOnly);
+ headerStream.setVersion(QDataStream::Qt_5_6);
+ headerStream << (quint64) initMsg.length();
+
+ socket->write( header );
socket->write( initMsg );
socket->flush();
socket->waitForBytesWritten( msecs );
@@ -274,31 +281,41 @@ void SingleApplicationPrivate::slotConnectionEstablished()
quint32 instanceId = 0;
ConnectionType connectionType = InvalidConnection;
if( nextConnSocket->waitForReadyRead( 100 ) ) {
- // read all data from message in same order/format as written
- QByteArray msgBytes = nextConnSocket->read(nextConnSocket->bytesAvailable() - static_cast<qint64>(sizeof(quint16)));
- QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
- QDataStream readStream(msgBytes);
- readStream.setVersion(QDataStream::Qt_5_6);
-
- // server name
- QByteArray latin1Name;
- readStream >> latin1Name;
- // connectioon type
- quint8 connType = InvalidConnection;
- readStream >> connType;
- connectionType = static_cast<ConnectionType>(connType);
- // instance id
- readStream >> instanceId;
- // checksum
- quint16 msgChecksum = 0;
- QDataStream checksumStream(checksumBytes);
- checksumStream.setVersion(QDataStream::Qt_5_6);
- checksumStream >> msgChecksum;
-
- const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
-
- if (readStream.status() != QDataStream::Ok || QLatin1String(latin1Name) != blockServerName || msgChecksum != actualChecksum) {
- connectionType = InvalidConnection;
+ // read the fields in same order and format as written
+ QDataStream headerStream(nextConnSocket);
+ headerStream.setVersion(QDataStream::Qt_5_6);
+
+ // Read the header to know the message length
+ quint64 msgLen = 0;
+ headerStream >> msgLen;
+
+ if (msgLen >= sizeof(quint16)) {
+ // Read the message body
+ QByteArray msgBytes = nextConnSocket->read(msgLen);
+ QDataStream readStream(msgBytes);
+ readStream.setVersion(QDataStream::Qt_5_6);
+
+ // server name
+ QByteArray latin1Name;
+ readStream >> latin1Name;
+
+ // connection type
+ quint8 connType = InvalidConnection;
+ readStream >> connType;
+ connectionType = static_cast<ConnectionType>(connType);
+
+ // instance id
+ readStream >> instanceId;
+
+ // checksum
+ quint16 msgChecksum = 0;
+ readStream >> msgChecksum;
+
+ const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length() - sizeof(quint16)));
+
+ if (readStream.status() != QDataStream::Ok || QLatin1String(latin1Name) != blockServerName || msgChecksum != actualChecksum) {
+ connectionType = InvalidConnection;
+ }
}
}