From 956c212db2fbfe6fce454534806533cb8b787856 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Oct 2014 15:24:23 -0700 Subject: [PATCH] manage sets of potential connections in ice server --- ice-server/src/IceServer.cpp | 67 ++++++++++++++++++++---- ice-server/src/IceServer.h | 6 ++- libraries/networking/src/NetworkPeer.cpp | 9 ++++ libraries/networking/src/NetworkPeer.h | 2 + 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index be97df37a4..e3db679009 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -11,6 +11,7 @@ #include +#include #include #include @@ -22,7 +23,8 @@ const int PEER_SILENCE_THRESHOLD_MSECS = 5 * 1000; IceServer::IceServer(int argc, char* argv[]) : QCoreApplication(argc, argv), _id(QUuid::createUuid()), - _serverSocket() + _serverSocket(), + _activePeers() { // start the ice-server socket qDebug() << "ice-server socket is listening on" << ICE_SERVER_DEFAULT_PORT; @@ -84,24 +86,67 @@ void IceServer::processDatagrams() { QUuid connectRequestID; hearbeatStream >> connectRequestID; + // get the peers asking for connections with this peer + QSet& requestingConnections = _currentConnections[senderUUID]; + if (!connectRequestID.isNull()) { qDebug() << "Peer wants to connect to peer with ID" << uuidStringWithoutCurlyBraces(connectRequestID); - // check if we have that ID - if we do we can respond with their info, otherwise nothing we can do - SharedNetworkPeer matchingConectee = _activePeers.value(connectRequestID); - if (matchingConectee) { - QByteArray heartbeatResponse = byteArrayWithPopulatedHeader(PacketTypeIceServerHeartbeatResponse, _id); - QDataStream responseStream(&heartbeatResponse, QIODevice::Append); - - responseStream << matchingConectee; - - _serverSocket.writeDatagram(heartbeatResponse, sendingSockAddr.getAddress(), sendingSockAddr.getPort()); - } + // ensure this peer is in the set of current connections for the peer with ID it wants to connect with + _currentConnections[connectRequestID].insert(senderUUID); + + // add the ID of the node they have said they would like to connect to + requestingConnections.insert(connectRequestID); + } + + if (requestingConnections.size() > 0) { + // send a heartbeart response based on the set of connections + qDebug() << "Sending a heartbeat response to" << senderUUID << "who has" << requestingConnections.size() + << "potential connections"; + sendHeartbeatResponse(sendingSockAddr, requestingConnections); } } } } +void IceServer::sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, QSet& connections) { + QSet::iterator peerID = connections.begin(); + + QByteArray outgoingPacket(MAX_PACKET_SIZE, 0); + int currentPacketSize = populatePacketHeader(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id); + + // go through the connections, sending packets containing connection information for those nodes + while (peerID != connections.end()) { + SharedNetworkPeer matchingPeer = _activePeers.value(*peerID); + // if this node is inactive we remove it from the set + if (!matchingPeer) { + peerID = connections.erase(peerID); + } else { + // get the byte array for this peer + QByteArray peerBytes = matchingPeer->toByteArray(); + + if (currentPacketSize + peerBytes.size() > MAX_PACKET_SIZE) { + // write the current packet + _serverSocket.writeDatagram(outgoingPacket.data(), currentPacketSize, + destinationSockAddr.getAddress(), destinationSockAddr.getPort()); + + // reset the packet size to our number of header bytes + currentPacketSize = populatePacketHeader(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id); + } + + // append the current peer bytes + outgoingPacket.insert(currentPacketSize, peerBytes); + currentPacketSize += peerBytes.size(); + + ++peerID; + } + } + + // write the last packet + _serverSocket.writeDatagram(outgoingPacket.data(), currentPacketSize, + destinationSockAddr.getAddress(), destinationSockAddr.getPort()); +} + void IceServer::clearInactivePeers() { NetworkPeerHash::iterator peerItem = _activePeers.begin(); diff --git a/ice-server/src/IceServer.h b/ice-server/src/IceServer.h index 9c4c4242dc..e15bda1211 100644 --- a/ice-server/src/IceServer.h +++ b/ice-server/src/IceServer.h @@ -27,9 +27,13 @@ private slots: void processDatagrams(); void clearInactivePeers(); private: + + void sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, QSet& connections); + QUuid _id; - NetworkPeerHash _activePeers; QUdpSocket _serverSocket; + NetworkPeerHash _activePeers; + QHash > _currentConnections; }; #endif // hifi_IceServer_h \ No newline at end of file diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index 1da6836bf9..79bed4f226 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -70,6 +70,15 @@ void NetworkPeer::activateSymmetricSocket() { _activeSocket = &_symmetricSocket; } +QByteArray NetworkPeer::toByteArray() const { + QByteArray peerByteArray; + + QDataStream peerStream(&peerByteArray, QIODevice::Append); + peerStream << *this; + + return peerByteArray; +} + QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer) { out << peer._uuid; out << peer._publicSocket; diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index dd32666b62..18015bc605 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -47,6 +47,8 @@ public: quint64 getLastHeardMicrostamp() const { return _lastHeardMicrostamp; } void setLastHeardMicrostamp(quint64 lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; } + QByteArray toByteArray() const; + friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer); friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer); protected: