void IceServer::processDatagrams() { HifiSockAddr sendingSockAddr; while (_serverSocket.hasPendingDatagrams()) { // setup a buffer to read the packet into int packetSizeWithHeader = _serverSocket.pendingDatagramSize(); auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]); _serverSocket.readDatagram(buffer.get(), packetSizeWithHeader, sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer()); // make sure that this packet at least looks like something we can read if (packetSizeWithHeader >= Packet::localHeaderSize(PacketType::ICEServerHeartbeat)) { auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, sendingSockAddr); PacketType::Value packetType = packet->getType(); if (packetType == PacketType::ICEServerHeartbeat) { SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*packet); // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now peer->activateMatchingOrNewSymmetricSocket(sendingSockAddr); } else if (packetType == PacketType::ICEServerQuery) { QDataStream heartbeatStream(packet.get()); // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer? QUuid senderUUID; heartbeatStream >> senderUUID; // pull the public and private sock addrs for this peer HifiSockAddr publicSocket, localSocket; heartbeatStream >> publicSocket >> localSocket; // check if this node also included a UUID that they would like to connect to QUuid connectRequestID; heartbeatStream >> connectRequestID; SharedNetworkPeer matchingPeer = _activePeers.value(connectRequestID); if (matchingPeer) { qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID; // we have the peer they want to connect to - send them pack the information for that peer sendPeerInformationPacket(*(matchingPeer.data()), &sendingSockAddr); // we also need to send them to the active peer they are hoping to connect to // create a dummy peer object we can pass to sendPeerInformationPacket NetworkPeer dummyPeer(senderUUID, publicSocket, localSocket); sendPeerInformationPacket(dummyPeer, matchingPeer->getActiveSocket()); } else { qDebug() << "Peer" << senderUUID << "asked for" << connectRequestID << "but no matching peer found"; } } }
void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) { auto nlPacket = NLPacket::fromBase(std::move(packet)); // make sure that this packet at least looks like something we can read if (nlPacket->getPayloadSize() >= NLPacket::localHeaderSize(PacketType::ICEServerHeartbeat)) { if (nlPacket->getType() == PacketType::ICEServerHeartbeat) { SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*nlPacket); if (peer) { // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now peer->activateMatchingOrNewSymmetricSocket(nlPacket->getSenderSockAddr()); // we have an active and verified heartbeating peer // send them an ACK packet so they know that they are being heard and ready for ICE static auto ackPacket = NLPacket::create(PacketType::ICEServerHeartbeatACK); _serverSocket.writePacket(*ackPacket, nlPacket->getSenderSockAddr()); } else { // we couldn't verify this peer - respond back to them so they know they may need to perform keypair re-generation static auto deniedPacket = NLPacket::create(PacketType::ICEServerHeartbeatDenied); _serverSocket.writePacket(*deniedPacket, nlPacket->getSenderSockAddr()); } } else if (nlPacket->getType() == PacketType::ICEServerQuery) { QDataStream heartbeatStream(nlPacket.get()); // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer? QUuid senderUUID; heartbeatStream >> senderUUID; // pull the public and private sock addrs for this peer HifiSockAddr publicSocket, localSocket; heartbeatStream >> publicSocket >> localSocket; // check if this node also included a UUID that they would like to connect to QUuid connectRequestID; heartbeatStream >> connectRequestID; SharedNetworkPeer matchingPeer = _activePeers.value(connectRequestID); if (matchingPeer) { qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID; // we have the peer they want to connect to - send them pack the information for that peer sendPeerInformationPacket(*matchingPeer, &nlPacket->getSenderSockAddr()); // we also need to send them to the active peer they are hoping to connect to // create a dummy peer object we can pass to sendPeerInformationPacket NetworkPeer dummyPeer(senderUUID, publicSocket, localSocket); sendPeerInformationPacket(dummyPeer, matchingPeer->getActiveSocket()); } else { qDebug() << "Peer" << senderUUID << "asked for" << connectRequestID << "but no matching peer found"; } } }