void TcpServerListener::onClientReceivedBlock(Block *block)
{
    TcpListener *client = qobject_cast<TcpListener *>(sender());
    if (!clientsList.contains(client)) {
        qCritical() << tr("Could not find client in list");
    } else {
        int id = clientsList.value(client);
        block->setSourceid(id);
        emit blockReceived(block);
    }
}
void TcpServerListener::onClientReceivedBlock(Block block)
{
    TcpListener *client = qobject_cast<TcpListener *>(sender());
    int index = clients.indexOf(client);
    if (index == -1) {
        qCritical() << tr("Could not find client in list");
    } else {
        block.sourceid = index;
        block.direction = Block::SOURCE;
        emit blockReceived(block);
    }
}
void TcpServerListener::handlingClient(int socketDescriptor)
#endif
{
    TcpListener * listener = new(std::nothrow) TcpListener(socketDescriptor);
    if (listener != NULL) {
       // qDebug() << "Listener created" << listener;
        listener->setDecodeinput(decodeInput);
        listener->setEncodeOutput(encodeOutput);
        clients.append(listener);
        listener->moveToThread(workerThread);
        connect(listener, SIGNAL(blockReceived(Block)), SLOT(onClientReceivedBlock(Block)));
        connect(listener, SIGNAL(stopped()), SLOT(clientFinished()));
        connect(listener, SIGNAL(error(QString,QString)), SIGNAL(error(QString,QString)));
        connect(listener, SIGNAL(status(QString,QString)), SIGNAL(status(QString,QString)));
        QTimer::singleShot(0,listener,SLOT(startListening()));
    } else {
        qFatal("Cannot allocate memory for TcpListener X{");
    }
}
void UdpServerListener::packetReceived()
{
    QByteArray data;
    QHostAddress sender;
    quint16 senderPort;

    qint64 datagramSize = udpSocket->pendingDatagramSize();
    data.resize(datagramSize);

    qint64 bread = 0;
    bread += udpSocket->readDatagram(data.data(), data.size(), &sender, &senderPort);

    if (bread != datagramSize) {
        qCritical() << tr("[UdpClientListener::dataReceived] not all the data was read T_T");
    }

    UDPClient client(sender,senderPort);

    if (data.isEmpty()){
        emit log(tr("Received data block is empty, ignoring."),ID, Pip3lineConst::LERROR);
        return;
    }

    int sid = Block::INVALID_ID;
    int index = clients.indexOf(client);
    if (index > -1) {
        sid = clients.at(index).getSid();
    } else {
        if (clients.size() > 1000000)
            emit log(tr("The number of UDP server \"connections\" as reached 1 Millions. Dude for real ?"),ID, Pip3lineConst::LERROR);
        sid = newSourceID(this);
        client.setSid(sid);
        clients.append(client);
        emit updated();
    }

    Block * datab = new(std::nothrow) Block(data,sid);
    if (datab == nullptr) qFatal("Cannot allocate Block for UdpServerListener X{");

    emit blockReceived(datab);
}
void PeerWireClient::processIncomingData()
{
    invalidateTimeout = true;
    if (!receivedHandShake) {
        // Check that we received enough data
        if (bytesAvailable() < MinimalHeaderSize)
            return;

        // Sanity check the protocol ID
        QByteArray id = read(ProtocolIdSize + 1);
        if (id.at(0) != ProtocolIdSize || !id.mid(1).startsWith(ProtocolId)) {
            abort();
            return;
        }

        // Discard 8 reserved bytes, then read the info hash and peer ID
        (void) read(8);

        // Read infoHash
        QByteArray peerInfoHash = read(20);
        if (!infoHash.isEmpty() && peerInfoHash != infoHash) {
            abort();
            return;
        }

        emit infoHashReceived(peerInfoHash);
        if (infoHash.isEmpty()) {
            abort();
            return;
        }

        // Send handshake
        if (!sentHandShake)
            sendHandShake();
        receivedHandShake = true;
    }

    // Handle delayed peer id arrival
    if (!gotPeerId) {
        if (bytesAvailable() < 20)
            return;
        gotPeerId = true;
        if (read(20) == peerIdString) {
            // We connected to ourself
            abort();
            return;
        }
    }

    // Initialize keep-alive timer
    if (!keepAliveTimer)
        keepAliveTimer = startTimer(KeepAliveInterval);

    do {
        // Find the packet length
        if (nextPacketLength == -1) {
            if (bytesAvailable() < 4)
                return;

            char tmp[4];
            read(tmp, sizeof(tmp));
            nextPacketLength = fromNetworkData(tmp);

            if (nextPacketLength < 0 || nextPacketLength > 200000) {
                // Prevent DoS
                abort();
                return;
            }
        }

        // KeepAlive
        if (nextPacketLength == 0) {
            nextPacketLength = -1;
            continue;
        }

        // Wait with parsing until the whole packet has been received
        if (bytesAvailable() < nextPacketLength)
            return;

        // Read the packet
        QByteArray packet = read(nextPacketLength);
        if (packet.size() != nextPacketLength) {
            abort();
            return;
        }

        switch (packet.at(0)) {
        case ChokePacket:
            // We have been choked.
            pwState |= ChokedByPeer;
            incoming.clear();
            if (pendingRequestTimer)
                killTimer(pendingRequestTimer);
            emit choked();
            break;
        case UnchokePacket:
            // We have been unchoked.
            pwState &= ~ChokedByPeer;
            emit unchoked();
            break;
        case InterestedPacket:
            // The peer is interested in downloading.
            pwState |= PeerIsInterested;
            emit interested();
            break;
        case NotInterestedPacket:
            // The peer is not interested in downloading.
            pwState &= ~PeerIsInterested;
            emit notInterested();
            break;
        case HavePacket: {
            // The peer has a new piece available.
            quint32 index = fromNetworkData(&packet.data()[1]);
            if (index < quint32(peerPieces.size())) {
                // Only accept indexes within the valid range.
                peerPieces.setBit(int(index));
            }
            emit piecesAvailable(availablePieces());
            break;
        }
        case BitFieldPacket:
            // The peer has the following pieces available.
            for (int i = 1; i < packet.size(); ++i) {
                for (int bit = 0; bit < 8; ++bit) {
                    if (packet.at(i) & (1 << (7 - bit))) {
                        int bitIndex = int(((i - 1) * 8) + bit);
                        if (bitIndex >= 0 && bitIndex < peerPieces.size()) {
                            // Occasionally, broken clients claim to have
                            // pieces whose index is outside the valid range.
                            // The most common mistake is the index == size
                            // case.
                            peerPieces.setBit(bitIndex);
                        }
                    }
                }
            }
            emit piecesAvailable(availablePieces());
            break;
        case RequestPacket: {
            // The peer requests a block.
            quint32 index = fromNetworkData(&packet.data()[1]);
            quint32 begin = fromNetworkData(&packet.data()[5]);
            quint32 length = fromNetworkData(&packet.data()[9]);
            emit blockRequested(int(index), int(begin), int(length));
            break;
        }
        case PiecePacket: {
            int index = int(fromNetworkData(&packet.data()[1]));
            int begin = int(fromNetworkData(&packet.data()[5]));

            incoming.removeAll(TorrentBlock(index, begin, packet.size() - 9));

            // The peer sends a block.
            emit blockReceived(index, begin, packet.mid(9));

            // Kill the pending block timer.
            if (pendingRequestTimer) {
                killTimer(pendingRequestTimer);
                pendingRequestTimer = 0;
            }
            break;
        }
        case CancelPacket: {
            // The peer cancels a block request.
            quint32 index = fromNetworkData(&packet.data()[1]);
            quint32 begin = fromNetworkData(&packet.data()[5]);
            quint32 length = fromNetworkData(&packet.data()[9]);
            for (int i = 0; i < pendingBlocks.size(); ++i) {
                const BlockInfo &blockInfo = pendingBlocks.at(i);
                if (blockInfo.pieceIndex == int(index)
                    && blockInfo.offset == int(begin)
                    && blockInfo.length == int(length)) {
                    pendingBlocks.removeAt(i);
                    break;
                }
            }
            break;
        }
        default:
            // Unsupported packet type; just ignore it.
            break;
        }
        nextPacketLength = -1;
    } while (bytesAvailable() > 0);
}
Beispiel #6
0
void Peer::processBlockReceived(int index, int offset, const QByteArray &block)
{
    emit blockReceived(index, offset, block);
}