Commit dc16ca85 authored by Kai Koehne's avatar Kai Koehne

Remove tcpportsgatherer

Has not been used since a while.

Change-Id: I53cf42d723c2f4d822ad63923b857f119e5cfa58
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent a4d00327
...@@ -229,7 +229,6 @@ tmp/ ...@@ -229,7 +229,6 @@ tmp/
/tests/manual/ssh/sftpfsmodel/sftpfsmodel /tests/manual/ssh/sftpfsmodel/sftpfsmodel
/tests/manual/ssh/shell/shell /tests/manual/ssh/shell/shell
/tests/manual/ssh/tunnel/tunnel /tests/manual/ssh/tunnel/tunnel
/tests/manual/utils/tcpportsgatherer/tst_tcpportsgatherer
/tests/tools/qml-ast2dot/qml-ast2dot /tests/tools/qml-ast2dot/qml-ast2dot
/tests/valgrind/memcheck/modeldemo /tests/valgrind/memcheck/modeldemo
/tests/valgrind/memcheck/parsertests /tests/valgrind/memcheck/parsertests
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "tcpportsgatherer.h"
#include "qtcassert.h"
#include <utils/hostosinfo.h>
#include <QDebug>
#include <QFile>
#include <QProcess>
#ifdef Q_OS_WIN
#include <QLibrary>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#endif
#if defined(Q_OS_WIN) && defined(Q_CC_MINGW)
// Missing declarations for MinGW 32.
#if __GNUC__ == 4 && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2)
typedef enum { } MIB_TCP_STATE;
#endif
typedef struct _MIB_TCP6ROW {
MIB_TCP_STATE State;
IN6_ADDR LocalAddr;
DWORD dwLocalScopeId;
DWORD dwLocalPort;
IN6_ADDR RemoteAddr;
DWORD dwRemoteScopeId;
DWORD dwRemotePort;
} MIB_TCP6ROW, *PMIB_TCP6ROW;
typedef struct _MIB_TCP6TABLE {
DWORD dwNumEntries;
MIB_TCP6ROW table[ANY_SIZE];
} MIB_TCP6TABLE, *PMIB_TCP6TABLE;
#endif // defined(Q_OS_WIN) && defined(Q_CC_MINGW)
namespace Utils {
namespace Internal {
class TcpPortsGathererPrivate
{
public:
TcpPortsGathererPrivate()
: protocol(QAbstractSocket::UnknownNetworkLayerProtocol) {}
QAbstractSocket::NetworkLayerProtocol protocol;
QSet<int> usedPorts;
void updateWin();
void updateLinux();
void updateNetstat();
};
#ifdef Q_OS_WIN
template <typename Table >
QSet<int> usedTcpPorts(ULONG (__stdcall *Func)(Table*, PULONG, BOOL))
{
Table *table = static_cast<Table*>(malloc(sizeof(Table)));
DWORD dwSize = sizeof(Table);
// get the necessary size into the dwSize variable
DWORD dwRetVal = Func(table, &dwSize, false);
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
free(table);
table = static_cast<Table*>(malloc(dwSize));
}
// get the actual data
QSet<int> result;
dwRetVal = Func(table, &dwSize, false);
if (dwRetVal == NO_ERROR) {
for (quint32 i = 0; i < table->dwNumEntries; i++) {
quint16 port = ntohs(table->table[i].dwLocalPort);
if (!result.contains(port))
result.insert(port);
}
} else {
qWarning() << "TcpPortsGatherer: GetTcpTable failed with" << dwRetVal;
}
free(table);
return result;
}
#endif
void TcpPortsGathererPrivate::updateWin()
{
#ifdef Q_OS_WIN
QSet<int> ports;
if (protocol == QAbstractSocket::IPv4Protocol) {
ports.unite(usedTcpPorts<MIB_TCPTABLE>(GetTcpTable));
} else {
//Dynamically load symbol for GetTcp6Table for systems that dont have support for IPV6,
//eg Windows XP
typedef ULONG (__stdcall *GetTcp6TablePtr)(PMIB_TCP6TABLE, PULONG, BOOL);
static GetTcp6TablePtr getTcp6TablePtr = 0;
if (!getTcp6TablePtr)
getTcp6TablePtr = (GetTcp6TablePtr)QLibrary::resolve(QLatin1String("Iphlpapi.dll"),
"GetTcp6Table");
if (getTcp6TablePtr && (protocol == QAbstractSocket::IPv6Protocol)) {
ports.unite(usedTcpPorts<MIB_TCP6TABLE>(getTcp6TablePtr));
} else if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol) {
ports.unite(usedTcpPorts<MIB_TCPTABLE>(GetTcpTable));
if (getTcp6TablePtr)
ports.unite(usedTcpPorts<MIB_TCP6TABLE>(getTcp6TablePtr));
}
}
foreach (int port, ports)
usedPorts.insert(port);
#endif
Q_UNUSED(protocol);
}
void TcpPortsGathererPrivate::updateLinux()
{
QStringList filePaths;
const QString tcpFile = QLatin1String("/proc/net/tcp");
const QString tcp6File = QLatin1String("/proc/net/tcp6");
if (protocol == QAbstractSocket::IPv4Protocol)
filePaths << tcpFile;
else if (protocol == QAbstractSocket::IPv6Protocol)
filePaths << tcp6File;
else
filePaths << tcpFile << tcp6File;
foreach (const QString &filePath, filePaths) {
QFile file(filePath);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qWarning() << "TcpPortsGatherer: Cannot open file"
<< filePath << ":" << file.errorString();
continue;
}
if (file.atEnd()) // read first line describing the output
file.readLine();
static QRegExp pattern(QLatin1String("^\\s*" // start of line, whitespace
"\\d+:\\s*" // integer, colon, space
"[0-9A-Fa-f]+:" // hexadecimal number (ip), colon
"([0-9A-Fa-f]+)" // hexadecimal number (port!)
));
while (!file.atEnd()) {
QByteArray line = file.readLine();
if (pattern.indexIn(QLatin1String(line)) != -1) {
bool isNumber;
quint16 port = pattern.cap(1).toUShort(&isNumber, 16);
QTC_ASSERT(isNumber, continue);
usedPorts.insert(port);
} else {
qWarning() << "TcpPortsGatherer: File" << filePath << "has unexpected format.";
continue;
}
}
}
}
// Only works with FreeBSD version of netstat like we have on Mac OS X
void TcpPortsGathererPrivate::updateNetstat()
{
QStringList netstatArgs;
netstatArgs.append(QLatin1String("-a")); // show also sockets of server processes
netstatArgs.append(QLatin1String("-n")); // show network addresses as numbers
netstatArgs.append(QLatin1String("-p"));
netstatArgs.append(QLatin1String("tcp"));
if (protocol != QAbstractSocket::UnknownNetworkLayerProtocol) {
netstatArgs.append(QLatin1String("-f")); // limit to address family
if (protocol == QAbstractSocket::IPv4Protocol)
netstatArgs.append(QLatin1String("inet"));
else
netstatArgs.append(QLatin1String("inet6"));
}
QProcess netstatProcess;
netstatProcess.start(QLatin1String("netstat"), netstatArgs);
if (!netstatProcess.waitForFinished(30000)) {
qWarning() << "TcpPortsGatherer: netstat did not return in time.";
return;
}
QList<QByteArray> output = netstatProcess.readAllStandardOutput().split('\n');
foreach (const QByteArray &line, output) {
static QRegExp pattern(QLatin1String("^tcp[46]+" // "tcp", followed by "4", "6", "46"
"\\s+\\d+" // whitespace, number (Recv-Q)
"\\s+\\d+" // whitespace, number (Send-Q)
"\\s+(\\S+)")); // whitespace, Local Address
if (pattern.indexIn(QLatin1String(line)) != -1) {
QString localAddress = pattern.cap(1);
// Examples of local addresses:
// '*.56501' , '*.*' 'fe80::1%lo0.123'
int portDelimiterPos = localAddress.lastIndexOf(QLatin1Char('.'));
if (portDelimiterPos == -1)
continue;
localAddress = localAddress.mid(portDelimiterPos + 1);
bool isNumber;
quint16 port = localAddress.toUShort(&isNumber);
if (!isNumber)
continue;
usedPorts.insert(port);
}
}
}
} // namespace Internal
/*!
\class Utils::TcpPortsGatherer
\brief The TcpPortsGatherer class gathers the list of local TCP ports
already in use.
Queries the system for the list of local TCP ports already in use. This
information can be used
to select a port for use in a range.
*/
TcpPortsGatherer::TcpPortsGatherer()
: d(new Internal::TcpPortsGathererPrivate())
{
}
TcpPortsGatherer::~TcpPortsGatherer()
{
delete d;
}
void TcpPortsGatherer::update(QAbstractSocket::NetworkLayerProtocol protocol)
{
d->protocol = protocol;
d->usedPorts.clear();
if (HostOsInfo::isWindowsHost())
d->updateWin();
else if (HostOsInfo::isLinuxHost())
d->updateLinux();
else
d->updateNetstat();
}
QList<int> TcpPortsGatherer::usedPorts() const
{
return d->usedPorts.values();
}
/*!
Selects a port out of \a freePorts that is not yet used.
Returns the port, or -1 if no free port is available.
*/
int TcpPortsGatherer::getNextFreePort(PortList *freePorts) const
{
QTC_ASSERT(freePorts, return -1);
while (freePorts->hasMore()) {
const int port = freePorts->getNext();
if (!d->usedPorts.contains(port))
return port;
}
return -1;
}
} // namespace Utils
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#ifndef TCPPORTSGATHERER_H
#define TCPPORTSGATHERER_H
#include "portlist.h"
#include <QAbstractSocket>
namespace Utils {
namespace Internal { class TcpPortsGathererPrivate; }
class QTCREATOR_UTILS_EXPORT TcpPortsGatherer
{
public:
TcpPortsGatherer();
~TcpPortsGatherer();
void update(QAbstractSocket::NetworkLayerProtocol protocol);
QList<int> usedPorts() const;
int getNextFreePort(PortList *port) const;
private:
Internal::TcpPortsGathererPrivate *d;
};
} // namespace Utils
#endif // TCPPORTSGATHERER_H
...@@ -70,7 +70,6 @@ SOURCES += $$PWD/environment.cpp \ ...@@ -70,7 +70,6 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/completingtextedit.cpp \ $$PWD/completingtextedit.cpp \
$$PWD/json.cpp \ $$PWD/json.cpp \
$$PWD/portlist.cpp \ $$PWD/portlist.cpp \
$$PWD/tcpportsgatherer.cpp \
$$PWD/appmainwindow.cpp \ $$PWD/appmainwindow.cpp \
$$PWD/sleep.cpp \ $$PWD/sleep.cpp \
$$PWD/basetreeview.cpp \ $$PWD/basetreeview.cpp \
...@@ -170,7 +169,6 @@ HEADERS += \ ...@@ -170,7 +169,6 @@ HEADERS += \
$$PWD/json.h \ $$PWD/json.h \
$$PWD/runextensions.h \ $$PWD/runextensions.h \
$$PWD/portlist.h \ $$PWD/portlist.h \
$$PWD/tcpportsgatherer.h \
$$PWD/appmainwindow.h \ $$PWD/appmainwindow.h \
$$PWD/sleep.h \ $$PWD/sleep.h \
$$PWD/basetreeview.h \ $$PWD/basetreeview.h \
......
...@@ -200,8 +200,6 @@ QtcLibrary { ...@@ -200,8 +200,6 @@ QtcLibrary {
"stylehelper.h", "stylehelper.h",
"synchronousprocess.cpp", "synchronousprocess.cpp",
"synchronousprocess.h", "synchronousprocess.h",
"tcpportsgatherer.cpp",
"tcpportsgatherer.h",
"templateengine.cpp", "templateengine.cpp",
"templateengine.h", "templateengine.h",
"textfieldcheckbox.cpp", "textfieldcheckbox.cpp",
......
...@@ -4,7 +4,6 @@ SUBDIRS= \ ...@@ -4,7 +4,6 @@ SUBDIRS= \
fakevim \ fakevim \
debugger \ debugger \
subdir_proparser \ subdir_proparser \
utils \
shootout shootout
unix { unix {
......
#include <QCoreApplication>
#include <utils/tcpportsgatherer.h>
#include <QDebug>
#include <QStringList>
using namespace Utils;
int main()
{
qDebug() << "Used TCP Ports (IP4):";
TcpPortsGatherer portsGatherer;
portsGatherer.update(QAbstractSocket::IPv4Protocol);
qDebug() << portsGatherer.usedPorts();
qDebug() << "Used TCP Ports (IP6):";
portsGatherer.update(QAbstractSocket::IPv6Protocol);
qDebug() << portsGatherer.usedPorts();
qDebug() << "All Used TCP Ports:";
portsGatherer.update(QAbstractSocket::UnknownNetworkLayerProtocol);
qDebug() << portsGatherer.usedPorts();
qDebug() << "Getting a few ports ...";
PortList portList = PortList::fromString(QLatin1String("10000-10100"));
QStringList ports;
for (int i = 0; i < 10; ++i) {
quint16 port = portsGatherer.getNextFreePort(&portList);
Q_ASSERT(!portsGatherer.usedPorts().contains(port));
Q_ASSERT(port >= 10000);
Q_ASSERT(port < 10100);
QString portStr = QString::number(port);
Q_ASSERT(!ports.contains(portStr));
ports.append(QString::number(port));
}
qDebug() << ports.join(QLatin1String(", "));
return 0;
}
QTC_LIB_DEPENDS += utils
include(../../../auto/qttest.pri)
QT += network
CONFIG += console
CONFIG -= app_bundle
SOURCES += main.cpp
import qbs 1.0
Application {
name: "tcpportsgatherer"
files: [
"main.cpp",
"../../../../src/libs/utils/portlist.cpp",
"../../../../src/libs/utils/portlist.h",
"../../../../src/libs/utils/tcpportsgatherer.cpp",
"../../../../src/libs/utils/tcpportsgatherer.h"
]
cpp.includePaths: [ "../../../../src/libs" ]
cpp.defines: [ "QTCREATOR_UTILS_STATIC_LIB" ]
Properties {
condition: qbs.targetOS == "windows"
cpp.dynamicLibraries: [ "iphlpapi.lib", "ws2_32.lib" ]
}
Depends { name: "cpp" }
Depends { name: "Qt"; submodules: ["widgets"] }
}
TEMPLATE = subdirs
SUBDIRS = tcpportsgatherer
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment