mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 15:47:02 +02:00
build out more of the ice-server, make connect requests from NodeList
This commit is contained in:
parent
9baf983d07
commit
cca1c30207
10 changed files with 154 additions and 55 deletions
|
@ -9,10 +9,62 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <PacketHeaders.h>
|
||||||
|
|
||||||
#include "IceServer.h"
|
#include "IceServer.h"
|
||||||
|
|
||||||
IceServer::IceServer(int argc, char* argv[]) :
|
IceServer::IceServer(int argc, char* argv[]) :
|
||||||
QCoreApplication(argc, argv)
|
QCoreApplication(argc, argv),
|
||||||
|
_serverSocket()
|
||||||
{
|
{
|
||||||
|
// start the ice-server socket
|
||||||
|
qDebug() << "ice-server socket is listening on" << ICE_SERVER_DEFAULT_PORT;
|
||||||
|
_serverSocket.bind(QHostAddress::AnyIPv4, ICE_SERVER_DEFAULT_PORT);
|
||||||
|
|
||||||
|
// call our process datagrams slot when the UDP socket has packets ready
|
||||||
|
connect(&_serverSocket, &QUdpSocket::readyRead, this, &IceServer::processDatagrams);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IceServer::processDatagrams() {
|
||||||
|
HifiSockAddr sendingSockAddr;
|
||||||
|
QByteArray incomingPacket;
|
||||||
|
|
||||||
|
while (_serverSocket.hasPendingDatagrams()) {
|
||||||
|
incomingPacket.resize(_serverSocket.pendingDatagramSize());
|
||||||
|
|
||||||
|
_serverSocket.readDatagram(incomingPacket.data(), incomingPacket.size(),
|
||||||
|
sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer());
|
||||||
|
|
||||||
|
|
||||||
|
if (packetTypeForPacket(incomingPacket) == PacketTypeIceServerHeartbeat) {
|
||||||
|
QUuid senderUUID = uuidFromPacketHeader(incomingPacket);
|
||||||
|
|
||||||
|
// pull the public and private sock addrs for this peer
|
||||||
|
HifiSockAddr publicSocket, localSocket;
|
||||||
|
|
||||||
|
QDataStream hearbeatStream(incomingPacket);
|
||||||
|
hearbeatStream.skipRawData(numBytesForPacketHeader(incomingPacket));
|
||||||
|
|
||||||
|
hearbeatStream >> publicSocket >> localSocket;
|
||||||
|
|
||||||
|
// make sure we have this sender in our peer hash
|
||||||
|
SharedNetworkPeer matchingPeer = _activePeers.value(senderUUID);
|
||||||
|
|
||||||
|
if (!matchingPeer) {
|
||||||
|
// if we don't have this sender we need to create them now
|
||||||
|
matchingPeer = SharedNetworkPeer(new NetworkPeer(senderUUID, publicSocket, localSocket));
|
||||||
|
|
||||||
|
qDebug() << "Added a new network peer" << *matchingPeer;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// we already had the peer so just potentially update their sockets
|
||||||
|
matchingPeer->setPublicSocket(publicSocket);
|
||||||
|
matchingPeer->setLocalSocket(localSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this node also included a UUID that they would like to connect to
|
||||||
|
QUuid connectRequestUUID;
|
||||||
|
hearbeatStream >> connectRequestUUID;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,20 @@
|
||||||
#ifndef hifi_IceServer_h
|
#ifndef hifi_IceServer_h
|
||||||
#define hifi_IceServer_h
|
#define hifi_IceServer_h
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <qcoreapplication.h>
|
||||||
|
#include <qsharedpointer.h>
|
||||||
|
#include <qudpsocket.h>
|
||||||
|
|
||||||
|
#include <NetworkPeer.h>
|
||||||
|
|
||||||
class IceServer : public QCoreApplication {
|
class IceServer : public QCoreApplication {
|
||||||
public:
|
public:
|
||||||
IceServer(int argc, char* argv[]);
|
IceServer(int argc, char* argv[]);
|
||||||
|
private slots:
|
||||||
|
void processDatagrams();
|
||||||
|
private:
|
||||||
|
QHash<QUuid, SharedNetworkPeer> _activePeers;
|
||||||
|
QUdpSocket _serverSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_IceServer_h
|
#endif // hifi_IceServer_h
|
|
@ -25,6 +25,7 @@ DomainHandler::DomainHandler(QObject* parent) :
|
||||||
_uuid(),
|
_uuid(),
|
||||||
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||||
_assignmentUUID(),
|
_assignmentUUID(),
|
||||||
|
_requiresICE(true),
|
||||||
_isConnected(false),
|
_isConnected(false),
|
||||||
_handshakeTimer(NULL),
|
_handshakeTimer(NULL),
|
||||||
_settingsObject(),
|
_settingsObject(),
|
||||||
|
@ -35,6 +36,7 @@ DomainHandler::DomainHandler(QObject* parent) :
|
||||||
|
|
||||||
void DomainHandler::clearConnectionInfo() {
|
void DomainHandler::clearConnectionInfo() {
|
||||||
_uuid = QUuid();
|
_uuid = QUuid();
|
||||||
|
_requiresICE = true;
|
||||||
_isConnected = false;
|
_isConnected = false;
|
||||||
emit disconnectedFromDomain();
|
emit disconnectedFromDomain();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@ public:
|
||||||
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
||||||
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
||||||
|
|
||||||
|
bool requiresICE() const { return _requiresICE; }
|
||||||
|
|
||||||
bool isConnected() const { return _isConnected; }
|
bool isConnected() const { return _isConnected; }
|
||||||
void setIsConnected(bool isConnected);
|
void setIsConnected(bool isConnected);
|
||||||
|
|
||||||
|
@ -85,6 +87,7 @@ private:
|
||||||
QString _hostname;
|
QString _hostname;
|
||||||
HifiSockAddr _sockAddr;
|
HifiSockAddr _sockAddr;
|
||||||
QUuid _assignmentUUID;
|
QUuid _assignmentUUID;
|
||||||
|
bool _requiresICE;
|
||||||
bool _isConnected;
|
bool _isConnected;
|
||||||
QTimer* _handshakeTimer;
|
QTimer* _handshakeTimer;
|
||||||
QJsonObject _settingsObject;
|
QJsonObject _settingsObject;
|
||||||
|
|
|
@ -63,4 +63,11 @@ void NetworkPeer::activatePublicSocket() {
|
||||||
void NetworkPeer::activateSymmetricSocket() {
|
void NetworkPeer::activateSymmetricSocket() {
|
||||||
qDebug() << "Activating symmetric socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
qDebug() << "Activating symmetric socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
||||||
_activeSocket = &_symmetricSocket;
|
_activeSocket = &_symmetricSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const NetworkPeer &peer) {
|
||||||
|
debug << uuidStringWithoutCurlyBraces(peer.getUUID())
|
||||||
|
<< "- public:" << peer.getPublicSocket()
|
||||||
|
<< "- local:" << peer.getLocalSocket();
|
||||||
|
return debug;
|
||||||
}
|
}
|
|
@ -17,10 +17,16 @@
|
||||||
|
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
|
|
||||||
|
const QString ICE_SERVER_HOSTNAME = "localhost";
|
||||||
|
const int ICE_SERVER_DEFAULT_PORT = 7337;
|
||||||
|
|
||||||
class NetworkPeer : public QObject {
|
class NetworkPeer : public QObject {
|
||||||
public:
|
public:
|
||||||
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
|
|
||||||
|
const QUuid& getUUID() const { return _uuid; }
|
||||||
|
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||||
|
|
||||||
const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
|
const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
|
||||||
void setPublicSocket(const HifiSockAddr& publicSocket);
|
void setPublicSocket(const HifiSockAddr& publicSocket);
|
||||||
const HifiSockAddr& getLocalSocket() const { return _localSocket; }
|
const HifiSockAddr& getLocalSocket() const { return _localSocket; }
|
||||||
|
@ -43,4 +49,7 @@ protected:
|
||||||
HifiSockAddr* _activeSocket;
|
HifiSockAddr* _activeSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const NetworkPeer &peer);
|
||||||
|
typedef QSharedPointer<NetworkPeer> SharedNetworkPeer;
|
||||||
|
|
||||||
#endif // hifi_NetworkPeer_h
|
#endif // hifi_NetworkPeer_h
|
|
@ -57,9 +57,6 @@ public:
|
||||||
char getType() const { return _type; }
|
char getType() const { return _type; }
|
||||||
void setType(char type) { _type = type; }
|
void setType(char type) { _type = type; }
|
||||||
|
|
||||||
const QUuid& getUUID() const { return _uuid; }
|
|
||||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
|
||||||
|
|
||||||
quint64 getWakeTimestamp() const { return _wakeTimestamp; }
|
quint64 getWakeTimestamp() const { return _wakeTimestamp; }
|
||||||
void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; }
|
void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; }
|
||||||
|
|
||||||
|
|
|
@ -243,61 +243,78 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
// send a STUN request to figure it out
|
// send a STUN request to figure it out
|
||||||
sendSTUNRequest();
|
sendSTUNRequest();
|
||||||
} else if (!_domainHandler.getIP().isNull()) {
|
} else if (!_domainHandler.getIP().isNull()) {
|
||||||
|
|
||||||
bool isUsingDTLS = false;
|
|
||||||
|
|
||||||
PacketType domainPacketType = !_domainHandler.isConnected()
|
if (!_domainHandler.isConnected() && _domainHandler.requiresICE()) {
|
||||||
|
sendICERequestForDomainConnection();
|
||||||
|
} else {
|
||||||
|
bool isUsingDTLS = false;
|
||||||
|
|
||||||
|
PacketType domainPacketType = !_domainHandler.isConnected()
|
||||||
? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest;
|
? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest;
|
||||||
|
|
||||||
if (!_domainHandler.isConnected()) {
|
if (!_domainHandler.isConnected()) {
|
||||||
qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
|
qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct the DS check in packet
|
||||||
|
QUuid packetUUID = _sessionUUID;
|
||||||
|
|
||||||
|
if (!_domainHandler.getAssignmentUUID().isNull() && domainPacketType == PacketTypeDomainConnectRequest) {
|
||||||
|
// this is a connect request and we're an assigned node
|
||||||
|
// so set our packetUUID as the assignment UUID
|
||||||
|
packetUUID = _domainHandler.getAssignmentUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID);
|
||||||
|
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
||||||
|
|
||||||
|
// pack our data to send to the domain-server
|
||||||
|
packetStream << _ownerType << _publicSockAddr
|
||||||
|
<< HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort())
|
||||||
|
<< (quint8) _nodeTypesOfInterest.size();
|
||||||
|
|
||||||
|
// copy over the bytes for node types of interest, if required
|
||||||
|
foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) {
|
||||||
|
packetStream << nodeTypeOfInterest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isUsingDTLS) {
|
||||||
|
writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
|
||||||
|
static unsigned int numDomainCheckins = 0;
|
||||||
|
|
||||||
|
// send a STUN request every Nth domain server check in so we update our public socket, if required
|
||||||
|
if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) {
|
||||||
|
sendSTUNRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
|
||||||
|
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
|
||||||
|
// so emit our signal that indicates that
|
||||||
|
emit limitOfSilentDomainCheckInsReached();
|
||||||
|
}
|
||||||
|
|
||||||
|
// increment the count of un-replied check-ins
|
||||||
|
_numNoReplyDomainCheckIns++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the DS check in packet
|
|
||||||
QUuid packetUUID = _sessionUUID;
|
|
||||||
|
|
||||||
if (!_domainHandler.getAssignmentUUID().isNull() && domainPacketType == PacketTypeDomainConnectRequest) {
|
|
||||||
// this is a connect request and we're an assigned node
|
|
||||||
// so set our packetUUID as the assignment UUID
|
|
||||||
packetUUID = _domainHandler.getAssignmentUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID);
|
|
||||||
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
|
||||||
|
|
||||||
// pack our data to send to the domain-server
|
|
||||||
packetStream << _ownerType << _publicSockAddr
|
|
||||||
<< HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort())
|
|
||||||
<< (quint8) _nodeTypesOfInterest.size();
|
|
||||||
|
|
||||||
// copy over the bytes for node types of interest, if required
|
|
||||||
foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) {
|
|
||||||
packetStream << nodeTypeOfInterest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isUsingDTLS) {
|
|
||||||
writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid());
|
|
||||||
}
|
|
||||||
|
|
||||||
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
|
|
||||||
static unsigned int numDomainCheckins = 0;
|
|
||||||
|
|
||||||
// send a STUN request every Nth domain server check in so we update our public socket, if required
|
|
||||||
if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) {
|
|
||||||
sendSTUNRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
|
|
||||||
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
|
|
||||||
// so emit our signal that indicates that
|
|
||||||
emit limitOfSilentDomainCheckInsReached();
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment the count of un-replied check-ins
|
|
||||||
_numNoReplyDomainCheckIns++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeList::sendICERequestForDomainConnection() {
|
||||||
|
QByteArray iceRequestByteArray = byteArrayWithPopulatedHeader(PacketTypeIceServerHeartbeat);
|
||||||
|
QDataStream iceDataStream(&iceRequestByteArray, QIODevice::Append);
|
||||||
|
|
||||||
|
iceDataStream << _publicSockAddr << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort());
|
||||||
|
iceDataStream << _domainHandler.getUUID();
|
||||||
|
|
||||||
|
qDebug() << "Sending packet to ICE server to request connection info for peer with ID"
|
||||||
|
<< uuidStringWithoutCurlyBraces(_domainHandler.getUUID());
|
||||||
|
|
||||||
|
_nodeSocket.writeDatagram(iceRequestByteArray, QHostAddress::LocalHost, ICE_SERVER_DEFAULT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
int NodeList::processDomainServerList(const QByteArray& packet) {
|
int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
// this is a packet from the domain server, reset the count of un-replied check-ins
|
// this is a packet from the domain server, reset the count of un-replied check-ins
|
||||||
_numNoReplyDomainCheckIns = 0;
|
_numNoReplyDomainCheckIns = 0;
|
||||||
|
|
|
@ -91,6 +91,8 @@ private:
|
||||||
void sendSTUNRequest();
|
void sendSTUNRequest();
|
||||||
bool processSTUNResponse(const QByteArray& packet);
|
bool processSTUNResponse(const QByteArray& packet);
|
||||||
|
|
||||||
|
void sendICERequestForDomainConnection();
|
||||||
|
|
||||||
void processDomainServerAuthRequest(const QByteArray& packet);
|
void processDomainServerAuthRequest(const QByteArray& packet);
|
||||||
void requestAuthForDomainServer();
|
void requestAuthForDomainServer();
|
||||||
void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode);
|
void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode);
|
||||||
|
|
|
@ -70,7 +70,8 @@ enum PacketType {
|
||||||
PacketTypeVoxelEditNack,
|
PacketTypeVoxelEditNack,
|
||||||
PacketTypeParticleEditNack,
|
PacketTypeParticleEditNack,
|
||||||
PacketTypeEntityEditNack, // 48
|
PacketTypeEntityEditNack, // 48
|
||||||
PacketTypeSignedTransactionPayment
|
PacketTypeSignedTransactionPayment,
|
||||||
|
PacketTypeIceServerHeartbeat
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef char PacketVersion;
|
typedef char PacketVersion;
|
||||||
|
|
Loading…
Reference in a new issue