allow a packet to be created with extended header

This commit is contained in:
Stephen Birarda 2015-07-06 16:18:49 -07:00
parent 3ae8ba2922
commit 33a9a04d9e
3 changed files with 53 additions and 34 deletions

View file

@ -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) {

View file

@ -18,10 +18,21 @@ PacketList::PacketList(PacketType::Value packetType, bool 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
_currentPacket = T::create(_packetType);
createPacketWithExtendedHeader();
}
// check if this block of data can fit into the currentPacket
@ -36,13 +47,13 @@ qint64 writeData(const char* data, qint64 maxSize) {
if (!_isOrdered) {
auto newPacket = T::create(_packetType);
PacketPayload& newPayload = newPacket.payload();
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->payload();
PacketPayload& currentPayload = _currentPacket->getPayload();
// check now to see if this is an unsupported write
int numBytesToEnd = currentPayload.size() - _segmentStartIndex;
@ -82,7 +93,7 @@ qint64 writeData(const char* data, qint64 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.payload();
PacketPayload& currentPayload = _currentPacket.getPayload();
int numBytesToEnd = _currentPayload.size() - _currentPayload.pos();
_currentPacket.write(data, numBytesToEnd);
@ -96,3 +107,11 @@ qint64 writeData(const char* data, qint64 maxSize) {
}
}
void PacketList::closeCurrentPacket() {
// shrink the current payload to the actual size of the packet
_currentPacket.getPayload().trim();
// move the current packet to our list of packets
_packets.insert(std::move(_currentPacket));
}

View file

@ -22,10 +22,16 @@ public:
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;
@ -33,6 +39,8 @@ private:
std::list<std::unique_ptr<T>> _packets;
int _segmentStartIndex = -1;
QByteArray _extendedHeader = extendedHeader;
}
#endif // hifi_PacketList_h