diff options
Diffstat (limited to 'libktorrent/torrent/peeruploader.cpp')
-rw-r--r-- | libktorrent/torrent/peeruploader.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/libktorrent/torrent/peeruploader.cpp b/libktorrent/torrent/peeruploader.cpp new file mode 100644 index 0000000..1e0dbca --- /dev/null +++ b/libktorrent/torrent/peeruploader.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** + * Copyright (C) 2005 by Joris Guisson * + * joris.guisson@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include <set> +#include <ksocketaddress.h> +#include <util/log.h> +#include <util/functions.h> +#include <util/sha1hash.h> +#include "peeruploader.h" +#include "peer.h" +#include "chunkmanager.h" +#include "packetwriter.h" +#include "torrent.h" + +using namespace KNetwork; + +namespace bt +{ + + PeerUploader::PeerUploader(Peer* peer) : peer(peer) + { + uploaded = 0; + } + + + PeerUploader::~PeerUploader() + {} + + void PeerUploader::addRequest(const Request & r) + { + // Out(SYS_CON|LOG_DEBUG) << + // QString("PeerUploader::addRequest %1 %2 %3\n").arg(r.getIndex()).arg(r.getOffset()).arg(r.getLength()) << endl; + + // allowed fast chunks go to the front of the queue + requests.append(r); + } + + void PeerUploader::removeRequest(const Request & r) + { + // Out(SYS_CON|LOG_DEBUG) << + // QString("PeerUploader::removeRequest %1 %2 %3\n").arg(r.getIndex()).arg(r.getOffset()).arg(r.getLength()) << endl; + requests.remove(r); + peer->getPacketWriter().doNotSendPiece(r,peer->getStats().fast_extensions); + } + + Uint32 PeerUploader::update(ChunkManager & cman,Uint32 opt_unchoked) + { + Uint32 ret = uploaded; + uploaded = 0; + + PacketWriter & pw = peer->getPacketWriter(); + + // if we have choked the peer do not upload + if (peer->areWeChoked()) + return ret; + + if (peer->isSnubbed() && !peer->areWeChoked() && + !cman.completed() && peer->getID() != opt_unchoked) + return ret; + + + while (requests.count() > 0) + { + Request r = requests.front(); + + Chunk* c = cman.grabChunk(r.getIndex()); + if (c && c->getData()) + { + if (!pw.sendChunk(r.getIndex(),r.getOffset(),r.getLength(),c)) + { + if (peer->getStats().fast_extensions) + pw.sendReject(r); + } + requests.pop_front(); + } + else + { + // remove requests we can't satisfy + Out(SYS_CON|LOG_DEBUG) << "Cannot satisfy request" << endl; + if (peer->getStats().fast_extensions) + pw.sendReject(r); + requests.pop_front(); + } + } + + return ret; + } + + void PeerUploader::clearAllRequests() + { + bool fast_ext = peer->getStats().fast_extensions; + PacketWriter & pw = peer->getPacketWriter(); + pw.clearPieces(fast_ext); + + if (fast_ext) + { + // reject all requests + // if the peer supports fast extensions, + // choke doesn't mean reject all + QValueList<Request>::iterator i = requests.begin(); + while (i != requests.end()) + { + pw.sendReject(*i); + i++; + } + } + requests.clear(); + } + + Uint32 PeerUploader::getNumRequests() const + { + return requests.count() + peer->getPacketWriter().getNumDataPacketsToWrite(); + } +} |