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) { const NodeSet& nodeInterestSet) {
auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
auto listPacket = NodeListPacket::make(PacketType::DomainList); PacketList domainListPackets(PacketType::DomainList);
// always send the node their own UUID back // always send the node their own UUID back
QDataStream broadcastDataStream(&listPacket.payload(), QIODevice::Append); QDataStream domainListStream(&domainListPackets);
broadcastDataStream << node->getUUID();
broadcastDataStream << node->getCanAdjustLocks();
broadcastDataStream << node->getCanRez();
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()); DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
@ -945,43 +952,28 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
if (nodeInterestSet.size() > 0) { if (nodeInterestSet.size() > 0) {
// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; // DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL;
int dataMTU = MAX_PACKET_SIZE;
if (nodeData->isAuthenticated()) { if (nodeData->isAuthenticated()) {
// if this authenticated node has any interest types, send back those nodes as well // if this authenticated node has any interest types, send back those nodes as well
limitedNodeList->eachNode([&](const SharedNodePointer& otherNode){ 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())) { 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 // 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 // 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've added the node we wanted so end the segment now
// we need to break here and start a new packet domainListStream.endSegment();
// 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);
} }
}); });
} }
} }
// always write the last broadcastPacket // write the PacketList to this node
limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node); limitedNodeList->sendPacketList(domainListPackets, node);
} }
QUuid DomainServer::connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { 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) { qint64 writeData(const char* data, qint64 maxSize) {
if (!_currentPacket) { if (!_currentPacket) {
// we don't have a current packet, time to set one up // 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 // check if this block of data can fit into the currentPacket
@ -36,13 +47,13 @@ qint64 writeData(const char* data, qint64 maxSize) {
if (!_isOrdered) { if (!_isOrdered) {
auto newPacket = T::create(_packetType); auto newPacket = T::create(_packetType);
PacketPayload& newPayload = newPacket.payload(); PacketPayload& newPayload = newPacket.getPayload();
if (_segmentStartIndex >= 0) { if (_segmentStartIndex >= 0) {
// We in the process of writing a segment for an unordered PacketList. // 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 // 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 // check now to see if this is an unsupported write
int numBytesToEnd = currentPayload.size() - _segmentStartIndex; int numBytesToEnd = currentPayload.size() - _segmentStartIndex;
@ -82,7 +93,7 @@ qint64 writeData(const char* data, qint64 maxSize) {
} else { } else {
// we're an ordered PacketList - let's fit what we can into the current packet and then put the leftover // we're an ordered PacketList - let's fit what we can into the current packet and then put the leftover
// into a new packet // into a new packet
PacketPayload& currentPayload = _currentPacket.payload(); PacketPayload& currentPayload = _currentPacket.getPayload();
int numBytesToEnd = _currentPayload.size() - _currentPayload.pos(); int numBytesToEnd = _currentPayload.size() - _currentPayload.pos();
_currentPacket.write(data, numBytesToEnd); _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 startSegment() { _segmentStartIndex = currentPacket->payload().pos(); }
void endSegment() { _segmentStartIndex = -1; } void endSegment() { _segmentStartIndex = -1; }
void closeCurrentPacket();
void setExtendedHeader(const QByteArray& extendedHeader) { _extendedHeader = extendedHeader; }
protected: protected:
qint64 writeData(const char* data, qint64 maxSize); qint64 writeData(const char* data, qint64 maxSize);
qint64 readData(const char* data, qint64 maxSize) { return 0 }; qint64 readData(const char* data, qint64 maxSize) { return 0 };
private: private:
void createPacketWithExtendedHeader();
PacketType::Value _packetType; PacketType::Value _packetType;
bool isOrdered; bool isOrdered;
@ -33,6 +39,8 @@ private:
std::list<std::unique_ptr<T>> _packets; std::list<std::unique_ptr<T>> _packets;
int _segmentStartIndex = -1; int _segmentStartIndex = -1;
QByteArray _extendedHeader = extendedHeader;
} }
#endif // hifi_PacketList_h #endif // hifi_PacketList_h