File indexing completed on 2025-01-05 04:37:22

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "peer.h"
0007 
0008 #include "packetreader.h"
0009 #include "peerdownloader.h"
0010 #include "peermanager.h"
0011 #include "peeruploader.h"
0012 #include "utmetadata.h"
0013 #include "utpex.h"
0014 #include <bcodec/bdecoder.h>
0015 #include <bcodec/bencoder.h>
0016 #include <bcodec/bnode.h>
0017 #include <cmath>
0018 #include <diskio/chunk.h>
0019 #include <download/piece.h>
0020 #include <download/request.h>
0021 #include <mse/encryptedpacketsocket.h>
0022 #include <net/address.h>
0023 #include <net/reverseresolver.h>
0024 #include <torrent/server.h>
0025 #include <torrent/torrent.h>
0026 #include <util/functions.h>
0027 #include <util/log.h>
0028 #include <version.h>
0029 
0030 using namespace net;
0031 
0032 namespace bt
0033 {
0034 static const int MAX_METADATA_SIZE = 100 * 1024 * 1024; // maximum allowed metadata_size (up to 100 MiB)
0035 static const unsigned MAX_PENDING_UPLOAD_BLOCKS = 512; // allow up to 8 MiB of 16KiB blocks
0036 static const Uint32 MAX_PENDING_UPLOAD_BYTES = MAX_PENDING_UPLOAD_BLOCKS * (13 + 16384);
0037 static Uint32 peer_id_counter = 1;
0038 bool Peer::resolve_hostname = true;
0039 
0040 Peer::Peer(mse::EncryptedPacketSocket::Ptr sock,
0041            const PeerID &peer_id,
0042            Uint32 num_chunks,
0043            Uint32 chunk_size,
0044            Uint32 support,
0045            bool local,
0046            ConnectionLimit::Token::Ptr token,
0047            PeerManager *pman)
0048     : PeerInterface(peer_id, num_chunks)
0049     , sock(sock)
0050     , token(token)
0051     , pman(pman)
0052 {
0053     id = peer_id_counter;
0054     peer_id_counter++;
0055     ut_pex_id = 0;
0056 
0057     Uint32 max_packet_len = 9 + MAX_PIECE_LEN; // size of piece packet
0058     Uint32 bitfield_length = num_chunks / 8 + 1 + (num_chunks % 8 == 0 ? 0 : 1);
0059     if (bitfield_length > max_packet_len) // bitfield can be longer
0060         max_packet_len = bitfield_length;
0061 
0062     // to be future proof use 10 times the max packet length,
0063     // in case some extension message comes along which is larger
0064     preader = new PacketReader(10 * max_packet_len);
0065     downloader = new PeerDownloader(this, chunk_size);
0066     uploader = new PeerUploader(this);
0067 
0068     stalled_timer.update();
0069 
0070     connect_time = QTime::currentTime();
0071     stats.client = peer_id.identifyClient();
0072     stats.ip_address = getIPAddresss();
0073     stats.dht_support = support & DHT_SUPPORT;
0074     stats.fast_extensions = support & FAST_EXT_SUPPORT;
0075     stats.extension_protocol = support & EXT_PROT_SUPPORT;
0076     stats.encrypted = sock->encrypted();
0077     stats.local = local;
0078     stats.transport_protocol = sock->socketDevice()->transportProtocol();
0079 
0080     if (stats.ip_address == QStringLiteral("0.0.0.0")) {
0081         Out(SYS_CON | LOG_DEBUG) << "No more 0.0.0.0" << endl;
0082         kill();
0083     } else {
0084         sock->startMonitoring(preader);
0085     }
0086 
0087     pex_allowed = stats.extension_protocol;
0088     extensions.setAutoDelete(true);
0089 
0090     if (resolve_hostname) {
0091         net::ReverseResolver *res = new net::ReverseResolver();
0092         connect(res, &net::ReverseResolver::resolved, this, &Peer::resolved, Qt::QueuedConnection);
0093         res->resolveAsync(sock->getRemoteAddress());
0094     }
0095 }
0096 
0097 Peer::~Peer()
0098 {
0099     // Seeing that we are going to delete the preader object,
0100     // call stopMonitoring, in some situations it is possible that the socket
0101     // is only deleted later because the authenticate object still has a reference to it
0102     sock->stopMonitoring();
0103     delete uploader;
0104     delete downloader;
0105     delete preader;
0106 }
0107 
0108 void Peer::closeConnection()
0109 {
0110     sock->close();
0111 }
0112 
0113 void Peer::kill()
0114 {
0115     sock->close();
0116     killed = true;
0117     token.clear();
0118 }
0119 
0120 void Peer::handleChoke(Uint32 len)
0121 {
0122     if (len != 1) {
0123         kill();
0124         return;
0125     }
0126 
0127     if (!stats.choked)
0128         stats.time_choked = CurrentTime();
0129     stats.choked = true;
0130     downloader->choked();
0131 }
0132 
0133 void Peer::handleUnchoke(Uint32 len)
0134 {
0135     if (len != 1) {
0136         Out(SYS_CON | LOG_DEBUG) << "len err UNCHOKE" << endl;
0137         kill();
0138         return;
0139     }
0140 
0141     if (stats.choked) {
0142         stats.time_unchoked = CurrentTime();
0143         bytes_downloaded_since_unchoke = 0;
0144     }
0145 
0146     stats.choked = false;
0147 }
0148 
0149 void Peer::handleInterested(Uint32 len)
0150 {
0151     if (len != 1) {
0152         Out(SYS_CON | LOG_DEBUG) << "len err INTERESTED" << endl;
0153         kill();
0154         return;
0155     }
0156 
0157     if (!stats.interested) {
0158         stats.interested = true;
0159         pman->rerunChoker();
0160     }
0161 }
0162 
0163 void Peer::handleNotInterested(Uint32 len)
0164 {
0165     if (len != 1) {
0166         kill();
0167         return;
0168     }
0169 
0170     if (stats.interested) {
0171         stats.interested = false;
0172         pman->rerunChoker();
0173     }
0174 }
0175 
0176 void Peer::handleHave(const bt::Uint8 *packet, Uint32 len)
0177 {
0178     if (len != 5) {
0179         kill();
0180     } else {
0181         Uint32 ch = ReadUint32(packet, 1);
0182         if (ch < pieces.getNumBits()) {
0183             pman->have(this, ch);
0184             pieces.set(ch, true);
0185         } else if (pman->getTorrent().isLoaded()) {
0186             Out(SYS_CON | LOG_NOTICE) << "Received invalid have value, kicking peer" << endl;
0187             kill();
0188         }
0189     }
0190 }
0191 
0192 void Peer::handleHaveAll(Uint32 len)
0193 {
0194     if (len != 1) {
0195         kill();
0196     } else {
0197         pieces.setAll(true);
0198         pman->bitSetReceived(this, pieces);
0199     }
0200 }
0201 
0202 void Peer::handleHaveNone(Uint32 len)
0203 {
0204     if (len != 1) {
0205         kill();
0206     } else {
0207         pieces.setAll(false);
0208         pman->bitSetReceived(this, pieces);
0209     }
0210 }
0211 
0212 void Peer::handleBitField(const bt::Uint8 *packet, Uint32 len)
0213 {
0214     if (len != 1 + pieces.getNumBytes()) {
0215         if (pman->getTorrent().isLoaded())
0216             kill();
0217     } else {
0218         pieces = BitSet(packet + 1, pieces.getNumBits());
0219         pman->bitSetReceived(this, pieces);
0220     }
0221 }
0222 
0223 void Peer::handleRequest(const bt::Uint8 *packet, Uint32 len)
0224 {
0225     if (len != 13) {
0226         kill();
0227         return;
0228     }
0229 
0230     Request r(ReadUint32(packet, 1), ReadUint32(packet, 5), ReadUint32(packet, 9), downloader);
0231 
0232     if (stats.has_upload_slot)
0233         uploader->addRequest(r);
0234     else if (stats.fast_extensions)
0235         sendReject(r);
0236 }
0237 
0238 void Peer::handlePiece(const bt::Uint8 *packet, Uint32 len)
0239 {
0240     if (paused)
0241         return;
0242 
0243     if (len < 9) {
0244         kill();
0245         return;
0246     }
0247 
0248     snub_timer.update();
0249 
0250     stats.bytes_downloaded += (len - 9);
0251     bytes_downloaded_since_unchoke += (len - 9);
0252     Piece p(ReadUint32(packet, 1), ReadUint32(packet, 5), len - 9, downloader, packet + 9);
0253     downloader->piece(p);
0254     pman->pieceReceived(p);
0255     downloader->update();
0256 }
0257 
0258 void Peer::handleCancel(const bt::Uint8 *packet, Uint32 len)
0259 {
0260     if (len != 13) {
0261         kill();
0262     } else {
0263         Request r(ReadUint32(packet, 1), ReadUint32(packet, 5), ReadUint32(packet, 9), downloader);
0264         uploader->removeRequest(r);
0265         sock->doNotSendPiece(r, stats.fast_extensions);
0266     }
0267 }
0268 
0269 void Peer::handleReject(const bt::Uint8 *packet, Uint32 len)
0270 {
0271     if (len != 13) {
0272         kill();
0273     } else {
0274         Request r(ReadUint32(packet, 1), ReadUint32(packet, 5), ReadUint32(packet, 9), downloader);
0275         downloader->onRejected(r);
0276     }
0277 }
0278 
0279 void Peer::handlePort(const bt::Uint8 *packet, Uint32 len)
0280 {
0281     if (len != 3) {
0282         kill();
0283     } else {
0284         Uint16 port = ReadUint16(packet, 1);
0285         //  Out(SYS_CON|LOG_DEBUG) << "Got PORT packet : " << port << endl;
0286         pman->portPacketReceived(getIPAddresss(), port);
0287     }
0288 }
0289 
0290 void Peer::handlePacket(const bt::Uint8 *packet, Uint32 size)
0291 {
0292     if (killed || size == 0)
0293         return;
0294 
0295     switch (packet[0]) {
0296     case CHOKE:
0297         handleChoke(size);
0298         break;
0299     case UNCHOKE:
0300         handleUnchoke(size);
0301         break;
0302     case INTERESTED:
0303         handleInterested(size);
0304         break;
0305     case NOT_INTERESTED:
0306         handleNotInterested(size);
0307         break;
0308     case HAVE:
0309         handleHave(packet, size);
0310         break;
0311     case BITFIELD:
0312         handleBitField(packet, size);
0313         break;
0314     case REQUEST:
0315         handleRequest(packet, size);
0316         break;
0317     case PIECE:
0318         handlePiece(packet, size);
0319         break;
0320     case CANCEL:
0321         handleCancel(packet, size);
0322         break;
0323     case REJECT_REQUEST:
0324         handleReject(packet, size);
0325         break;
0326     case PORT:
0327         handlePort(packet, size);
0328         break;
0329     case HAVE_ALL:
0330         handleHaveAll(size);
0331         break;
0332     case HAVE_NONE:
0333         handleHaveNone(size);
0334         break;
0335     case SUGGEST_PIECE:
0336         // ignore suggestions for the moment
0337         break;
0338     case ALLOWED_FAST:
0339         // we no longer support this, so do nothing
0340         break;
0341     case EXTENDED:
0342         handleExtendedPacket(packet, size);
0343         break;
0344     }
0345 }
0346 
0347 void Peer::pause()
0348 {
0349     if (paused)
0350         return;
0351 
0352     downloader->cancelAll();
0353     // choke the peer and tell it we are not interested
0354     choke();
0355     sendNotInterested();
0356     paused = true;
0357 }
0358 
0359 void Peer::unpause()
0360 {
0361     paused = false;
0362 }
0363 
0364 void Peer::handleExtendedPacket(const Uint8 *packet, Uint32 size)
0365 {
0366     if (size <= 2)
0367         return;
0368 
0369     PeerProtocolExtension *ext = extensions.find(packet[1]);
0370     if (ext) {
0371         ext->handlePacket(packet, size);
0372     } else if (packet[1] == 0) {
0373         handleExtendedHandshake(packet, size);
0374     }
0375 }
0376 
0377 void Peer::handleExtendedHandshake(const Uint8 *packet, Uint32 size)
0378 {
0379     QByteArray tmp = QByteArray::fromRawData((const char *)packet, size);
0380     BNode *node = nullptr;
0381     try {
0382         BDecoder dec(tmp, false, 2);
0383         node = dec.decode();
0384         if (!node || node->getType() != BNode::DICT) {
0385             delete node;
0386             return;
0387         }
0388 
0389         BDictNode *dict = (BDictNode *)node;
0390         BDictNode *mdict = dict->getDict(QByteArrayLiteral("m"));
0391         if (!mdict) {
0392             delete node;
0393             return;
0394         }
0395 
0396         BValueNode *val = nullptr;
0397 
0398         if ((val = mdict->getValue(QByteArrayLiteral("ut_pex"))) && UTPex::isEnabled()) {
0399             // ut_pex packet
0400             ut_pex_id = val->data().toInt();
0401             if (ut_pex_id == 0) {
0402                 extensions.erase(UT_PEX_ID);
0403             } else {
0404                 PeerProtocolExtension *ext = extensions.find(UT_PEX_ID);
0405                 if (ext)
0406                     ext->changeID(ut_pex_id);
0407                 else if (pex_allowed)
0408                     extensions.insert(UT_PEX_ID, new UTPex(this, ut_pex_id));
0409             }
0410         }
0411 
0412         if ((val = mdict->getValue(QByteArrayLiteral("ut_metadata")))) {
0413             // meta data
0414             Uint32 ut_metadata_id = val->data().toInt();
0415             if (ut_metadata_id == 0) { // disabled by other side
0416                 extensions.erase(UT_METADATA_ID);
0417             } else {
0418                 PeerProtocolExtension *ext = extensions.find(UT_METADATA_ID);
0419                 if (ext) {
0420                     ext->changeID(ut_metadata_id);
0421                 } else {
0422                     int metadata_size = 0;
0423                     if (dict->getValue(QByteArrayLiteral("metadata_size")))
0424                         metadata_size = dict->getInt(QByteArrayLiteral("metadata_size"));
0425 
0426                     if (metadata_size > MAX_METADATA_SIZE) { // check for wrong metadata_size values
0427                         Out(SYS_GEN | LOG_NOTICE) << "Wrong or too high metadata size: " << metadata_size << ". Killing peer... " << endl;
0428                         Out(SYS_GEN | LOG_NOTICE) << "Maximum supported metadata (torrent file) size: " << MAX_METADATA_SIZE << endl;
0429                         kill();
0430                         delete node;
0431                         return;
0432                     }
0433 
0434                     UTMetaData *md = new UTMetaData(pman->getTorrent(), ut_metadata_id, this);
0435                     md->setReportedMetadataSize(metadata_size);
0436                     extensions.insert(UT_METADATA_ID, md);
0437                 }
0438             }
0439         }
0440 
0441         if ((val = dict->getValue(QByteArrayLiteral("reqq")))) {
0442             stats.max_request_queue = val->data().toInt();
0443         }
0444 
0445         if ((val = dict->getValue(QByteArrayLiteral("upload_only")))) {
0446             stats.partial_seed = val->data().toInt() == 1;
0447         }
0448     } catch (...) {
0449         // just ignore invalid packets
0450         Out(SYS_CON | LOG_DEBUG) << "Invalid extended packet" << endl;
0451     }
0452     delete node;
0453 }
0454 
0455 Uint32 Peer::sendData(const Uint8 *data, Uint32 len)
0456 {
0457     if (killed)
0458         return 0;
0459 
0460     Uint32 ret = sock->sendData(data, len);
0461     if (!sock->ok())
0462         kill();
0463 
0464     return ret;
0465 }
0466 
0467 Uint32 Peer::readData(Uint8 *buf, Uint32 len)
0468 {
0469     if (killed)
0470         return 0;
0471 
0472     Uint32 ret = sock->readData(buf, len);
0473 
0474     if (!sock->ok())
0475         kill();
0476 
0477     return ret;
0478 }
0479 
0480 Uint32 Peer::bytesAvailable() const
0481 {
0482     return sock->bytesAvailable();
0483 }
0484 
0485 Uint32 Peer::getUploadRate() const
0486 {
0487     if (sock)
0488         return sock->getUploadRate();
0489     else
0490         return 0;
0491 }
0492 
0493 Uint32 Peer::getDownloadRate() const
0494 {
0495     if (sock)
0496         return sock->getDownloadRate();
0497     else
0498         return 0;
0499 }
0500 
0501 void Peer::update()
0502 {
0503     if (killed)
0504         return;
0505 
0506     if (!sock->ok() || !preader->ok()) {
0507         Out(SYS_CON | LOG_DEBUG) << "Connection closed" << endl;
0508         kill();
0509         return;
0510     }
0511 
0512     sock->updateSpeeds(bt::CurrentTime());
0513     preader->update(*this);
0514 
0515     Uint32 data_bytes = sock->dataBytesUploaded();
0516 
0517     if (data_bytes > 0) {
0518         stats.bytes_uploaded += data_bytes;
0519         uploader->addUploadedBytes(data_bytes);
0520     }
0521 
0522     if (!paused) {
0523         PtrMap<Uint32, PeerProtocolExtension>::iterator i = extensions.begin();
0524         while (i != extensions.end()) {
0525             if (i->second->needsUpdate())
0526                 i->second->update();
0527             ++i;
0528         }
0529     }
0530 
0531     // if no data is being sent or received, and there are pending requests
0532     // increment the connection stalled timer
0533     if (getUploadRate() > 100 || getDownloadRate() > 100
0534         || (uploader->getNumRequests() == 0 && sock->numPendingPieceUploads() == 0 && downloader->getNumRequests() == 0))
0535         stalled_timer.update();
0536 
0537     stats.download_rate = this->getDownloadRate();
0538     stats.upload_rate = this->getUploadRate();
0539     stats.perc_of_file = this->percentAvailable();
0540     stats.snubbed = this->isSnubbed();
0541     stats.num_up_requests = uploader->getNumRequests() + sock->numPendingPieceUploads();
0542     stats.num_down_requests = downloader->getNumRequests();
0543 }
0544 
0545 bool Peer::isStalled() const
0546 {
0547     return stalled_timer.getElapsedSinceUpdate() >= 2 * 60 * 1000;
0548 }
0549 
0550 bool Peer::isSnubbed() const
0551 {
0552     // 4 minutes
0553     return snub_timer.getElapsedSinceUpdate() >= 2 * 60 * 1000 && stats.num_down_requests > 0;
0554 }
0555 
0556 QString Peer::getIPAddresss() const
0557 {
0558     if (sock)
0559         return sock->getRemoteIPAddress();
0560     else
0561         return QString();
0562 }
0563 
0564 Uint16 Peer::getPort() const
0565 {
0566     if (!sock)
0567         return 0;
0568     else
0569         return sock->getRemotePort();
0570 }
0571 
0572 net::Address Peer::getAddress() const
0573 {
0574     if (!sock)
0575         return net::Address();
0576     else
0577         return sock->getRemoteAddress();
0578 }
0579 
0580 Uint32 Peer::getTimeSinceLastPiece() const
0581 {
0582     return snub_timer.getElapsedSinceUpdate();
0583 }
0584 
0585 float Peer::percentAvailable() const
0586 {
0587     // calculation needs to use bytes, instead of chunks, because
0588     // the last chunk can have a different size
0589     const Torrent &tor = pman->getTorrent();
0590     Uint64 bytes = 0;
0591     if (pieces.get(tor.getNumChunks() - 1))
0592         bytes = tor.getChunkSize() * (pieces.numOnBits() - 1) + tor.getLastChunkSize();
0593     else
0594         bytes = tor.getChunkSize() * pieces.numOnBits();
0595 
0596     Uint64 tbytes = tor.getChunkSize() * (pieces.getNumBits() - 1) + tor.getLastChunkSize();
0597     return (float)bytes / (float)tbytes * 100.0;
0598 }
0599 
0600 void Peer::setACAScore(double s)
0601 {
0602     stats.aca_score = s;
0603 }
0604 
0605 void Peer::choke()
0606 {
0607     if (!stats.has_upload_slot)
0608         return;
0609 
0610     sendChoke();
0611     uploader->clearAllRequests();
0612 }
0613 
0614 void Peer::emitPortPacket()
0615 {
0616     pman->portPacketReceived(sock->getRemoteIPAddress(), sock->getRemotePort());
0617 }
0618 
0619 void Peer::emitPex(const QByteArray &data)
0620 {
0621     pman->pex(data);
0622 }
0623 
0624 void Peer::setPexEnabled(bool on)
0625 {
0626     if (!stats.extension_protocol)
0627         return;
0628 
0629     PeerProtocolExtension *ext = extensions.find(UT_PEX_ID);
0630     if (ext && (!on || !UTPex::isEnabled())) {
0631         extensions.erase(UT_PEX_ID);
0632     } else if (!ext && on && ut_pex_id > 0 && UTPex::isEnabled()) {
0633         // if the other side has enabled it to, create a new UTPex object
0634         extensions.insert(UT_PEX_ID, new UTPex(this, ut_pex_id));
0635     }
0636 
0637     pex_allowed = on;
0638 }
0639 
0640 void Peer::sendExtProtHandshake(Uint16 port, Uint32 metadata_size, bool partial_seed)
0641 {
0642     if (!stats.extension_protocol)
0643         return;
0644 
0645     QByteArray arr;
0646     BEncoder enc(new BEncoderBufferOutput(arr));
0647     enc.beginDict();
0648     enc.write(QByteArrayLiteral("m"));
0649     // supported messages
0650     enc.beginDict();
0651     enc.write(QByteArrayLiteral("ut_pex"));
0652     enc.write((Uint32)(pex_allowed ? UT_PEX_ID : 0));
0653     enc.write(QByteArrayLiteral("ut_metadata"));
0654     enc.write(UT_METADATA_ID);
0655     enc.end();
0656     if (port > 0) {
0657         enc.write(QByteArrayLiteral("p"));
0658         enc.write((Uint32)port);
0659     }
0660     enc.write(QByteArrayLiteral("reqq"));
0661     enc.write((bt::Uint32)250);
0662     if (metadata_size) {
0663         enc.write(QByteArrayLiteral("metadata_size"));
0664         enc.write(metadata_size);
0665     }
0666 
0667     enc.write(QByteArrayLiteral("upload_only"), partial_seed);
0668     enc.write(QByteArrayLiteral("v"));
0669     enc.write(bt::GetVersionString().toLatin1());
0670     enc.end();
0671     sendExtProtMsg(0, arr);
0672 }
0673 
0674 void Peer::setGroupIDs(Uint32 up_gid, Uint32 down_gid)
0675 {
0676     sock->setGroupID(up_gid, true);
0677     sock->setGroupID(down_gid, false);
0678 }
0679 
0680 void Peer::resolved(const QString &hinfo)
0681 {
0682     stats.hostname = hinfo;
0683 }
0684 
0685 void Peer::setResolveHostnames(bool on)
0686 {
0687     resolve_hostname = on;
0688 }
0689 
0690 void Peer::emitMetadataDownloaded(const QByteArray &data)
0691 {
0692     Q_EMIT metadataDownloaded(data);
0693 }
0694 
0695 bool Peer::hasWantedChunks(const bt::BitSet &wanted_chunks) const
0696 {
0697     BitSet bs = pieces;
0698     bs.andBitSet(wanted_chunks);
0699     return bs.numOnBits() > 0;
0700 }
0701 
0702 Uint32 Peer::averageDownloadSpeed() const
0703 {
0704     if (stats.choked)
0705         return 0;
0706 
0707     TimeStamp now = CurrentTime();
0708     if (now >= getUnchokeTime())
0709         return 0;
0710     else
0711         return bytes_downloaded_since_unchoke / (getUnchokeTime() - now);
0712 }
0713 
0714 void Peer::sendChoke()
0715 {
0716     if (!stats.has_upload_slot)
0717         return;
0718 
0719     sock->addPacket(Packet::Ptr(new Packet(CHOKE)));
0720     stats.has_upload_slot = false;
0721 }
0722 
0723 void Peer::sendUnchoke()
0724 {
0725     if (stats.has_upload_slot)
0726         return;
0727 
0728     sock->addPacket(Packet::Ptr(new Packet(UNCHOKE)));
0729     stats.has_upload_slot = true;
0730 }
0731 
0732 void Peer::sendEvilUnchoke()
0733 {
0734     sock->addPacket(Packet::Ptr(new Packet(UNCHOKE)));
0735     stats.has_upload_slot = false;
0736 }
0737 
0738 void Peer::sendInterested()
0739 {
0740     if (stats.am_interested == true)
0741         return;
0742 
0743     sock->addPacket(Packet::Ptr(new Packet(INTERESTED)));
0744     stats.am_interested = true;
0745 }
0746 
0747 void Peer::sendNotInterested()
0748 {
0749     if (stats.am_interested == false)
0750         return;
0751 
0752     sock->addPacket(Packet::Ptr(new Packet(NOT_INTERESTED)));
0753     stats.am_interested = false;
0754 }
0755 
0756 void Peer::sendRequest(const Request &r)
0757 {
0758     sock->addPacket(Packet::Ptr(new Packet(r, bt::REQUEST)));
0759 }
0760 
0761 void Peer::sendCancel(const Request &r)
0762 {
0763     sock->addPacket(Packet::Ptr(new Packet(r, bt::CANCEL)));
0764 }
0765 
0766 void Peer::sendReject(const Request &r)
0767 {
0768     sock->addPacket(Packet::Ptr(new Packet(r, bt::REJECT_REQUEST)));
0769 }
0770 
0771 void Peer::sendHave(Uint32 index)
0772 {
0773     sock->addPacket(Packet::Ptr(new Packet(index, bt::HAVE)));
0774 }
0775 
0776 void Peer::sendPort(Uint16 port)
0777 {
0778     sock->addPacket(Packet::Ptr(new Packet(port)));
0779 }
0780 
0781 void Peer::sendBitSet(const BitSet &bs)
0782 {
0783     sock->addPacket(Packet::Ptr(new Packet(bs)));
0784 }
0785 
0786 void Peer::sendHaveAll()
0787 {
0788     sock->addPacket(Packet::Ptr(new Packet(bt::HAVE_ALL)));
0789 }
0790 
0791 void Peer::sendHaveNone()
0792 {
0793     sock->addPacket(Packet::Ptr(new Packet(bt::HAVE_NONE)));
0794 }
0795 
0796 void Peer::sendSuggestPiece(Uint32 index)
0797 {
0798     sock->addPacket(Packet::Ptr(new Packet(index, bt::SUGGEST_PIECE)));
0799 }
0800 
0801 void Peer::sendAllowedFast(Uint32 index)
0802 {
0803     sock->addPacket(Packet::Ptr(new Packet(index, bt::ALLOWED_FAST)));
0804 }
0805 
0806 bool Peer::sendChunk(Uint32 index, Uint32 begin, Uint32 len, Chunk *ch)
0807 {
0808     //      Out() << "sendChunk " << index << " " << begin << " " << len << endl;
0809 
0810 #ifndef NDEBUG
0811     Q_ASSERT(ch);
0812     if (!ch) {
0813         Out(SYS_CON | LOG_NOTICE) << "Warning : attempted to upload an invalid chunk" << endl;
0814         return false;
0815     }
0816 #endif
0817     if (begin >= ch->getSize() || begin + len > ch->getSize()) {
0818         Out(SYS_CON | LOG_NOTICE) << "Warning : Illegal piece request" << endl;
0819         Out(SYS_CON | LOG_NOTICE) << "\tChunk : index " << index << " size = " << ch->getSize() << endl;
0820         Out(SYS_CON | LOG_NOTICE) << "\tPiece : begin = " << begin << " len = " << len << endl;
0821         return false;
0822     }
0823     if (sock->numPendingPieceUploads() >= MAX_PENDING_UPLOAD_BLOCKS ||
0824         sock->numPendingPieceUploadBytes() + 13 + len > MAX_PENDING_UPLOAD_BYTES)
0825     {
0826         Out(SYS_CON | LOG_NOTICE) << "Warning : rejecting piece request due to limit on pending uploads" << endl;
0827         return false;
0828     }
0829     /*      Out(SYS_CON|LOG_DEBUG) << QString("Uploading %1 %2 %3 %4 %5")
0830      *          .arg(index).arg(begin).arg(len).arg((quint64)ch,0,16).arg((quint64)ch->getData(),0,16)
0831      *          << endl;;
0832      */
0833     sock->addPacket(Packet::Ptr(new Packet(index, begin, len, ch)));
0834     return true;
0835 }
0836 
0837 void Peer::sendExtProtMsg(Uint8 id, const QByteArray &data)
0838 {
0839     sock->addPacket(Packet::Ptr(new Packet(id, data)));
0840 }
0841 
0842 void Peer::clearPendingPieceUploads()
0843 {
0844     sock->clearPieces(stats.fast_extensions);
0845 }
0846 
0847 void Peer::chunkAllowed(Uint32 chunk)
0848 {
0849     sendHave(chunk);
0850 }
0851 
0852 }
0853 
0854 #include "moc_peer.cpp"