Skip to content

Commit

Permalink
Identified areas that need to be worked on for IPv6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
ksuprynowicz committed Dec 26, 2024
1 parent 5cf0fc6 commit b6da491
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 134 deletions.
3 changes: 2 additions & 1 deletion assignment-client/src/Agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,10 @@ void Agent::requestScript() {

// figure out the URL for the script for this agent assignment
QUrl scriptURL;
// TODO(IPv6): IPv6 URLs have different format
if (_payload.isEmpty()) {
scriptURL = QUrl(QString("http://%1:%2/assignment/%3/")
.arg(nodeList->getDomainHandler().getIP().toString())
.arg(nodeList->getDomainHandler().getIPv4().toString())
.arg(DOMAIN_SERVER_HTTP_PORT)
.arg(uuidStringWithoutCurlyBraces(nodeList->getSessionUUID())));
} else {
Expand Down
10 changes: 6 additions & 4 deletions assignment-client/src/AssignmentClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri

// did we get an assignment-client monitor port?
if (assignmentMonitorPort > 0) {
_assignmentClientMonitorSocket = SockAddr(SocketType::UDP, DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME,
// TODO(IPv6):
_assignmentClientMonitorSocket = SockAddr(SocketType::UDP, DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, QHostAddress(),
assignmentMonitorPort);
_assignmentClientMonitorSocket.setObjectName("AssignmentClientMonitor");

Expand Down Expand Up @@ -249,7 +250,8 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
nodeList->getDomainHandler().setSockAddr(message->getSenderSockAddr(), _assignmentServerHostname);
nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID());

qCDebug(assignment_client) << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString();
qCDebug(assignment_client) << "Destination IP for assignment is" << nodeList->getDomainHandler().getIPv4().toString()
<< " " << nodeList->getDomainHandler().getIPv6().toString();

// start the deployed assignment
QThread* workerThread = new QThread();
Expand Down Expand Up @@ -287,8 +289,8 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
void AssignmentClient::handleStopNodePacket(QSharedPointer<ReceivedMessage> message) {
const SockAddr& senderSockAddr = message->getSenderSockAddr();

if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
if (senderSockAddr.getAddressIPv4() == QHostAddress::LocalHost ||
senderSockAddr.getAddressIPv6() == QHostAddress::LocalHostIPv6) {

qCDebug(assignment_client) << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode.";
QCoreApplication::quit();
Expand Down
4 changes: 2 additions & 2 deletions assignment-client/src/AssignmentClientMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<ReceivedMes

if (!matchingNode) {
// The parent only expects to be talking with programs running on this same machine.
if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
if (senderSockAddr.getAddressIPv4() == QHostAddress::LocalHost ||
senderSockAddr.getAddressIPv6() == QHostAddress::LocalHostIPv6) {

if (!senderID.isNull()) {
// We don't have this node yet - we should add it
Expand Down
3 changes: 2 additions & 1 deletion assignment-client/src/octree/OctreeServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,8 @@ void OctreeServer::readConfiguration() {
_settings = settingsSectionObject; // keep this for later

if (!readOptionString(QString("statusHost"), settingsSectionObject, _statusHost) || _statusHost.isEmpty()) {
_statusHost = getGuessedLocalAddress().toString();
// TODO(IPv6):
_statusHost = getGuessedLocalAddress(QAbstractSocket::IPv4Protocol).toString();
}
qDebug("statusHost=%s", qPrintable(_statusHost));

Expand Down
18 changes: 12 additions & 6 deletions domain-server/src/DomainGatekeeper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,17 @@ void DomainGatekeeper::updateNodePermissions() {
hardwareAddress = nodeData->getHardwareAddress();
machineFingerprint = nodeData->getMachineFingerprint();

auto sendingAddress = nodeData->getSendingSockAddr().getAddress();
// TODO(IPv6):
auto sendingAddress = nodeData->getSendingSockAddr().getAddressIPv4();
auto nodeList = limitedNodeListWeak.lock();
isLocalUser = ((nodeList && sendingAddress == nodeList->getLocalSockAddr().getAddress()) ||
// TODO(IPv6):
isLocalUser = ((nodeList && sendingAddress == nodeList->getLocalSockAddr().getAddressIPv4()) ||
sendingAddress == QHostAddress::LocalHost);
}

// TODO(IPv6):
userPerms = setPermissionsForUser(isLocalUser, verifiedUsername, verifiedDomainUserName,
connectingAddr.getAddress(), hardwareAddress, machineFingerprint);
connectingAddr.getAddressIPv4(), hardwareAddress, machineFingerprint);
}

node->setPermissions(userPerms);
Expand Down Expand Up @@ -473,9 +476,11 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
userPerms.setAll(false);

// check if this user is on our local machine - if this is true set permissions to those for a "localhost" connection
QHostAddress senderHostAddress = nodeConnection.senderSockAddr.getAddress();
// TODO(IPv6):
QHostAddress senderHostAddress = nodeConnection.senderSockAddr.getAddressIPv4();
// TODO(IPv6):
bool isLocalUser =
(senderHostAddress == limitedNodeList->getLocalSockAddr().getAddress() || senderHostAddress == QHostAddress::LocalHost);
(senderHostAddress == limitedNodeList->getLocalSockAddr().getAddressIPv4() || senderHostAddress == QHostAddress::LocalHost);

QString verifiedUsername; // if this remains empty, consider this an anonymous connection attempt
if (!username.isEmpty()) {
Expand Down Expand Up @@ -544,8 +549,9 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
}
}

// TODO(IPv6):
userPerms = setPermissionsForUser(isLocalUser, verifiedUsername, verifiedDomainUsername,
nodeConnection.senderSockAddr.getAddress(), nodeConnection.hardwareAddress,
nodeConnection.senderSockAddr.getAddressIPv4(), nodeConnection.hardwareAddress,
nodeConnection.machineFingerprint);

if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) {
Expand Down
33 changes: 22 additions & 11 deletions domain-server/src/DomainServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const QString DomainServer::REPLACEMENT_FILE_EXTENSION = ".replace";
const QString& DOMAIN_SERVER_SETTINGS_KEY = "domain_server";
const QString PUBLIC_SOCKET_ADDRESS_KEY = "network_address";
const QString PUBLIC_SOCKET_PORT_KEY = "network_port";
const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking";
const int MIN_PORT = 1;
const int MAX_PORT = 65535;

Expand Down Expand Up @@ -1496,7 +1497,8 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer<ReceivedMessage
// construct the requested assignment from the packet data
Assignment requestAssignment(*message);

auto senderAddr = message->getSenderSockAddr().getAddress();
// TODO(IPv6):
auto senderAddr = message->getSenderSockAddr().getAddressIPv4();

auto isHostAddressInSubnet = [&senderAddr](const Subnet& mask) -> bool {
return senderAddr.isInSubnet(mask);
Expand Down Expand Up @@ -1560,14 +1562,17 @@ QJsonObject jsonForDomainSocketUpdate(const SockAddr& socket) {
const QString SOCKET_PORT_KEY = "port";

QJsonObject socketObject;
socketObject[SOCKET_NETWORK_ADDRESS_KEY] = socket.getAddress().toString();
// TODO(IPv6):
socketObject[SOCKET_NETWORK_ADDRESS_KEY] = socket.getAddressIPv4().toString();
socketObject[SOCKET_PORT_KEY] = socket.getPort();

return socketObject;
}

void DomainServer::performIPAddressPortUpdate(const SockAddr& newPublicSockAddr) {
const QString& publicSocketAddress = newPublicSockAddr.getAddress().toString();
const QString& DOMAIN_SERVER_SETTINGS_KEY = "domain_server";
// TODO(IPv6):
const QString& publicSocketAddress = newPublicSockAddr.getAddressIPv4().toString();
const int publicSocketPort = newPublicSockAddr.getPort();

if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE) {
Expand Down Expand Up @@ -1711,7 +1716,8 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() {
domainObject[ICE_SERVER_ADDRESS] = "0.0.0.0";
} else {
// we're using full automatic networking and we have a current ice-server socket, use that now
domainObject[ICE_SERVER_ADDRESS] = _iceServerSocket.getAddress().toString();
// TODO(IPv6):
domainObject[ICE_SERVER_ADDRESS] = _iceServerSocket.getAddressIPv4().toString();
}

const auto& temporaryDomainKey = DependencyManager::get<AccountManager>()->getTemporaryDomainKey(getID());
Expand All @@ -1730,7 +1736,8 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() {
callbackParameters.jsonCallbackMethod = "handleSuccessfulICEServerAddressUpdate";

qCDebug(domain_server_ice) << "Updating ice-server address in Directory Services API to"
<< (_iceServerSocket.isNull() ? "" : _iceServerSocket.getAddress().toString());
<< (_iceServerSocket.isNull() ? "" : _iceServerSocket.getAddressIPv4().toString()) << " "
<< (_iceServerSocket.isNull() ? "" : _iceServerSocket.getAddressIPv6().toString());

static const QString DOMAIN_ICE_ADDRESS_UPDATE = "/api/v1/domains/%1/ice_server_address";

Expand Down Expand Up @@ -1771,7 +1778,8 @@ void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply* requestRepl
}

void DomainServer::sendHeartbeatToIceServer() {
if (!_iceServerSocket.getAddress().isNull()) {
// TODO(IPv6):
if (!_iceServerSocket.getAddressIPv4().isNull()) {

auto accountManager = DependencyManager::get<AccountManager>();
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
Expand Down Expand Up @@ -1799,7 +1807,8 @@ void DomainServer::sendHeartbeatToIceServer() {
qCWarning(domain_server_ice) << "Clearing the current ice-server socket and selecting a new candidate ice-server";

// add the current address to our list of failed addresses
_failedIceServerAddresses << _iceServerSocket.getAddress();
// TODO(IPv6):
_failedIceServerAddresses << _iceServerSocket.getAddressIPv4();

// if we've failed to hear back for three heartbeats, we clear the current ice-server socket and attempt
// to randomize a new one
Expand Down Expand Up @@ -1992,7 +2001,8 @@ void DomainServer::processNodeJSONStatsPacket(QSharedPointer<ReceivedMessage> pa
QJsonObject DomainServer::jsonForSocket(const SockAddr& socket) {
QJsonObject socketJSON;

socketJSON["ip"] = socket.getAddress().toString();
// TODO(IPv6): IPv6 needs to be added here too
socketJSON["ip"] = socket.getAddressIPv4().toString();
socketJSON["port"] = socket.getPort();

return socketJSON;
Expand Down Expand Up @@ -3586,8 +3596,8 @@ void DomainServer::handleICEHostInfo(const QHostInfo& hostInfo) {
QList<QHostAddress> sanitizedAddresses = hostInfo.addresses();
auto it = sanitizedAddresses.begin();
while (it != sanitizedAddresses.end()) {
//if (!it->isNull() && it->protocol() == QAbstractSocket::IPv4Protocol) {
if (!it->isNull() && it->protocol() == QAbstractSocket::AnyIPProtocol) {
// TODO(IPv6):
if (!it->isNull() && it->protocol() == QAbstractSocket::IPv4Protocol) {
++it;
} else {
it = sanitizedAddresses.erase(it);
Expand Down Expand Up @@ -3664,7 +3674,8 @@ void DomainServer::randomizeICEServerAddress(bool shouldTriggerHostLookup) {
indexToTry = distribution(generator);
}

_iceServerSocket = SockAddr { SocketType::UDP, candidateICEAddresses[indexToTry], ICE_SERVER_DEFAULT_PORT };
// TODO(IPv6):
_iceServerSocket = SockAddr { SocketType::UDP, candidateICEAddresses[indexToTry], QHostAddress(), ICE_SERVER_DEFAULT_PORT };
qCInfo(domain_server_ice) << "Set candidate ice-server socket to" << _iceServerSocket;

// clear our number of hearbeat denials, this should be re-set on ice-server change
Expand Down
10 changes: 6 additions & 4 deletions domain-server/src/DomainServerSettingsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,16 +989,18 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
}

if (banByIP) {
// TODO(IPv6):
auto& kickAddress = matchingNode->getActiveSocket()
? matchingNode->getActiveSocket()->getAddress()
: matchingNode->getPublicSocket().getAddress();
? matchingNode->getActiveSocket()->getAddressIPv4()
: matchingNode->getPublicSocket().getAddressIPv4();

// probably isLoopback covers it, as whenever I try to ban an agent on same machine as the domain-server
// it is always 127.0.0.1, but looking at the public and local addresses just to be sure
// TODO: soon we will have feedback (in the form of a message to the client) after we kick. When we
// do, we will have a success flag, and perhaps a reason for failure. For now, just don't do it.
if (kickAddress == limitedNodeList->getPublicSockAddr().getAddress() ||
kickAddress == limitedNodeList->getLocalSockAddr().getAddress() ||
// TODO(IPv6):
if (kickAddress == limitedNodeList->getPublicSockAddr().getAddressIPv4() ||
kickAddress == limitedNodeList->getLocalSockAddr().getAddressIPv4() ||
kickAddress.isLoopback() ) {
qWarning() << "attempt to kick node running on same machine as domain server, ignoring KickRequest";
return;
Expand Down
12 changes: 8 additions & 4 deletions domain-server/src/NodeConnectionData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
}

// We don't know whether it's a public or local connection so set both the same.
auto address = senderSockAddr.getAddress();
// TODO(IPv6):
auto address = senderSockAddr.getAddressIPv4();
auto port = senderSockAddr.getPort();
newHeader.publicSockAddr.setAddress(address);
newHeader.publicSockAddr.setPort(port);
Expand All @@ -77,16 +78,19 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c

newHeader.senderSockAddr = senderSockAddr;

if (newHeader.publicSockAddr.getAddress().isNull()) {
// TODO(IPv6):
if (newHeader.publicSockAddr.getAddressIPv4().isNull()) {
// this node wants to use us its STUN server
// so set the node public address to whatever we perceive the public address to be

// if the sender is on our box then leave its public address to 0 so that
// other users attempt to reach it on the same address they have for the domain-server
if (senderSockAddr.getAddress().isLoopback()) {
// TODO(IPv6):
if (senderSockAddr.getAddressIPv4().isLoopback()) {
newHeader.publicSockAddr.setAddress(QHostAddress());
} else {
newHeader.publicSockAddr.setAddress(senderSockAddr.getAddress());
// TODO(IPv6):
newHeader.publicSockAddr.setAddress(senderSockAddr.getAddressIPv4());
}
}

Expand Down
3 changes: 2 additions & 1 deletion interface/src/DiscoverabilityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ void DiscoverabilityManager::updateLocation() {
// in case the place/domain isn't in the database, we send the network address and port
auto& domainSockAddr = domainHandler.getSockAddr();
const QString NETWORK_ADDRESS_KEY_IN_LOCATION = "network_address";
locationObject.insert(NETWORK_ADDRESS_KEY_IN_LOCATION, domainSockAddr.getAddress().toString());
// TODO(IPv6):
locationObject.insert(NETWORK_ADDRESS_KEY_IN_LOCATION, domainSockAddr.getAddressIPv4().toString());

const QString NETWORK_ADDRESS_PORT_IN_LOCATION = "network_port";
locationObject.insert(NETWORK_ADDRESS_PORT_IN_LOCATION, domainSockAddr.getPort());
Expand Down
Loading

0 comments on commit b6da491

Please sign in to comment.