[rkward-cvs] SF.net SVN: rkward:[3195] branches/2010_10_18_backend_restructuring_branch/ rkward/rbackend

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 19 12:37:51 UTC 2010


Revision: 3195
          http://rkward.svn.sourceforge.net/rkward/?rev=3195&view=rev
Author:   tfry
Date:     2010-11-19 12:37:51 +0000 (Fri, 19 Nov 2010)

Log Message:
-----------
Add handshake proceedure

Modified Paths:
--------------
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.h
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.h
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rktransmitter.cpp

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.cpp	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.cpp	2010-11-19 12:37:51 UTC (rev 3195)
@@ -22,12 +22,14 @@
 #include <QTimer>
 #include <QLocalSocket>
 
+#include "../version.h"
 #include "../debug.h"
 
-RKRBackendTransmitter::RKRBackendTransmitter (const QString &servername) {
+RKRBackendTransmitter::RKRBackendTransmitter (const QString &servername, const QString &token) {
 	RK_TRACE (RBACKEND);
 
 	RKRBackendTransmitter::servername = servername;
+	RKRBackendTransmitter::token = token;
 }
 
 RKRBackendTransmitter::~RKRBackendTransmitter () {
@@ -56,7 +58,11 @@
 	setConnection (con);
 	
 	if (!connection->waitForConnected ()) handleTransmissionError ("Could not connect: " + connection->errorString ());
-#warning do handshake
+	// handshake
+	connection->write (token.toLocal8Bit ().data ());
+	connection->write ("\n");
+	connection->write (VERSION);
+	connection->write ("\n");
 
 	QTimer* flush_timer = new QTimer (this);
 	connect (flush_timer, SIGNAL (timeout()), this, SLOT (flushOutput()));

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.h	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkbackendtransmitter.h	2010-11-19 12:37:51 UTC (rev 3195)
@@ -25,7 +25,7 @@
 class RKRBackendTransmitter : public RKAbstractTransmitter {
 Q_OBJECT
 public:
-	RKRBackendTransmitter (const QString &servername);
+	RKRBackendTransmitter (const QString &servername, const QString &token);
 	~RKRBackendTransmitter ();
 
 	void publicmsleep (int delay) { msleep (delay); };
@@ -41,6 +41,7 @@
 	void flushOutput (bool force);
 	QList<RBackendRequest*> current_sync_requests;	// pointers to the request that we expect a reply for. Yes, internally, this can be several requests.
 	QString servername;
+	QString token;
 };
 
 #endif

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.cpp	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.cpp	2010-11-19 12:37:51 UTC (rev 3195)
@@ -21,12 +21,15 @@
 #include "../misc/rkcommonfunctions.h"
 #include "../settings/rksettingsmodulegeneral.h"
 
+#include "klocale.h"
+#include "krandom.h"
 #include "kstandarddirs.h"
 #include <QCoreApplication>
 #include <QProcess>
 #include <QLocalServer>
 #include <QLocalSocket>
 
+#include "../version.h"
 #include "../debug.h"
 
 RKFrontendTransmitter::RKFrontendTransmitter () : RKAbstractTransmitter () {
@@ -46,7 +49,9 @@
 
 	// start server
 	server = new QLocalServer (this);
-	if (!server->listen ("rkward")) handleTransmissionError ("failure to start frontend server: " + server->errorString ());
+	// we add a bit of randomness to the servername, as in general the servername must be unique
+	// there could be conflicts with concurrent or with previous crashed rkward sessions.
+	if (!server->listen ("rkward" + KRandom::randomString (8))) handleTransmissionError ("Failure to start frontend server: " + server->errorString ());
 	connect (server, SIGNAL (newConnection ()), this, SLOT (connectAndEnterLoop ()), Qt::QueuedConnection);
 
 	// start backend
@@ -56,13 +61,20 @@
 	args.append ("--server-name " + server->fullServerName ());
 	args.append ("--data-dir " + RKSettingsModuleGeneral::filesPath ());
 	backend->setProcessChannelMode (QProcess::MergedChannels);	// at least for now. Seems difficult to get interleaving right, without this.
-	connect (backend, SIGNAL (readyReadStandardOutput ()), this, SLOT (newProcessOutput ()));
 	connect (backend, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (backendExit (int)));
 	QString backend_executable = KStandardDirs::findExe ("rkward.rbackend", QCoreApplication::applicationDirPath () + "/rbackend");
 	if (backend_executable.isEmpty ()) backend_executable = KStandardDirs::findExe ("rkward.rbackend", QCoreApplication::applicationDirPath ());
 	RK_ASSERT (!backend_executable.isEmpty ());
 	backend->start (backend_executable, args, QIODevice::ReadOnly);
 
+	// fetch security token
+	if (!backend->canReadLine ()) backend->waitForReadyRead ();
+	token = QString::fromLocal8Bit (backend->readLine ());
+	token.chop (1);
+
+	connect (backend, SIGNAL (readyReadStandardOutput ()), this, SLOT (newProcessOutput ()));
+	if (backend->bytesAvailable ()) newProcessOutput ();
+
 	exec ();
 
 	if (!connection) {
@@ -78,8 +90,20 @@
 	RK_TRACE (RBACKEND);
 	RK_ASSERT (server->hasPendingConnections ());
 
-	setConnection (server->nextPendingConnection ());
+	QLocalSocket *con = server->nextPendingConnection ();
 	server->close ();
+
+	// handshake
+	if (!con->canReadLine ()) con->waitForReadyRead (1000);
+	QString token_c = QString::fromLocal8Bit (con->readLine ());
+	token_c.chop (1);
+	if (token_c != token) handleTransmissionError (i18n ("Error during handshake with backend process. Expected token '%1', received token '%2'").arg (token).arg (token_c));
+	if (!con->canReadLine ()) con->waitForReadyRead (1000);
+	QString version_c = QString::fromLocal8Bit (con->readLine ());
+	version_c.chop (1);
+	if (version_c != VERSION) handleTransmissionError (i18n ("Version mismatch during handshake with backend process. Frontend is version '%1' while backend is '%2'.\nPlease fix your installation.").arg (VERSION).arg (version_c));
+
+	setConnection (con);
 }
 
 void RKFrontendTransmitter::newProcessOutput () {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.h	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkfrontendtransmitter.h	2010-11-19 12:37:51 UTC (rev 3195)
@@ -47,6 +47,7 @@
 	int current_request_length;
 	QProcess* backend;
 	QLocalServer* server;
+	QString token;
 };
 
 #endif

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrbackendprotocol_backend.cpp	2010-11-19 12:37:51 UTC (rev 3195)
@@ -84,6 +84,7 @@
 #	include "rkbackendtransmitter.h"
 
 #	include "ktemporaryfile.h"
+#	include "krandom.h"
 	int RK_Debug_Level = 2;
 	int RK_Debug_Flags = ALL;
 	QMutex RK_Debug_Mutex;
@@ -127,9 +128,16 @@
 		}
 		if (servername.isEmpty ()) {
 			printf ("no server to connect to");
+			return 1;
 		}
 
-		RKRBackendTransmitter transmitter (servername);
+		// a simple security token to all the frontend to make sure that it is really talking to the backend process that it started in the local socket connection.
+		// this token is sent both via stdout and the local socket connection. The frontend simply compares both values.
+		QString token = KRandom::randomString (32);
+		printf ("%s\n", token.toLocal8Bit ().data ());
+		fflush (stdout);
+
+		RKRBackendTransmitter transmitter (servername, token);
 		RKRBackendProtocolBackend backend (data_dir);
 		transmitter.start ();
 		RKRBackend::this_pointer->run ();

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rktransmitter.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rktransmitter.cpp	2010-11-19 11:08:05 UTC (rev 3194)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rktransmitter.cpp	2010-11-19 12:37:51 UTC (rev 3195)
@@ -276,6 +276,9 @@
 
 	connect (connection, SIGNAL (readyRead()), this, SLOT (fetchTransmission()));
 	connect (connection, SIGNAL (disconnected()), this, SLOT (disconnected()));
+
+	// In case something is pending already.
+	if (connection->bytesAvailable ()) QTimer::singleShot (0, this, SLOT (fetchTransmission ()));
 }
 
 void RKAbstractTransmitter::disconnected () {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list