예제 #1
0
파일: IceServer.cpp 프로젝트: rabedik/hifi
void IceServer::processDatagrams() {
    HifiSockAddr sendingSockAddr;

    while (_serverSocket.hasPendingDatagrams()) {
        // setup a buffer to read the packet into
        int packetSizeWithHeader = _serverSocket.pendingDatagramSize();
        auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);

        _serverSocket.readDatagram(buffer.get(), packetSizeWithHeader,
                                   sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer());
        
        // make sure that this packet at least looks like something we can read
        if (packetSizeWithHeader >= Packet::localHeaderSize(PacketType::ICEServerHeartbeat)) {
            
            auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, sendingSockAddr);
            
            PacketType::Value packetType = packet->getType();
            
            if (packetType == PacketType::ICEServerHeartbeat) {
                SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*packet);
                
                // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now
                peer->activateMatchingOrNewSymmetricSocket(sendingSockAddr);
            } else if (packetType == PacketType::ICEServerQuery) {
                QDataStream heartbeatStream(packet.get());
                
                // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer?
                QUuid senderUUID;
                heartbeatStream >> senderUUID;
                
                // pull the public and private sock addrs for this peer
                HifiSockAddr publicSocket, localSocket;
                heartbeatStream >> publicSocket >> localSocket;
                
                // check if this node also included a UUID that they would like to connect to
                QUuid connectRequestID;
                heartbeatStream >> connectRequestID;
                
                SharedNetworkPeer matchingPeer = _activePeers.value(connectRequestID);
                
                if (matchingPeer) {
                    
                    qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID;
                    
                    // we have the peer they want to connect to - send them pack the information for that peer
                    sendPeerInformationPacket(*(matchingPeer.data()), &sendingSockAddr);
                    
                    // we also need to send them to the active peer they are hoping to connect to
                    // create a dummy peer object we can pass to sendPeerInformationPacket
                    
                    NetworkPeer dummyPeer(senderUUID, publicSocket, localSocket);
                    sendPeerInformationPacket(dummyPeer, matchingPeer->getActiveSocket());
                } else {
                    qDebug() << "Peer" << senderUUID << "asked for" << connectRequestID << "but no matching peer found";
                }
            }
        }
예제 #2
0
void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {

    auto nlPacket = NLPacket::fromBase(std::move(packet));
    
    // make sure that this packet at least looks like something we can read
    if (nlPacket->getPayloadSize() >= NLPacket::localHeaderSize(PacketType::ICEServerHeartbeat)) {
        
        if (nlPacket->getType() == PacketType::ICEServerHeartbeat) {
            SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*nlPacket);
            if (peer) {
                // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now
                peer->activateMatchingOrNewSymmetricSocket(nlPacket->getSenderSockAddr());

                // we have an active and verified heartbeating peer
                // send them an ACK packet so they know that they are being heard and ready for ICE
                static auto ackPacket = NLPacket::create(PacketType::ICEServerHeartbeatACK);
                _serverSocket.writePacket(*ackPacket, nlPacket->getSenderSockAddr());
            } else {
                // we couldn't verify this peer - respond back to them so they know they may need to perform keypair re-generation
                static auto deniedPacket = NLPacket::create(PacketType::ICEServerHeartbeatDenied);
                _serverSocket.writePacket(*deniedPacket, nlPacket->getSenderSockAddr());
            }
        } else if (nlPacket->getType() == PacketType::ICEServerQuery) {
            QDataStream heartbeatStream(nlPacket.get());
            
            // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer?
            QUuid senderUUID;
            heartbeatStream >> senderUUID;
            
            // pull the public and private sock addrs for this peer
            HifiSockAddr publicSocket, localSocket;
            heartbeatStream >> publicSocket >> localSocket;
            
            // check if this node also included a UUID that they would like to connect to
            QUuid connectRequestID;
            heartbeatStream >> connectRequestID;
            
            SharedNetworkPeer matchingPeer = _activePeers.value(connectRequestID);
            
            if (matchingPeer) {
                
                qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID;
                
                // we have the peer they want to connect to - send them pack the information for that peer
                sendPeerInformationPacket(*matchingPeer, &nlPacket->getSenderSockAddr());
                
                // we also need to send them to the active peer they are hoping to connect to
                // create a dummy peer object we can pass to sendPeerInformationPacket
                
                NetworkPeer dummyPeer(senderUUID, publicSocket, localSocket);
                sendPeerInformationPacket(dummyPeer, matchingPeer->getActiveSocket());
            } else {
                qDebug() << "Peer" << senderUUID << "asked for" << connectRequestID << "but no matching peer found";
            }
        }
    }
예제 #3
0
파일: IceServer.cpp 프로젝트: bakarih/hifi
void IceServer::processDatagrams() {
    HifiSockAddr sendingSockAddr;
    QByteArray incomingPacket;
    
    while (_serverSocket.hasPendingDatagrams()) {
        incomingPacket.resize(_serverSocket.pendingDatagramSize());
        
        _serverSocket.readDatagram(incomingPacket.data(), incomingPacket.size(),
                                   sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer());
        
        
        if (packetTypeForPacket(incomingPacket) == PacketTypeIceServerHeartbeat) {
            QUuid senderUUID = uuidFromPacketHeader(incomingPacket);
            
            // pull the public and private sock addrs for this peer
            HifiSockAddr publicSocket, localSocket;
            
            QDataStream hearbeatStream(incomingPacket);
            hearbeatStream.skipRawData(numBytesForPacketHeader(incomingPacket));
            
            hearbeatStream >> publicSocket >> localSocket;
            
            // make sure we have this sender in our peer hash
            SharedNetworkPeer matchingPeer = _activePeers.value(senderUUID);
            
            if (!matchingPeer) {
                // if we don't have this sender we need to create them now
                matchingPeer = SharedNetworkPeer(new NetworkPeer(senderUUID, publicSocket, localSocket));
                _activePeers.insert(senderUUID, matchingPeer);
                
                qDebug() << "Added a new network peer" << *matchingPeer;
            } else {
                // we already had the peer so just potentially update their sockets
                matchingPeer->setPublicSocket(publicSocket);
                matchingPeer->setLocalSocket(localSocket);
                
                qDebug() << "Matched hearbeat to existing network peer" << *matchingPeer;
            }
            
            // update our last heard microstamp for this network peer to now
            matchingPeer->setLastHeardMicrostamp(usecTimestampNow());
            
            // check if this node also included a UUID that they would like to connect to
            QUuid connectRequestID;
            hearbeatStream >> connectRequestID;
            
            // get the peers asking for connections with this peer
            QSet<QUuid>& requestingConnections = _currentConnections[senderUUID];
            
            if (!connectRequestID.isNull()) {
                qDebug() << "Peer wants to connect to peer with ID" << uuidStringWithoutCurlyBraces(connectRequestID);
                
                // ensure this peer is in the set of current connections for the peer with ID it wants to connect with
                _currentConnections[connectRequestID].insert(senderUUID);
                
                // add the ID of the node they have said they would like to connect to
                requestingConnections.insert(connectRequestID);
            }
            
            if (requestingConnections.size() > 0) {
                // send a heartbeart response based on the set of connections
                qDebug() << "Sending a heartbeat response to" << senderUUID << "who has" << requestingConnections.size()
                    << "potential connections";
                sendHeartbeatResponse(sendingSockAddr, requestingConnections);
            }
        }
    }