diff options
Diffstat (limited to 'examples/network/torrent/peerwireclient.cpp')
-rw-r--r-- | examples/network/torrent/peerwireclient.cpp | 152 |
1 files changed, 44 insertions, 108 deletions
diff --git a/examples/network/torrent/peerwireclient.cpp b/examples/network/torrent/peerwireclient.cpp index 177568d402..349371afbf 100644 --- a/examples/network/torrent/peerwireclient.cpp +++ b/examples/network/torrent/peerwireclient.cpp @@ -1,87 +1,23 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "peerwireclient.h" #include <QHostAddress> #include <QTimerEvent> +#include <QtEndian> -static const int PendingRequestTimeout = 60 * 1000; -static const int ClientTimeout = 120 * 1000; -static const int ConnectTimeout = 60 * 1000; -static const int KeepAliveInterval = 30 * 1000; -static const int RateControlTimerDelay = 2000; +#include <chrono> + +static constexpr std::chrono::seconds PendingRequestTimeout(60); +static constexpr std::chrono::seconds ClientTimeout(120); +static constexpr std::chrono::seconds ConnectTimeout(60); +static constexpr std::chrono::seconds KeepAliveInterval(30); +static constexpr std::chrono::seconds PeerRateControlTimerDelay(2); static const int MinimalHeaderSize = 48; static const char ProtocolId[] = "BitTorrent protocol"; static const char ProtocolIdSize = 19; -// Reads a 32bit unsigned int from data in network order. -static inline quint32 fromNetworkData(const char *data) -{ - const unsigned char *udata = (const unsigned char *)data; - return (quint32(udata[0]) << 24) - | (quint32(udata[1]) << 16) - | (quint32(udata[2]) << 8) - | (quint32(udata[3])); -} - -// Writes a 32bit unsigned int from num to data in network order. -static inline void toNetworkData(quint32 num, char *data) -{ - unsigned char *udata = (unsigned char *)data; - udata[3] = (num & 0xff); - udata[2] = (num & 0xff00) >> 8; - udata[1] = (num & 0xff0000) >> 16; - udata[0] = (num & 0xff000000) >> 24; -} - // Constructs an unconnected PeerWire client and starts the connect timer. PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent) : QTcpSocket(parent), pendingBlockSizes(0), @@ -92,7 +28,7 @@ PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent) memset(uploadSpeedData, 0, sizeof(uploadSpeedData)); memset(downloadSpeedData, 0, sizeof(downloadSpeedData)); - transferSpeedTimer = startTimer(RateControlTimerDelay); + transferSpeedTimer = startTimer(PeerRateControlTimerDelay); timeoutTimer = startTimer(ConnectTimeout); peerIdString = peerId; @@ -118,7 +54,7 @@ PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent) // Registers the peer ID and SHA1 sum of the torrent, and initiates // the handshake. -void PeerWireClient::initialize(const QByteArray &infoHash, int pieceCount) +void PeerWireClient::initialize(const QByteArray &infoHash, qint32 pieceCount) { this->infoHash = infoHash; peerPieces.resize(pieceCount); @@ -206,13 +142,13 @@ void PeerWireClient::sendNotInterested() // Sends a piece notification / a "have" message, informing the peer // that we have just downloaded a new piece. -void PeerWireClient::sendPieceNotification(int piece) +void PeerWireClient::sendPieceNotification(qint32 piece) { if (!sentHandShake) sendHandShake(); char message[] = {0, 0, 0, 5, 4, 0, 0, 0, 0}; - toNetworkData(piece, &message[5]); + qToBigEndian(piece, &message[5]); write(message, sizeof(message)); } @@ -241,22 +177,22 @@ void PeerWireClient::sendPieceList(const QBitArray &bitField) } char message[] = {0, 0, 0, 1, 5}; - toNetworkData(bits.size() + 1, &message[0]); + qToBigEndian<qint32>(bits.size() + 1, &message[0]); write(message, sizeof(message)); write(bits); } // Sends a request for a block. -void PeerWireClient::requestBlock(int piece, int offset, int length) +void PeerWireClient::requestBlock(qint32 piece, qint32 offset, qint32 length) { char message[] = {0, 0, 0, 1, 6}; - toNetworkData(13, &message[0]); + qToBigEndian(13, &message[0]); write(message, sizeof(message)); char numbers[4 * 3]; - toNetworkData(piece, &numbers[0]); - toNetworkData(offset, &numbers[4]); - toNetworkData(length, &numbers[8]); + qToBigEndian(piece, &numbers[0]); + qToBigEndian(offset, &numbers[4]); + qToBigEndian(length, &numbers[8]); write(numbers, sizeof(numbers)); incoming << TorrentBlock(piece, offset, length); @@ -270,33 +206,33 @@ void PeerWireClient::requestBlock(int piece, int offset, int length) } // Cancels a request for a block. -void PeerWireClient::cancelRequest(int piece, int offset, int length) +void PeerWireClient::cancelRequest(qint32 piece, qint32 offset, qint32 length) { char message[] = {0, 0, 0, 1, 8}; - toNetworkData(13, &message[0]); + qToBigEndian(13, &message[0]); write(message, sizeof(message)); char numbers[4 * 3]; - toNetworkData(piece, &numbers[0]); - toNetworkData(offset, &numbers[4]); - toNetworkData(length, &numbers[8]); + qToBigEndian(piece, &numbers[0]); + qToBigEndian(offset, &numbers[4]); + qToBigEndian(length, &numbers[8]); write(numbers, sizeof(numbers)); incoming.removeAll(TorrentBlock(piece, offset, length)); } // Sends a block to the peer. -void PeerWireClient::sendBlock(int piece, int offset, const QByteArray &data) +void PeerWireClient::sendBlock(qint32 piece, qint32 offset, const QByteArray &data) { QByteArray block; char message[] = {0, 0, 0, 1, 7}; - toNetworkData(9 + data.size(), &message[0]); + qToBigEndian<qint32>(9 + data.size(), &message[0]); block += QByteArray(message, sizeof(message)); char numbers[4 * 2]; - toNetworkData(piece, &numbers[0]); - toNetworkData(offset, &numbers[4]); + qToBigEndian(piece, &numbers[0]); + qToBigEndian(offset, &numbers[4]); block += QByteArray(numbers, sizeof(numbers)); block += data; @@ -515,7 +451,7 @@ void PeerWireClient::processIncomingData() char tmp[4]; read(tmp, sizeof(tmp)); - nextPacketLength = fromNetworkData(tmp); + nextPacketLength = qFromBigEndian<qint32>(tmp); if (nextPacketLength < 0 || nextPacketLength > 200000) { // Prevent DoS @@ -567,7 +503,7 @@ void PeerWireClient::processIncomingData() break; case HavePacket: { // The peer has a new piece available. - quint32 index = fromNetworkData(&packet.data()[1]); + quint32 index = qFromBigEndian<quint32>(&packet.data()[1]); if (index < quint32(peerPieces.size())) { // Only accept indexes within the valid range. peerPieces.setBit(int(index)); @@ -580,7 +516,7 @@ void PeerWireClient::processIncomingData() 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); + qint32 bitIndex = qint32(((i - 1) * 8) + bit); if (bitIndex >= 0 && bitIndex < peerPieces.size()) { // Occasionally, broken clients claim to have // pieces whose index is outside the valid range. @@ -595,15 +531,15 @@ void PeerWireClient::processIncomingData() 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)); + quint32 index = qFromBigEndian<quint32>(&packet.data()[1]); + quint32 begin = qFromBigEndian<quint32>(&packet.data()[5]); + quint32 length = qFromBigEndian<quint32>(&packet.data()[9]); + emit blockRequested(qint32(index), qint32(begin), qint32(length)); break; } case PiecePacket: { - int index = int(fromNetworkData(&packet.data()[1])); - int begin = int(fromNetworkData(&packet.data()[5])); + qint32 index = qint32(qFromBigEndian<quint32>(&packet.data()[1])); + qint32 begin = qint32(qFromBigEndian<quint32>(&packet.data()[5])); incoming.removeAll(TorrentBlock(index, begin, packet.size() - 9)); @@ -619,14 +555,14 @@ void PeerWireClient::processIncomingData() } 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]); + quint32 index = qFromBigEndian<quint32>(&packet.data()[1]); + quint32 begin = qFromBigEndian<quint32>(&packet.data()[5]); + quint32 length = qFromBigEndian<quint32>(&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)) { + if (blockInfo.pieceIndex == qint32(index) + && blockInfo.offset == qint32(begin) + && blockInfo.length == qint32(length)) { pendingBlocks.removeAt(i); break; } |