mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01: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
|
||||
//
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
|
||||
#include "IceServer.h"
|
||||
|
||||
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
|
||||
#define hifi_IceServer_h
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qsharedpointer.h>
|
||||
#include <qudpsocket.h>
|
||||
|
||||
#include <NetworkPeer.h>
|
||||
|
||||
class IceServer : public QCoreApplication {
|
||||
public:
|
||||
IceServer(int argc, char* argv[]);
|
||||
private slots:
|
||||
void processDatagrams();
|
||||
private:
|
||||
QHash<QUuid, SharedNetworkPeer> _activePeers;
|
||||
QUdpSocket _serverSocket;
|
||||
};
|
||||
|
||||
#endif // hifi_IceServer_h
|
|
@ -25,6 +25,7 @@ DomainHandler::DomainHandler(QObject* parent) :
|
|||
_uuid(),
|
||||
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||
_assignmentUUID(),
|
||||
_requiresICE(true),
|
||||
_isConnected(false),
|
||||
_handshakeTimer(NULL),
|
||||
_settingsObject(),
|
||||
|
@ -35,6 +36,7 @@ DomainHandler::DomainHandler(QObject* parent) :
|
|||
|
||||
void DomainHandler::clearConnectionInfo() {
|
||||
_uuid = QUuid();
|
||||
_requiresICE = true;
|
||||
_isConnected = false;
|
||||
emit disconnectedFromDomain();
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
||||
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
||||
|
||||
bool requiresICE() const { return _requiresICE; }
|
||||
|
||||
bool isConnected() const { return _isConnected; }
|
||||
void setIsConnected(bool isConnected);
|
||||
|
||||
|
@ -85,6 +87,7 @@ private:
|
|||
QString _hostname;
|
||||
HifiSockAddr _sockAddr;
|
||||
QUuid _assignmentUUID;
|
||||
bool _requiresICE;
|
||||
bool _isConnected;
|
||||
QTimer* _handshakeTimer;
|
||||
QJsonObject _settingsObject;
|
||||
|
|
|
@ -63,4 +63,11 @@ void NetworkPeer::activatePublicSocket() {
|
|||
void NetworkPeer::activateSymmetricSocket() {
|
||||
qDebug() << "Activating symmetric socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
||||
_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"
|
||||
|
||||
const QString ICE_SERVER_HOSTNAME = "localhost";
|
||||
const int ICE_SERVER_DEFAULT_PORT = 7337;
|
||||
|
||||
class NetworkPeer : public QObject {
|
||||
public:
|
||||
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; }
|
||||
void setPublicSocket(const HifiSockAddr& publicSocket);
|
||||
const HifiSockAddr& getLocalSocket() const { return _localSocket; }
|
||||
|
@ -43,4 +49,7 @@ protected:
|
|||
HifiSockAddr* _activeSocket;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const NetworkPeer &peer);
|
||||
typedef QSharedPointer<NetworkPeer> SharedNetworkPeer;
|
||||
|
||||
#endif // hifi_NetworkPeer_h
|
|
@ -57,9 +57,6 @@ public:
|
|||
char getType() const { return _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; }
|
||||
void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; }
|
||||
|
||||
|
|
|
@ -243,61 +243,78 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
// send a STUN request to figure it out
|
||||
sendSTUNRequest();
|
||||
} 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;
|
||||
|
||||
if (!_domainHandler.isConnected()) {
|
||||
qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
|
||||
|
||||
if (!_domainHandler.isConnected()) {
|
||||
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) {
|
||||
// this is a packet from the domain server, reset the count of un-replied check-ins
|
||||
_numNoReplyDomainCheckIns = 0;
|
||||
|
|
|
@ -91,6 +91,8 @@ private:
|
|||
void sendSTUNRequest();
|
||||
bool processSTUNResponse(const QByteArray& packet);
|
||||
|
||||
void sendICERequestForDomainConnection();
|
||||
|
||||
void processDomainServerAuthRequest(const QByteArray& packet);
|
||||
void requestAuthForDomainServer();
|
||||
void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode);
|
||||
|
|
|
@ -70,7 +70,8 @@ enum PacketType {
|
|||
PacketTypeVoxelEditNack,
|
||||
PacketTypeParticleEditNack,
|
||||
PacketTypeEntityEditNack, // 48
|
||||
PacketTypeSignedTransactionPayment
|
||||
PacketTypeSignedTransactionPayment,
|
||||
PacketTypeIceServerHeartbeat
|
||||
};
|
||||
|
||||
typedef char PacketVersion;
|
||||
|
|
Loading…
Reference in a new issue