mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 14:39:45 +02:00
Merge branch 'atp' of https://github.com/birarda/hifi into protocol
This commit is contained in:
commit
0c7dc1e28f
5 changed files with 193 additions and 40 deletions
|
@ -927,15 +927,22 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
const NodeSet& nodeInterestSet) {
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
auto listPacket = NodeListPacket::make(PacketType::DomainList);
|
||||
PacketList domainListPackets(PacketType::DomainList);
|
||||
|
||||
// always send the node their own UUID back
|
||||
QDataStream broadcastDataStream(&listPacket.payload(), QIODevice::Append);
|
||||
broadcastDataStream << node->getUUID();
|
||||
broadcastDataStream << node->getCanAdjustLocks();
|
||||
broadcastDataStream << node->getCanRez();
|
||||
QDataStream domainListStream(&domainListPackets);
|
||||
|
||||
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();
|
||||
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + 2;
|
||||
|
||||
// setup the extended header for the domain list packets
|
||||
// this data is at the beginning of each of the domain list packets
|
||||
QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0);
|
||||
extendedHeader.replace(0, NUM_BYTES_RFC4122_UUID, node->getUUID().toRfc4122());
|
||||
|
||||
extendedHeader[NUM_BYTES_RFC4122_UUID] = (char) node->getCanAdjustLocks();
|
||||
extendedHeader[NUM_BYTES_RFC4122_UUID + 1] = (char) node->getCanRez();
|
||||
|
||||
domainListPackets.setExtendedHeader(extendedHeader);
|
||||
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
||||
|
@ -944,44 +951,29 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
|
||||
if (nodeInterestSet.size() > 0) {
|
||||
|
||||
// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL;
|
||||
int dataMTU = MAX_PACKET_SIZE;
|
||||
|
||||
// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL;
|
||||
if (nodeData->isAuthenticated()) {
|
||||
// if this authenticated node has any interest types, send back those nodes as well
|
||||
limitedNodeList->eachNode([&](const SharedNodePointer& otherNode){
|
||||
// reset our nodeByteArray and nodeDataStream
|
||||
QByteArray nodeByteArray;
|
||||
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
||||
|
||||
if (otherNode->getUUID() != node->getUUID() && nodeInterestSet.contains(otherNode->getType())) {
|
||||
// since we're about to add a node to the packet we start a segment
|
||||
domainListStream.startSegment();
|
||||
|
||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||
nodeDataStream << *otherNode.data();
|
||||
domainListStream << *otherNode.data();
|
||||
|
||||
// pack the secret that these two nodes will use to communicate with each other
|
||||
nodeDataStream << connectionSecretForNodes(node, otherNode);
|
||||
domainListStream << connectionSecretForNodes(node, otherNode);
|
||||
|
||||
if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) {
|
||||
// we need to break here and start a new packet
|
||||
// so send the current one
|
||||
|
||||
limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node, senderSockAddr);
|
||||
|
||||
// reset the broadcastPacket structure
|
||||
broadcastPacket.resize(numBroadcastPacketLeadBytes);
|
||||
broadcastDataStream.device()->seek(numBroadcastPacketLeadBytes);
|
||||
}
|
||||
|
||||
// append the nodeByteArray to the current state of broadcastDataStream
|
||||
broadcastPacket.append(nodeByteArray);
|
||||
// we've added the node we wanted so end the segment now
|
||||
domainListStream.endSegment();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// always write the last broadcastPacket
|
||||
limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node);
|
||||
// write the PacketList to this node
|
||||
limitedNodeList->sendPacketList(domainListPackets, node);
|
||||
}
|
||||
|
||||
QUuid DomainServer::connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) {
|
||||
|
|
111
libraries/networking/src/PacketList.cpp
Normal file
111
libraries/networking/src/PacketList.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// PacketList.cpp
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 07/06/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "PacketList.h"
|
||||
|
||||
PacketList::PacketList(PacketType::Value packetType, bool isOrdered) :
|
||||
_packetType(packetType),
|
||||
_isOrdered(isOrdered)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PacketList::createPacketWithExtendedHeader() {
|
||||
// use the static create method to create a new packet
|
||||
_currentPacket = T::create(_packetType);
|
||||
|
||||
// add the extended header to the front of the packet
|
||||
if (_currentPacket.write(_extendedHeader) == -1) {
|
||||
qDebug() << "Could not write extendedHeader in PacketList::createPacketWithExtendedHeader"
|
||||
<< "- make sure that _extendedHeader is not larger than the payload capacity.";
|
||||
}
|
||||
}
|
||||
|
||||
qint64 writeData(const char* data, qint64 maxSize) {
|
||||
if (!_currentPacket) {
|
||||
// we don't have a current packet, time to set one up
|
||||
createPacketWithExtendedHeader();
|
||||
}
|
||||
|
||||
// check if this block of data can fit into the currentPacket
|
||||
if (maxSize <= _currentPacket.size()) {
|
||||
// it fits, just write it to the current packet
|
||||
_currentPacket.write(data, maxSize);
|
||||
|
||||
// return the number of bytes written
|
||||
return maxSize;
|
||||
} else {
|
||||
// it does not fit - this may need to be in the next packet
|
||||
|
||||
if (!_isOrdered) {
|
||||
auto newPacket = T::create(_packetType);
|
||||
PacketPayload& newPayload = newPacket.getPayload();
|
||||
|
||||
if (_segmentStartIndex >= 0) {
|
||||
// We in the process of writing a segment for an unordered PacketList.
|
||||
// We need to try and pull the first part of the segment out to our new packet
|
||||
|
||||
PacketPayload& currentPayload = _currentPacket->getPayload();
|
||||
|
||||
// check now to see if this is an unsupported write
|
||||
int numBytesToEnd = currentPayload.size() - _segmentStartIndex;
|
||||
|
||||
if ((newPayload.size() - numBytesToEnd) < maxSize) {
|
||||
// this is an unsupported case - the segment is bigger than the size of an individual packet
|
||||
// but the PacketList is not going to be sent ordered
|
||||
qDebug() << "Error in PacketList::writeData - attempted to write a segment to an unordered packet that is"
|
||||
<< "larger than the payload size.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy from currentPacket where the segment started to the beginning of the newPacket
|
||||
newPayload.write(currentPacket.constData() + _segmentStartIndex, numBytesToEnd);
|
||||
|
||||
// the current segment now starts at the beginning of the new packet
|
||||
_segmentStartIndex = 0;
|
||||
|
||||
// shrink the current payload to the actual size of the packet
|
||||
currentPayload.setSizeUsed(_segmentStartIndex);
|
||||
}
|
||||
|
||||
// move the current packet to our list of packets
|
||||
_packets.insert(std::move(_currentPacket));
|
||||
|
||||
// write the data to the newPacket
|
||||
newPayload.write(data, maxSize);
|
||||
|
||||
// set our current packet to the new packet
|
||||
_currentPacket = newPacket;
|
||||
|
||||
// return the number of bytes written to the new packet
|
||||
return maxSize;
|
||||
} else {
|
||||
// we're an ordered PacketList - let's fit what we can into the current packet and then put the leftover
|
||||
// into a new packet
|
||||
PacketPayload& currentPayload = _currentPacket.getPayload();
|
||||
|
||||
int numBytesToEnd = _currentPayload.size() - _currentPayload.pos();
|
||||
_currentPacket.write(data, numBytesToEnd);
|
||||
|
||||
// move the current packet to our list of packets
|
||||
_packets.insert(std::move(_currentPacket));
|
||||
|
||||
// recursively call our writeData method for the remaining data to write to a new packet
|
||||
return numBytesToEnd + writeData(data + numBytesToEnd, maxSize - numBytesToEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PacketList::closeCurrentPacket() {
|
||||
// move the current packet to our list of packets
|
||||
_packets.insert(std::move(_currentPacket));
|
||||
}
|
||||
|
46
libraries/networking/src/PacketList.h
Normal file
46
libraries/networking/src/PacketList.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// PacketList.h
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 07/06/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_PacketList_h
|
||||
#define hifi_PacketList_h
|
||||
|
||||
#pragma once
|
||||
|
||||
template <class T> class PacketList : public QIODevice {
|
||||
public:
|
||||
PacketList(PacketType::Value packetType, bool isOrdered = false);
|
||||
|
||||
virtual bool isSequential() const { return true; }
|
||||
|
||||
void startSegment() { _segmentStartIndex = currentPacket->payload().pos(); }
|
||||
void endSegment() { _segmentStartIndex = -1; }
|
||||
|
||||
void closeCurrentPacket();
|
||||
|
||||
void setExtendedHeader(const QByteArray& extendedHeader) { _extendedHeader = extendedHeader; }
|
||||
protected:
|
||||
qint64 writeData(const char* data, qint64 maxSize);
|
||||
qint64 readData(const char* data, qint64 maxSize) { return 0 };
|
||||
private:
|
||||
void createPacketWithExtendedHeader();
|
||||
|
||||
PacketType::Value _packetType;
|
||||
bool isOrdered;
|
||||
|
||||
std::unique_ptr<T> _currentPacket;
|
||||
std::list<std::unique_ptr<T>> _packets;
|
||||
|
||||
int _segmentStartIndex = -1;
|
||||
|
||||
QByteArray _extendedHeader = extendedHeader;
|
||||
}
|
||||
|
||||
#endif // hifi_PacketList_h
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
#include "PacketPayload.h"
|
||||
|
||||
PacketPayload::PacketPayload(char* data, qint64 size) :
|
||||
PacketPayload::PacketPayload(char* data, qint64 capacity) :
|
||||
_data(data)
|
||||
_size(size)
|
||||
_capacity(capacity)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ qint64 PacketPayload::writeData(const char* data, qint64 maxSize) {
|
|||
qint64 currentPos = pos();
|
||||
|
||||
// make sure we have the space required to write this block
|
||||
qint64 bytesAvailable = _size - currentPos;
|
||||
qint64 bytesAvailable = _capacity - currentPos;
|
||||
|
||||
if (bytesAvailable < srcBytes) {
|
||||
// good to go - write the data
|
||||
|
@ -35,7 +35,7 @@ qint64 PacketPayload::writeData(const char* data, qint64 maxSize) {
|
|||
seek(currentPos + srcBytes);
|
||||
|
||||
// keep track of _maxWritten so we can just write the actual data when packet is about to be sent
|
||||
_maxWritten = std::max(pos() + 1, _maxWritten);
|
||||
_size = std::max(pos() + 1, _maxWritten);
|
||||
|
||||
// return the number of bytes written
|
||||
return srcBytes;
|
||||
|
|
|
@ -18,19 +18,23 @@
|
|||
|
||||
class PacketPayload : public QIODevice {
|
||||
public:
|
||||
PacketPayload(char* data, qint64 size);
|
||||
PacketPayload(char* data, qint64 capacity);
|
||||
|
||||
virtual qint64 size() const { return _size; }
|
||||
qint64 getSizeUsed() const { return _sizeUsed; }
|
||||
void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; }
|
||||
|
||||
virtual qint64 size() const { return _capacity; }
|
||||
virtual bool isSequential() const { return false; }
|
||||
|
||||
const char* constData() const { return _data; }
|
||||
protected:
|
||||
virtual qint64 writeData(const char* data, qint64 maxSize);
|
||||
virtual qint64 readData(const char* data, qint64 maxSize);
|
||||
qint64 writeData(const char* data, qint64 maxSize);
|
||||
qint64 readData(char* data, qint64 maxSize);
|
||||
|
||||
private:
|
||||
char* _data;
|
||||
qint64 _size = 0;
|
||||
qint64 _maxWritten = 0;
|
||||
qint64 _sizeUsed = 0;
|
||||
qint64 _capacity = 0;
|
||||
};
|
||||
|
||||
#endif // hifi_PacketPayload_h
|
||||
|
|
Loading…
Reference in a new issue