forked from qt-creator/qt-creator
iOS: Add relay server to route gdb data via service connection
Communication using sockets can no longer be done for gdb server, though a TCP socket opened using USB MUX still operates normally. I.e the QML debug server communication remains as is but GDB server data has to be routed via the secure service connection Task-number: QTCREATORBUG-24672 Change-Id: I64631d66dc845dd2d7a20c771534ae17e183a9b8 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -259,12 +259,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
|
||||
if (deviceSession) {
|
||||
int qmlPort = deviceSession->qmljsDebugPort();
|
||||
if (qmlPort) {
|
||||
qmlServer = new GenericRelayServer(this, qmlPort, deviceSession);
|
||||
qmlServer = new QmlRelayServer(this, qmlPort, deviceSession);
|
||||
qmlServer->startServer();
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
gdbServer = new SingleRelayServer(this, gdbFd);
|
||||
gdbServer = new GdbRelayServer(this, gdbFd, conn);
|
||||
if (!gdbServer->startServer()) {
|
||||
doExit(-4);
|
||||
return;
|
||||
|
@@ -34,8 +34,8 @@
|
||||
|
||||
namespace Ios {
|
||||
class GdbRunner;
|
||||
class SingleRelayServer;
|
||||
class GenericRelayServer;
|
||||
class GdbRelayServer;
|
||||
class QmlRelayServer;
|
||||
|
||||
class IosTool: public QObject
|
||||
{
|
||||
@@ -79,8 +79,8 @@ private:
|
||||
QFile outFile;
|
||||
QString m_qmlPort;
|
||||
QXmlStreamWriter out;
|
||||
SingleRelayServer *gdbServer;
|
||||
GenericRelayServer *qmlServer;
|
||||
GdbRelayServer *gdbServer;
|
||||
QmlRelayServer *qmlServer;
|
||||
GdbRunner *gdbRunner;
|
||||
bool m_echoRelays = false;
|
||||
friend class GdbRunner;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "relayserver.h"
|
||||
|
||||
#include "iostool.h"
|
||||
#include "mobiledevicelib.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
@@ -45,15 +46,7 @@ Relayer::Relayer(RelayServer *parent, QTcpSocket *clientSocket) :
|
||||
|
||||
Relayer::~Relayer()
|
||||
{
|
||||
if (m_serverFileDescriptor > 0) {
|
||||
::close(m_serverFileDescriptor);
|
||||
m_serverFileDescriptor = -1;
|
||||
if (m_serverNotifier)
|
||||
delete m_serverNotifier;
|
||||
}
|
||||
if (m_clientSocket->isOpen())
|
||||
m_clientSocket->close();
|
||||
delete m_clientSocket;
|
||||
closeConnection();
|
||||
}
|
||||
|
||||
void Relayer::setClientSocket(QTcpSocket *clientSocket)
|
||||
@@ -93,7 +86,7 @@ void Relayer::handleSocketHasData(int socket)
|
||||
m_serverNotifier->setEnabled(false);
|
||||
char buf[255];
|
||||
while (true) {
|
||||
qptrdiff rRead = read(socket, &buf, sizeof(buf)-1);
|
||||
qptrdiff rRead = readData(socket, &buf, sizeof(buf)-1);
|
||||
if (rRead == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
@@ -158,7 +151,7 @@ void Relayer::handleClientHasData()
|
||||
.arg((quintptr)(void *)this), buf, rRead);
|
||||
}
|
||||
while (true) {
|
||||
qptrdiff written = write(m_serverFileDescriptor, buf + pos, rRead);
|
||||
qptrdiff written = writeData(m_serverFileDescriptor, buf + pos, rRead);
|
||||
if (written == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
@@ -193,6 +186,32 @@ void Relayer::handleClientHasError(QAbstractSocket::SocketError error)
|
||||
server()->removeRelayConnection(this);
|
||||
}
|
||||
|
||||
int Relayer::readData(int socketFd, void *buf, size_t size)
|
||||
{
|
||||
return read(socketFd, buf, size);
|
||||
}
|
||||
|
||||
int Relayer::writeData(int socketFd, const void *data, size_t size)
|
||||
{
|
||||
return write(socketFd, data, size);
|
||||
}
|
||||
|
||||
void Relayer::closeConnection()
|
||||
{
|
||||
if (m_serverFileDescriptor > 0) {
|
||||
::close(m_serverFileDescriptor);
|
||||
m_serverFileDescriptor = -1;
|
||||
if (m_serverNotifier) {
|
||||
delete m_serverNotifier;
|
||||
m_serverNotifier = nullptr;
|
||||
}
|
||||
}
|
||||
if (m_clientSocket->isOpen())
|
||||
m_clientSocket->close();
|
||||
delete m_clientSocket;
|
||||
m_clientSocket = nullptr;
|
||||
}
|
||||
|
||||
IosTool *Relayer::iosTool() const
|
||||
{
|
||||
return (server() ? server()->iosTool() : 0);
|
||||
@@ -203,7 +222,7 @@ RelayServer *Relayer::server() const
|
||||
return qobject_cast<RelayServer *>(parent());
|
||||
}
|
||||
|
||||
RemotePortRelayer::RemotePortRelayer(GenericRelayServer *parent, QTcpSocket *clientSocket) :
|
||||
RemotePortRelayer::RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientSocket) :
|
||||
Relayer(parent, clientSocket)
|
||||
{
|
||||
m_remoteConnectTimer.setSingleShot(true);
|
||||
@@ -217,7 +236,7 @@ void RemotePortRelayer::tryRemoteConnect()
|
||||
if (m_serverFileDescriptor > 0)
|
||||
return;
|
||||
ServiceSocket ss;
|
||||
GenericRelayServer *grServer = qobject_cast<GenericRelayServer *>(server());
|
||||
QmlRelayServer *grServer = qobject_cast<QmlRelayServer *>(server());
|
||||
if (!grServer)
|
||||
return;
|
||||
if (grServer->m_deviceSession->connectToPort(grServer->m_remotePort, &ss)) {
|
||||
@@ -294,16 +313,17 @@ void RelayServer::removeRelayConnection(Relayer *relayer)
|
||||
relayer->deleteLater();
|
||||
}
|
||||
|
||||
SingleRelayServer::SingleRelayServer(IosTool *parent,
|
||||
int serverFileDescriptor) :
|
||||
RelayServer(parent)
|
||||
GdbRelayServer::GdbRelayServer(IosTool *parent,
|
||||
int serverFileDescriptor, ServiceConnRef conn) :
|
||||
RelayServer(parent),
|
||||
m_serverFileDescriptor(serverFileDescriptor),
|
||||
m_serviceConn(conn)
|
||||
{
|
||||
m_serverFileDescriptor = serverFileDescriptor;
|
||||
if (m_serverFileDescriptor > 0)
|
||||
fcntl(m_serverFileDescriptor, F_SETFL, fcntl(m_serverFileDescriptor, F_GETFL, 0) | O_NONBLOCK);
|
||||
}
|
||||
|
||||
void SingleRelayServer::newRelayConnection()
|
||||
void GdbRelayServer::newRelayConnection()
|
||||
{
|
||||
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
|
||||
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
|
||||
@@ -312,13 +332,13 @@ void SingleRelayServer::newRelayConnection()
|
||||
return;
|
||||
}
|
||||
if (clientSocket) {
|
||||
Relayer *newConnection = new Relayer(this, clientSocket);
|
||||
Relayer *newConnection = new ServiceConnectionRelayer(this, clientSocket, m_serviceConn);
|
||||
m_connections.append(newConnection);
|
||||
newConnection->startRelay(m_serverFileDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,
|
||||
QmlRelayServer::QmlRelayServer(IosTool *parent, int remotePort,
|
||||
Ios::DeviceSession *deviceSession) :
|
||||
RelayServer(parent),
|
||||
m_remotePort(remotePort),
|
||||
@@ -328,7 +348,7 @@ GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,
|
||||
}
|
||||
|
||||
|
||||
void GenericRelayServer::newRelayConnection()
|
||||
void QmlRelayServer::newRelayConnection()
|
||||
{
|
||||
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
|
||||
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
|
||||
@@ -339,4 +359,42 @@ void GenericRelayServer::newRelayConnection()
|
||||
newConnection->tryRemoteConnect();
|
||||
}
|
||||
}
|
||||
|
||||
ServiceConnectionRelayer::ServiceConnectionRelayer(RelayServer *parent, QTcpSocket *clientSocket,
|
||||
ServiceConnRef conn)
|
||||
: Relayer(parent, clientSocket),
|
||||
m_serviceConn(conn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int ServiceConnectionRelayer::readData(int socketFd, void *buf, size_t size)
|
||||
{
|
||||
Q_UNUSED(socketFd)
|
||||
if (!buf || !m_serviceConn)
|
||||
return 0;
|
||||
MobileDeviceLib &mlib = MobileDeviceLib::instance();
|
||||
return mlib.serviceConnectionReceive(m_serviceConn, buf, size);
|
||||
}
|
||||
|
||||
int ServiceConnectionRelayer::writeData(int socketFd, const void *data, size_t size)
|
||||
{
|
||||
Q_UNUSED(socketFd)
|
||||
if (!data || !m_serviceConn)
|
||||
return 0;
|
||||
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||
return mLib.serviceConnectionSend(m_serviceConn, data, size);
|
||||
}
|
||||
|
||||
void ServiceConnectionRelayer::closeConnection()
|
||||
{
|
||||
Relayer::closeConnection();
|
||||
if (m_serviceConn) {
|
||||
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||
mLib.serviceConnectionInvalidate(m_serviceConn);
|
||||
m_serviceConn = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ namespace Ios {
|
||||
class DeviceSession;
|
||||
class IosTool;
|
||||
class RelayServer;
|
||||
class GenericRelayServer;
|
||||
class QmlRelayServer;
|
||||
|
||||
class Relayer: public QObject
|
||||
{
|
||||
@@ -55,11 +55,29 @@ public:
|
||||
void handleClientHasError(QAbstractSocket::SocketError error);
|
||||
|
||||
protected:
|
||||
virtual int readData(int socketFd, void* buf, size_t size);
|
||||
virtual int writeData(int socketFd, const void *data, size_t size);
|
||||
virtual void closeConnection();
|
||||
|
||||
IosTool *iosTool() const;
|
||||
RelayServer *server() const;
|
||||
ServiceSocket m_serverFileDescriptor;
|
||||
QTcpSocket *m_clientSocket;
|
||||
QSocketNotifier *m_serverNotifier;
|
||||
QTcpSocket *m_clientSocket = nullptr;
|
||||
QSocketNotifier *m_serverNotifier = nullptr;
|
||||
};
|
||||
|
||||
class ServiceConnectionRelayer : public Relayer
|
||||
{
|
||||
public:
|
||||
ServiceConnectionRelayer(RelayServer *parent, QTcpSocket *clientSocket, ServiceConnRef conn);
|
||||
|
||||
protected:
|
||||
int readData(int socketFd, void* buf, size_t size) override;
|
||||
int writeData(int socketFd, const void *data, size_t size) override;
|
||||
void closeConnection() override;
|
||||
|
||||
private:
|
||||
ServiceConnRef m_serviceConn;
|
||||
};
|
||||
|
||||
class RemotePortRelayer: public Relayer
|
||||
@@ -69,11 +87,11 @@ class RemotePortRelayer: public Relayer
|
||||
public:
|
||||
static const int reconnectMsecDelay = 500;
|
||||
static const int maxReconnectAttempts = 2*60*5; // 5 min
|
||||
RemotePortRelayer(GenericRelayServer *parent, QTcpSocket *clientSocket);
|
||||
RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientSocket);
|
||||
void tryRemoteConnect();
|
||||
|
||||
signals:
|
||||
void didConnect(GenericRelayServer *serv);
|
||||
void didConnect(QmlRelayServer *serv);
|
||||
|
||||
private:
|
||||
QTimer m_remoteConnectTimer;
|
||||
@@ -103,27 +121,28 @@ protected:
|
||||
QList<Relayer *> m_connections;
|
||||
};
|
||||
|
||||
class SingleRelayServer: public RelayServer
|
||||
class GdbRelayServer: public RelayServer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SingleRelayServer(IosTool *parent, int serverFileDescriptor);
|
||||
GdbRelayServer(IosTool *parent, int serverFileDescriptor, ServiceConnRef conn);
|
||||
|
||||
protected:
|
||||
void newRelayConnection() override;
|
||||
|
||||
private:
|
||||
int m_serverFileDescriptor;
|
||||
int m_serverFileDescriptor = -1;
|
||||
ServiceConnRef m_serviceConn = nullptr;
|
||||
};
|
||||
|
||||
class GenericRelayServer: public RelayServer
|
||||
class QmlRelayServer: public RelayServer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenericRelayServer(IosTool *parent, int remotePort,
|
||||
Ios::DeviceSession *deviceSession);
|
||||
QmlRelayServer(IosTool *parent, int remotePort,
|
||||
Ios::DeviceSession *deviceSession);
|
||||
|
||||
protected:
|
||||
void newRelayConnection() override;
|
||||
|
Reference in New Issue
Block a user