Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions assignment-client/src/AssignmentClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const QString ASSIGNMENT_CLIENT_TARGET_NAME = "assignment-client";
const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000;

AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, QString assignmentServerHostname,
quint16 listenPort, int publicListenPort, QString assignmentServerHostname,
quint16 assignmentServerPort, quint16 assignmentMonitorPort,
bool disableDomainPortAutoDiscovery) :
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME)
Expand All @@ -60,7 +60,8 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
auto addressManager = DependencyManager::set<AddressManager>();

// create a NodeList as an unassigned client, must be after addressManager
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned, listenPort);
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned,
listenPort, INVALID_PORT, publicListenPort);

nodeList->startThread();
// set the logging target to the the CHILD_TARGET_NAME
Expand Down
2 changes: 1 addition & 1 deletion assignment-client/src/AssignmentClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class AssignmentClient : public QObject {
Q_OBJECT
public:
AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, QString assignmentServerHostname,
quint16 listenPort, int publicListenPort, QString assignmentServerHostname,
quint16 assignmentServerPort, quint16 assignmentMonitorPort,
bool disableDomainPortAutoDiscovery);
~AssignmentClient();
Expand Down
30 changes: 26 additions & 4 deletions assignment-client/src/AssignmentClientApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,21 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
"UDP port for this assignment client (or monitor)", "port");
parser.addOption(portOption);

const QCommandLineOption publicPortOption(ASSIGNMENT_CLIENT_LISTEN_PUBLIC_PORT_OPTION,
"Public UDP port for this assignment client (or monitor), optional", "port");
parser.addOption(publicPortOption);

const QCommandLineOption minChildListenPort(ASSIGNMENT_MONITOR_MIN_CHILDREN_LISTEN_PORT_OPTION,
"Minimum UDP listen port", "port");
parser.addOption(minChildListenPort);

const QCommandLineOption useSamePublicPortsOption(ASSIGNMENT_MONITOR_USE_SAME_PUBLIC_PORTS_OPTION,
"Normally public ports are discovered using STUN server. "
"Sometimes this doesn't work and gives wrong port names. "
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Sometimes this doesn't work and gives wrong port names. "
"Sometimes this doesn't work and gives wrong port numbers. "

"In such case this option can be used together with port forwarding on the router. "
"Needs to be used together with --min-listen-port.");
parser.addOption(useSamePublicPortsOption);

const QCommandLineOption assignmentServerHostnameOption(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION,
"set assignment-server hostname", "hostname");
parser.addOption(assignmentServerHostnameOption);
Expand Down Expand Up @@ -208,7 +219,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
assignmentServerHostname = parser.value(assignmentServerHostnameOption);
}

// check for an overriden assignment server port
// check for an overridden assignment server port
quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT;
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) {
assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toUInt();
Expand All @@ -223,7 +234,12 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
childMinListenPort = argumentVariantMap.value(ASSIGNMENT_MONITOR_MIN_CHILDREN_LISTEN_PORT_OPTION).toUInt();
}

// check for an overidden listen port
bool useSamePublicPorts = false;
if (parser.isSet(useSamePublicPortsOption)) {
useSamePublicPorts = true;
}

// check for an overridden listen port
quint16 listenPort = 0;
if (argumentVariantMap.contains(ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION)) {
listenPort = argumentVariantMap.value(ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION).toUInt();
Expand All @@ -233,6 +249,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
listenPort = parser.value(portOption).toUInt();
}

int publicListenPort = INVALID_PORT;
if (parser.isSet(publicPortOption)) {
publicListenPort = parser.value(publicPortOption).toInt();
}

if (parser.isSet(numChildsOption)) {
if (minForks && minForks > numForks) {
qCritical() << "--min can't be more than -n";
Expand Down Expand Up @@ -271,13 +292,14 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
if (numForks || minForks || maxForks) {
AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks,
requestAssignmentType, assignmentPool, listenPort,
childMinListenPort, assignmentServerHostname,
childMinListenPort, useSamePublicPorts, assignmentServerHostname,
assignmentServerPort, httpStatusPort, logDirectory,
disableDomainPortAutoDiscovery);
monitor->setParent(this);
connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit);
} else {
AssignmentClient* client = new AssignmentClient(requestAssignmentType, assignmentPool, listenPort,
AssignmentClient* client = new AssignmentClient(requestAssignmentType, assignmentPool,
listenPort, publicListenPort,
assignmentServerHostname,
assignmentServerPort, monitorPort,
disableDomainPortAutoDiscovery);
Expand Down
2 changes: 2 additions & 0 deletions assignment-client/src/AssignmentClientApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "t";
const QString ASSIGNMENT_POOL_OPTION = "pool";
const QString ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION = "p";
const QString ASSIGNMENT_CLIENT_LISTEN_PUBLIC_PORT_OPTION = "public-port";
const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "a";
const QString ASSIGNMENT_MONITOR_MIN_CHILDREN_LISTEN_PORT_OPTION = "min-listen-port";
const QString ASSIGNMENT_MONITOR_USE_SAME_PUBLIC_PORTS_OPTION = "use-same-public-ports";
const QString CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION = "server-port";
const QString ASSIGNMENT_NUM_FORKS_OPTION = "n";
const QString ASSIGNMENT_MIN_FORKS_OPTION = "min";
Expand Down
9 changes: 8 additions & 1 deletion assignment-client/src/AssignmentClientMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
const unsigned int minAssignmentClientForks,
const unsigned int maxAssignmentClientForks,
Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, quint16 childMinListenPort, QString assignmentServerHostname,
quint16 listenPort, quint16 childMinListenPort, bool useSamePublicPorts,
QString assignmentServerHostname,
quint16 assignmentServerPort, quint16 httpStatusServerPort, QString logDirectory,
bool disableDomainPortAutoDiscovery) :
_httpManager(QHostAddress::LocalHost, httpStatusServerPort, "", this),
Expand All @@ -53,6 +54,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
_assignmentServerHostname(assignmentServerHostname),
_assignmentServerPort(assignmentServerPort),
_childMinListenPort(childMinListenPort),
_useSamePublicPorts(useSamePublicPorts),
_disableDomainPortAutoDiscovery(disableDomainPortAutoDiscovery)
{
qDebug() << "_requestAssignmentType =" << _requestAssignmentType;
Expand Down Expand Up @@ -205,6 +207,11 @@ void AssignmentClientMonitor::spawnChildClient() {
_childArguments.append(QString::number(listenPort));
}

if (_useSamePublicPorts && listenPort) {
_childArguments.append("--" + ASSIGNMENT_CLIENT_LISTEN_PUBLIC_PORT_OPTION);
_childArguments.append(QString::number(listenPort));
}

// tell children which assignment monitor port to use
// for now they simply talk to us on localhost
_childArguments.append("--" + ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION);
Expand Down
4 changes: 3 additions & 1 deletion assignment-client/src/AssignmentClientMonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class AssignmentClientMonitor : public QObject, public HTTPRequestHandler {
public:
AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks,
const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType,
QString assignmentPool, quint16 listenPort, quint16 childMinListenPort,
QString assignmentPool, quint16 listenPort, quint16 childMinListenPort, bool useSamePublicPorts,
QString assignmentServerHostname, quint16 assignmentServerPort, quint16 httpStatusServerPort,
QString logDirectory, bool disableDomainPortAutoDiscovery);
~AssignmentClientMonitor();
Expand Down Expand Up @@ -80,6 +80,8 @@ public slots:
quint16 _childMinListenPort;
QSet<quint16> _childListenPorts;

bool _useSamePublicPorts { false };

bool _wantsChildFileLogging { false };
bool _disableDomainPortAutoDiscovery { false };
};
Expand Down
18 changes: 15 additions & 3 deletions libraries/networking/src/LimitedNodeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.Loc
using namespace std::chrono_literals;
static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL_MS = 1s;

LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort, int publicListenPort) :
_nodeSocket(this, true),
_publicPortOverride(publicListenPort),
_packetReceiver(new PacketReceiver(this))
{
qRegisterMetaType<ConnectionStep>("ConnectionStep");
Expand Down Expand Up @@ -1107,15 +1108,26 @@ void LimitedNodeList::processSTUNResponse(std::unique_ptr<udt::BasePacket> packe
uint16_t newPublicPort;
QHostAddress newPublicAddress;
if (parseSTUNResponse(packet.get(), newPublicAddress, newPublicPort)) {
// We consider port change only if public port is not overridden by the user.
bool portChanged = _publicPortOverride == INVALID_PORT ?
(newPublicPort != _publicSockAddr.getPort()) : false;

if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) {
if (newPublicAddress != _publicSockAddr.getAddress() || portChanged) {
qCDebug(networking, "New public socket received from STUN server is %s:%hu (was %s:%hu)",
newPublicAddress.toString().toStdString().c_str(),
newPublicPort,
_publicSockAddr.getAddress().toString().toLocal8Bit().constData(),
_publicSockAddr.getPort());

_publicSockAddr = SockAddr(SocketType::UDP, newPublicAddress, newPublicPort);
if (_publicPortOverride == INVALID_PORT) {
_publicSockAddr = SockAddr(SocketType::UDP, newPublicAddress, newPublicPort);
} else {
// Port is forwarded to a public port specified by user.
qDebug(networking) << "Public port is specified by the user, address and port is "
<< newPublicAddress.toString() << ":"
<< _publicPortOverride;
_publicSockAddr = SockAddr(SocketType::UDP, newPublicAddress, _publicPortOverride);
}

if (!_hasCompletedInitialSTUN) {
// if we're here we have definitely completed our initial STUN sequence
Expand Down
6 changes: 5 additions & 1 deletion libraries/networking/src/LimitedNodeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ protected slots:
QUuid connectionSecretUUID;
};

LimitedNodeList(int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
LimitedNodeList(int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT, int publicListenPort = INVALID_PORT);
LimitedNodeList(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
void operator=(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton

Expand Down Expand Up @@ -446,6 +446,10 @@ protected slots:
udt::Socket _nodeSocket;
QUdpSocket* _dtlsSocket { nullptr };
SockAddr _localSockAddr;

// When local port is forwarded to the public one we don't want to use UDP hole punching on this side and instead use the port directly.
int _publicPortOverride { INVALID_PORT };

SockAddr _publicSockAddr;
SockAddr _stunSockAddr { SocketType::UDP, STUN_SERVER_HOSTNAME, STUN_SERVER_PORT };
bool _hasTCPCheckedLocalSocket { false };
Expand Down
4 changes: 2 additions & 2 deletions libraries/networking/src/NodeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ using namespace std::chrono;
const int KEEPALIVE_PING_INTERVAL_MS = 1000;
const int MAX_SYSTEM_INFO_SIZE = 1000;

NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) :
LimitedNodeList(socketListenPort, dtlsListenPort),
NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort, int publicListenPort) :
LimitedNodeList(socketListenPort, dtlsListenPort, publicListenPort),
_ownerType(newOwnerType),
_nodeTypesOfInterest(),
_domainHandler(this),
Expand Down
2 changes: 1 addition & 1 deletion libraries/networking/src/NodeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ private slots:
NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) {
assert(false); // Not implemented, needed for DependencyManager templates compile
}
NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT, int publicListenPort = INVALID_PORT);

void processDomainServerAuthRequest(const QByteArray& packet);
void requestAuthForDomainServer();
Expand Down
Loading