add a method to DS to respond to path query

This commit is contained in:
Stephen Birarda 2015-05-12 12:29:09 -07:00
parent d8b17ffeb0
commit e0ccc986b1
3 changed files with 98 additions and 29 deletions

View file

@ -1398,6 +1398,11 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
break;
}
case PacketTypeDomainServerPathQuery: {
// have our private method attempt to respond to this path query
respondToPathQuery(receivedPacket, senderSockAddr);
break;
}
case PacketTypeNodeJsonStats: {
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
if (matchingNode) {
@ -2190,3 +2195,64 @@ void DomainServer::addStaticAssignmentsToQueue() {
++staticAssignment;
}
}
void DomainServer::respondToPathQuery(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) {
// this is a query for the viewpoint resulting from a path
// first pull the query path from the packet
int numHeaderBytes = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerPathQuery);
const char* packetDataStart = receivedPacket.data() + numHeaderBytes;
// figure out how many bytes the sender said this path is
quint8 numPathBytes = *packetDataStart;
if (numPathBytes <= receivedPacket.size() - numHeaderBytes - 1) {
// the number of path bytes makes sense for the sent packet - pull out the path
QString pathQuery = QString::fromUtf8(packetDataStart + 1, numPathBytes);
// our settings contain paths that start with a leading slash, so make sure this query has that
if (!pathQuery.startsWith("/")) {
pathQuery.prepend("/");
}
const QString PATHS_SETTINGS_KEYPATH_FORMAT = "paths.%2";
const QString PATH_VIEWPOINT_KEY = "viewpoint";
// check out paths in the _configMap to see if we have a match
const QVariant* pathMatch = valueForKeyPath(_settingsManager.getSettingsMap(),
QString(PATHS_SETTINGS_KEYPATH_FORMAT).arg(pathQuery));
if (pathMatch) {
// we got a match, respond with the resulting viewpoint
auto nodeList = DependencyManager::get<LimitedNodeList>();
QString responseViewpoint = pathMatch->toMap()[PATH_VIEWPOINT_KEY].toString();
if (!responseViewpoint.isEmpty()) {
QByteArray viewpointUTF8 = responseViewpoint.toUtf8();
// prepare a packet for the response
QByteArray pathResponsePacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeDomainServerPathResponse);
// first append the number of bytes the viewpoint is, for unpacking on the other side
quint8 numViewpointBytes = responseViewpoint.toUtf8().size();
// are we going to be able to fit this viewpoint in a packet?
if (numViewpointBytes + pathResponsePacket.size() + sizeof(numViewpointBytes) < MAX_PACKET_SIZE) {
pathResponsePacket.append(reinterpret_cast<char*>(&numViewpointBytes), sizeof(numViewpointBytes));
// append the viewpoint itself
pathResponsePacket.append(viewpointUTF8);
// send off the packet - see if we can associate this outbound data to a particular node
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
nodeList->writeUnverifiedDatagram(pathResponsePacket, matchingNode, senderSockAddr);
}
}
} else {
// we don't respond if there is no match - this may need to change once this packet
// query/response is made reliable
qDebug() << "No match for path query" << pathQuery << "- refusing to respond.";
}
}
}

View file

@ -39,29 +39,29 @@ class DomainServer : public QCoreApplication, public HTTPSRequestHandler {
Q_OBJECT
public:
DomainServer(int argc, char* argv[]);
static int const EXIT_CODE_REBOOT;
bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler = false);
bool handleHTTPSRequest(HTTPSConnection* connection, const QUrl& url, bool skipSubHandler = false);
public slots:
/// Called by NodeList to inform us a node has been added
void nodeAdded(SharedNodePointer node);
/// Called by NodeList to inform us a node has been killed
void nodeKilled(SharedNodePointer node);
void publicKeyJSONCallback(QNetworkReply& requestReply);
void transactionJSONCallback(const QJsonObject& data);
void restart();
private slots:
void loginFailed();
void readAvailableDatagrams();
void setupPendingAssignmentCredits();
void sendPendingTransactionsToServer();
void requestCurrentPublicSocketViaSTUN();
void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr);
void performICEUpdates();
@ -74,23 +74,23 @@ private:
bool optionallyReadX509KeyAndCertificate();
bool didSetupAccountManagerWithAccessToken();
bool optionallySetupAssignmentPayment();
void setupAutomaticNetworking();
void sendHeartbeatToDataServer(const QString& networkAddress);
void processICEPingReply(const QByteArray& packet, const HifiSockAddr& senderSockAddr);
void processICEHeartbeatResponse(const QByteArray& packet);
void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
void handleConnectRequest(const QByteArray& packet, const HifiSockAddr& senderSockAddr);
unsigned int countConnectedUsers();
bool verifyUsersKey (const QString& username, const QByteArray& usernameSignature, QString& reasonReturn);
bool shouldAllowConnectionFromNode(const QString& username, const QByteArray& usernameSignature,
const HifiSockAddr& senderSockAddr, QString& reasonReturn);
void preloadAllowedUserPublicKeys();
void requestUserPublicKey(const QString& username);
int parseNodeDataFromByteArray(QDataStream& packetStream,
NodeType_t& nodeType,
HifiSockAddr& publicSockAddr,
@ -99,61 +99,63 @@ private:
NodeSet nodeInterestListFromPacket(const QByteArray& packet, int numPreceedingBytes);
void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr,
const NodeSet& nodeInterestList);
void parseAssignmentConfigs(QSet<Assignment::Type>& excludedTypes);
void addStaticAssignmentToAssignmentHash(Assignment* newAssignment);
void createStaticAssignmentsForType(Assignment::Type type, const QVariantList& configList);
void populateDefaultStaticAssignmentsExcludingTypes(const QSet<Assignment::Type>& excludedTypes);
void populateStaticScriptedAssignmentsFromSettings();
SharedAssignmentPointer matchingQueuedAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType);
SharedAssignmentPointer deployableAssignmentForRequest(const Assignment& requestAssignment);
void removeMatchingAssignmentFromQueue(const SharedAssignmentPointer& removableAssignment);
void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment);
void addStaticAssignmentsToQueue();
void respondToPathQuery(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
QUrl oauthRedirectURL();
QUrl oauthAuthorizationURL(const QUuid& stateUUID = QUuid::createUuid());
bool isAuthenticatedRequest(HTTPConnection* connection, const QUrl& url);
void handleTokenRequestFinished();
QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply);
void handleProfileRequestFinished();
Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply);
void loadExistingSessionsFromSettings();
QJsonObject jsonForSocket(const HifiSockAddr& socket);
QJsonObject jsonObjectForNode(const SharedNodePointer& node);
HTTPManager _httpManager;
HTTPSManager* _httpsManager;
QHash<QUuid, SharedAssignmentPointer> _allAssignments;
QQueue<SharedAssignmentPointer> _unfulfilledAssignments;
QHash<QUuid, PendingAssignedNodeData*> _pendingAssignedNodes;
TransactionHash _pendingAssignmentCredits;
bool _isUsingDTLS;
QUrl _oauthProviderURL;
QString _oauthClientID;
QString _oauthClientSecret;
QString _hostname;
QSet<QUuid> _webAuthenticationStateSet;
QHash<QUuid, DomainServerWebSessionData> _cookieSessionHash;
QHash<QString, QByteArray> _userPublicKeys;
QHash<QUuid, NetworkPeer> _connectingICEPeers;
QHash<QUuid, HifiSockAddr> _connectedICEPeers;
QString _automaticNetworkingSetting;
DomainServerSettingsManager _settingsManager;
HifiSockAddr _iceServerSocket;
};

View file

@ -96,7 +96,8 @@ const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
<< PacketTypeNodeJsonStats << PacketTypeEntityQuery
<< PacketTypeOctreeDataNack << PacketTypeEntityEditNack
<< PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode;
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode
<< PacketTypeDomainServerPathQuery << PacketTypeDomainServerPathResponse;
const QSet<PacketType> SEQUENCE_NUMBERED_PACKETS = QSet<PacketType>()
<< PacketTypeAvatarData;