void NodeList::processPingPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) { // send back a reply auto replyPacket = constructPingReplyPacket(*message); const HifiSockAddr& senderSockAddr = message->getSenderSockAddr(); sendPacket(std::move(replyPacket), *sendingNode, senderSockAddr); // If we don't have a symmetric socket for this node and this socket doesn't match // what we have for public and local then set it as the symmetric. // This allows a server on a reachable port to communicate with nodes on symmetric NATs if (sendingNode->getSymmetricSocket().isNull()) { if (senderSockAddr != sendingNode->getLocalSocket() && senderSockAddr != sendingNode->getPublicSocket()) { sendingNode->setSymmetricSocket(senderSockAddr); } } }
void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { switch (packetTypeForPacket(packet)) { case PacketTypeDomainList: { processDomainServerList(packet); break; } case PacketTypeDomainServerRequireDTLS: { _domainHandler.parseDTLSRequirementPacket(packet); break; } case PacketTypeIceServerHeartbeatResponse: { _domainHandler.processICEResponsePacket(packet); break; } case PacketTypePing: { // send back a reply SharedNodePointer matchingNode = sendingNodeForPacket(packet); if (matchingNode) { matchingNode->setLastHeardMicrostamp(usecTimestampNow()); QByteArray replyPacket = constructPingReplyPacket(packet); writeDatagram(replyPacket, matchingNode, senderSockAddr); // If we don't have a symmetric socket for this node and this socket doesn't match // what we have for public and local then set it as the symmetric. // This allows a server on a reachable port to communicate with nodes on symmetric NATs if (matchingNode->getSymmetricSocket().isNull()) { if (senderSockAddr != matchingNode->getLocalSocket() && senderSockAddr != matchingNode->getPublicSocket()) { matchingNode->setSymmetricSocket(senderSockAddr); } } } break; } case PacketTypePingReply: { SharedNodePointer sendingNode = sendingNodeForPacket(packet); if (sendingNode) { sendingNode->setLastHeardMicrostamp(usecTimestampNow()); // activate the appropriate socket for this node, if not yet updated activateSocketFromNodeCommunication(packet, sendingNode); // set the ping time for this node for stat collection timePingReply(packet, sendingNode); } break; } case PacketTypeUnverifiedPing: { // send back a reply QByteArray replyPacket = constructPingReplyPacket(packet, _domainHandler.getICEClientID()); writeUnverifiedDatagram(replyPacket, senderSockAddr); break; } case PacketTypeUnverifiedPingReply: { qDebug() << "Received reply from domain-server on" << senderSockAddr; // for now we're unsafely assuming this came back from the domain if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) { qDebug() << "Connecting to domain using local socket"; _domainHandler.activateICELocalSocket(); } else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) { qDebug() << "Conecting to domain using public socket"; _domainHandler.activateICEPublicSocket(); } else { qDebug() << "Reply does not match either local or public socket for domain. Will not connect."; } } case PacketTypeStunResponse: { // a STUN packet begins with 00, we've checked the second zero with packetVersionMatch // pass it along so it can be processed into our public address and port processSTUNResponse(packet); break; } default: LimitedNodeList::processNodeData(senderSockAddr, packet); break; } }