IosTool: Always listen on both IPv4 and IPv6

We don't know which protocol QtCreator will choose to connect to the
QML debug server. Currently QtCreator uses whatever "localhost"
resolves to.

Change-Id: Id41fb54e5eb975581d382767bdd125fbb9801f4f
Task-number: QTCREATORBUG-17141
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Ulf Hermann
2016-10-27 16:04:39 +02:00
parent 779c54872a
commit c0ff0b7237

View File

@@ -103,7 +103,7 @@ class RelayServer: public QObject
public: public:
RelayServer(IosTool *parent); RelayServer(IosTool *parent);
~RelayServer(); ~RelayServer();
bool startServer(int port, bool ipv6); bool startServer(int port);
void stopServer(); void stopServer();
quint16 serverPort(); quint16 serverPort();
IosTool *iosTool(); IosTool *iosTool();
@@ -113,7 +113,8 @@ public:
protected: protected:
virtual void newRelayConnection() = 0; virtual void newRelayConnection() = 0;
QTcpServer m_server; QTcpServer m_ipv4Server;
QTcpServer m_ipv6Server;
QList<Relayer *> m_connections; QList<Relayer *> m_connections;
}; };
@@ -188,7 +189,6 @@ private:
int maxProgress; int maxProgress;
int opLeft; int opLeft;
bool debug; bool debug;
bool ipv6;
bool inAppOutput; bool inAppOutput;
bool splitAppOutput; // as QXmlStreamReader reports the text attributes atomically it is better to split bool splitAppOutput; // as QXmlStreamReader reports the text attributes atomically it is better to split
Ios::IosDeviceManager::AppOp appOp; Ios::IosDeviceManager::AppOp appOp;
@@ -404,30 +404,39 @@ RelayServer::~RelayServer()
stopServer(); stopServer();
} }
bool RelayServer::startServer(int port, bool ipv6) bool RelayServer::startServer(int port)
{ {
QTC_CHECK(!m_server.isListening()); QTC_CHECK(!m_ipv4Server.isListening());
connect(&m_server, &QTcpServer::newConnection, this, &RelayServer::handleNewRelayConnection); QTC_CHECK(!m_ipv6Server.isListening());
connect(&m_ipv4Server, &QTcpServer::newConnection,
this, &RelayServer::handleNewRelayConnection);
connect(&m_ipv6Server, &QTcpServer::newConnection,
this, &RelayServer::handleNewRelayConnection);
quint16 portValue = static_cast<quint16>(port); quint16 portValue = static_cast<quint16>(port);
if (port < 0 || port > 0xFFFF) if (port < 0 || port > 0xFFFF)
return false; return false;
if (ipv6) m_ipv4Server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue);
return m_server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue); m_ipv6Server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
else return m_ipv4Server.isListening() || m_ipv6Server.isListening();
return m_server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
} }
void RelayServer::stopServer() void RelayServer::stopServer()
{ {
foreach (Relayer *connection, m_connections) foreach (Relayer *connection, m_connections)
delete connection; delete connection;
if (m_server.isListening()) if (m_ipv4Server.isListening())
m_server.close(); m_ipv4Server.close();
if (m_ipv6Server.isListening())
m_ipv6Server.close();
} }
quint16 RelayServer::serverPort() quint16 RelayServer::serverPort()
{ {
return m_server.serverPort(); if (m_ipv4Server.isListening())
return m_ipv4Server.serverPort();
if (m_ipv6Server.isListening())
return m_ipv6Server.serverPort();
return 0;
} }
IosTool *RelayServer::iosTool() IosTool *RelayServer::iosTool()
@@ -458,11 +467,12 @@ SingleRelayServer::SingleRelayServer(IosTool *parent,
void SingleRelayServer::newRelayConnection() void SingleRelayServer::newRelayConnection()
{ {
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (m_connections.size() > 0) { if (m_connections.size() > 0) {
delete m_server.nextPendingConnection(); delete clientSocket;
return; return;
} }
QTcpSocket *clientSocket = m_server.nextPendingConnection();
if (clientSocket) { if (clientSocket) {
Relayer *newConnection = new Relayer(this, clientSocket); Relayer *newConnection = new Relayer(this, clientSocket);
m_connections.append(newConnection); m_connections.append(newConnection);
@@ -482,7 +492,8 @@ GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,
void GenericRelayServer::newRelayConnection() void GenericRelayServer::newRelayConnection()
{ {
QTcpSocket *clientSocket = m_server.nextPendingConnection(); QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (clientSocket) { if (clientSocket) {
iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection")); iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection"));
RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket); RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket);
@@ -497,7 +508,6 @@ IosTool::IosTool(QObject *parent):
maxProgress(0), maxProgress(0),
opLeft(0), opLeft(0),
debug(false), debug(false),
ipv6(false),
inAppOutput(false), inAppOutput(false),
splitAppOutput(true), splitAppOutput(true),
appOp(Ios::IosDeviceManager::None), appOp(Ios::IosDeviceManager::None),
@@ -547,8 +557,6 @@ void IosTool::run(const QStringList &args)
appOp = Ios::IosDeviceManager::AppOp(appOp | Ios::IosDeviceManager::Run); appOp = Ios::IosDeviceManager::AppOp(appOp | Ios::IosDeviceManager::Run);
} else if (arg == QLatin1String("--noninteractive")) { } else if (arg == QLatin1String("--noninteractive")) {
// ignored for compatibility // ignored for compatibility
} else if (arg == QLatin1String("--ipv6")) {
ipv6 = true;
} else if (arg == QLatin1String("-v") || arg == QLatin1String("--verbose")) { } else if (arg == QLatin1String("-v") || arg == QLatin1String("--verbose")) {
echoRelays = true; echoRelays = true;
} else if (arg == QLatin1String("-d") || arg == QLatin1String("--debug")) { } else if (arg == QLatin1String("-d") || arg == QLatin1String("--debug")) {
@@ -720,12 +728,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
int qmlPort = deviceSession->qmljsDebugPort(); int qmlPort = deviceSession->qmljsDebugPort();
if (qmlPort) { if (qmlPort) {
qmlServer = new GenericRelayServer(this, qmlPort, deviceSession); qmlServer = new GenericRelayServer(this, qmlPort, deviceSession);
qmlServer->startServer(0, ipv6); qmlServer->startServer(0);
} }
} }
if (debug) { if (debug) {
gdbServer = new SingleRelayServer(this, gdbFd); gdbServer = new SingleRelayServer(this, gdbFd);
if (!gdbServer->startServer(0, ipv6)) { if (!gdbServer->startServer(0)) {
doExit(-4); doExit(-4);
return; return;
} }