mirror of https://github.com/aria2/aria2
pull/1/head
parent
df6c7c0385
commit
29374cd70c
|
@ -1,3 +1,7 @@
|
||||||
|
2006-03-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
* BitTorrent protocol support added.
|
||||||
|
|
||||||
2006-03-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2006-03-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
* SocketCore.cc: remove the assignment of addrinfo.ai_addr.
|
* SocketCore.cc: remove the assignment of addrinfo.ai_addr.
|
||||||
|
|
24
README
24
README
|
@ -20,6 +20,7 @@ aria2 is in very early development stage. Currently it has following features:
|
||||||
* Segmented download
|
* Segmented download
|
||||||
* Cookie support(currently aria2 ignores "expires")
|
* Cookie support(currently aria2 ignores "expires")
|
||||||
* It can run as a daemon process.
|
* It can run as a daemon process.
|
||||||
|
* BitTorrent protocol support
|
||||||
|
|
||||||
3. How to build
|
3. How to build
|
||||||
---------------
|
---------------
|
||||||
|
@ -30,4 +31,25 @@ The executable is aria2c in src directory.
|
||||||
|
|
||||||
4. SSL
|
4. SSL
|
||||||
------
|
------
|
||||||
You need OpenSSL library(0.9.7b or higher) to enable HTTPS support.
|
You need OpenSSL library(0.9.7b or higher) to enable HTTPS and BitTorrent
|
||||||
|
support.
|
||||||
|
|
||||||
|
5. BitTorrrent
|
||||||
|
--------------
|
||||||
|
The filename of the downloaded file is determined as follows:
|
||||||
|
|
||||||
|
single-file mode:
|
||||||
|
If "name" key is present in .torrent file, filename is the value of "name"
|
||||||
|
key. Otherwise, filename is the basename of .torrent file appended by
|
||||||
|
".file". For example, .torrent file is "test.torrrent", then filename is
|
||||||
|
"test.torrent.file".
|
||||||
|
The directory to store the downloaded file can be specified by -d option.
|
||||||
|
multi-file mode:
|
||||||
|
The complete directory/file structure mentioned in .torrent file is
|
||||||
|
created.
|
||||||
|
The directory to store the top directory of downloaded files can be
|
||||||
|
specified by -d option.
|
||||||
|
|
||||||
|
Note: -o option is used to change the filename of downloaded .torrent file.
|
||||||
|
|
||||||
|
This version only supports compact peers list format.
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#ifndef _D_META_ENTRY_H_
|
#ifndef _D_META_ENTRY_H_
|
||||||
#define _D_META_ENTRY_H_
|
#define _D_META_ENTRY_H_
|
||||||
|
|
||||||
//#include "MetaEntryVisitor.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
class MetaEntryVisitor;
|
class MetaEntryVisitor;
|
||||||
|
|
|
@ -97,7 +97,8 @@ bool PeerAbstractCommand::execute() {
|
||||||
onAbort(err);
|
onAbort(err);
|
||||||
delete(err);
|
delete(err);
|
||||||
return prepareForNextPeer(0);
|
return prepareForNextPeer(0);
|
||||||
} catch(DlRetryEx* err) {
|
}
|
||||||
|
/*catch(DlRetryEx* err) {
|
||||||
e->logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
e->logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
||||||
peer->tryCount++;
|
peer->tryCount++;
|
||||||
bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
|
bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
|
||||||
|
@ -114,6 +115,7 @@ bool PeerAbstractCommand::execute() {
|
||||||
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this method removed when PeerBalancerCommand is implemented
|
// TODO this method removed when PeerBalancerCommand is implemented
|
||||||
|
|
|
@ -102,7 +102,6 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
}
|
}
|
||||||
receiveMessage();
|
receiveMessage();
|
||||||
}
|
}
|
||||||
//detectTimeoutAndDuplicateBlock();
|
|
||||||
requestSlotMan->deleteTimedoutRequestSlot(piece);
|
requestSlotMan->deleteTimedoutRequestSlot(piece);
|
||||||
requestSlotMan->deleteCompletedRequestSlot(piece);
|
requestSlotMan->deleteCompletedRequestSlot(piece);
|
||||||
sendInterest();
|
sendInterest();
|
||||||
|
@ -255,41 +254,6 @@ void PeerInteractionCommand::onGotWrongPiece() {
|
||||||
e->torrentMan->updatePiece(piece);
|
e->torrentMan->updatePiece(piece);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
const RequestSlot& PeerInteractionCommand::getRequestSlot(int index, int begin, int length) const {
|
|
||||||
for(RequestSlots::const_iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) {
|
|
||||||
const RequestSlot& slot = *itr;
|
|
||||||
if(slot.index == index && slot.begin == begin && slot.length == length) {
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RequestSlot::nullSlot;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
bool PeerInteractionCommand::deleteRequestSlot(const RequestSlot& slot) {
|
|
||||||
for(RequestSlots::iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) {
|
|
||||||
if(slot.index == itr->index && slot.begin == itr->begin && slot.length == itr->length) {
|
|
||||||
requestSlots.erase(itr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
void PeerInteractionCommand::deleteAllRequestSlot() {
|
|
||||||
if(!Piece::isNull(piece)) {
|
|
||||||
for(RequestSlots::const_iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) {
|
|
||||||
if(itr->index == piece.getIndex()) {
|
|
||||||
piece.cancelBlock(itr->blockIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e->torrentMan->updatePiece(piece);
|
|
||||||
}
|
|
||||||
requestSlots.clear();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// TODO this method removed when PeerBalancerCommand is implemented
|
// TODO this method removed when PeerBalancerCommand is implemented
|
||||||
bool PeerInteractionCommand::prepareForNextPeer(int wait) {
|
bool PeerInteractionCommand::prepareForNextPeer(int wait) {
|
||||||
if(e->torrentMan->isPeerAvailable()) {
|
if(e->torrentMan->isPeerAvailable()) {
|
||||||
|
@ -306,38 +270,9 @@ bool PeerInteractionCommand::prepareForRetry(int wait) {
|
||||||
e->commands.push(this);
|
e->commands.push(this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void PeerInteractionCommand::detectTimeoutAndDuplicateBlock() {
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
for(RequestSlots::iterator itr = requestSlots.begin(); itr != requestSlots.end();) {
|
|
||||||
const RequestSlot& slot = *itr;
|
|
||||||
if(slot.isTimeout(120) || piece.hasBlock(slot.blockIndex)) {
|
|
||||||
e->logger->debug("CUID#%d - deleting requestslot blockIndex %d", cuid, slot.blockIndex);
|
|
||||||
if(slot.isTimeout(120)) {
|
|
||||||
e->logger->debug("CUID#%d - because of timeout", cuid);
|
|
||||||
} else {
|
|
||||||
e->logger->debug("CUID#%d - because of duplicate block", cuid);
|
|
||||||
}
|
|
||||||
piece.cancelBlock(slot.blockIndex);
|
|
||||||
e->torrentMan->updatePiece(piece);
|
|
||||||
// send cancel message
|
|
||||||
PendingMessage pendingMessage =
|
|
||||||
PendingMessage::createCancelMessage(piece.getIndex(),
|
|
||||||
slot.blockIndex*piece.getBlockLength(),
|
|
||||||
piece.getBlockLength(slot.blockIndex),
|
|
||||||
peerConnection);
|
|
||||||
pendingMessages.push_back(pendingMessage);
|
|
||||||
itr = requestSlots.erase(itr);
|
|
||||||
} else {
|
|
||||||
itr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Piece PeerInteractionCommand::getNewPieceAndSendInterest() {
|
Piece PeerInteractionCommand::getNewPieceAndSendInterest() {
|
||||||
Piece piece = e->torrentMan->getMissingPiece(peer->getBitfield(),
|
Piece piece = e->torrentMan->getMissingPiece(peer);
|
||||||
peer->getBitfieldLength());
|
|
||||||
if(Piece::isNull(piece)) {
|
if(Piece::isNull(piece)) {
|
||||||
e->logger->debug("CUID#%d - try to send not-interested", cuid);
|
e->logger->debug("CUID#%d - try to send not-interested", cuid);
|
||||||
PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection);
|
PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection);
|
||||||
|
@ -346,7 +281,6 @@ Piece PeerInteractionCommand::getNewPieceAndSendInterest() {
|
||||||
e->logger->debug("CUID#%d - try to send interested", cuid);
|
e->logger->debug("CUID#%d - try to send interested", cuid);
|
||||||
PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection);
|
PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection);
|
||||||
pendingMessages.push_back(pendingMessage);
|
pendingMessages.push_back(pendingMessage);
|
||||||
//piecefield = new BitfieldMan(16*1024, piece.length);
|
|
||||||
}
|
}
|
||||||
return piece;
|
return piece;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,12 +130,12 @@ bool TorrentMan::isEndGame() const {
|
||||||
return bitfield->countMissingBlock() <= END_GAME_PIECE_NUM;
|
return bitfield->countMissingBlock() <= END_GAME_PIECE_NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Piece TorrentMan::getMissingPiece(const unsigned char* peerBitfield, int length) {
|
Piece TorrentMan::getMissingPiece(const Peer* peer) {
|
||||||
int index = -1;
|
int index = -1;
|
||||||
if(isEndGame()) {
|
if(isEndGame()) {
|
||||||
index = bitfield->getMissingIndex(peerBitfield, length);
|
index = bitfield->getMissingIndex(peer->getBitfield(), peer->getBitfieldLength());
|
||||||
} else {
|
} else {
|
||||||
index = bitfield->getMissingUnusedIndex(peerBitfield, length);
|
index = bitfield->getMissingUnusedIndex(peer->getBitfield(), peer->getBitfieldLength());
|
||||||
}
|
}
|
||||||
if(index == -1) {
|
if(index == -1) {
|
||||||
return Piece::nullPiece;
|
return Piece::nullPiece;
|
||||||
|
@ -308,7 +308,7 @@ void TorrentMan::setup(string metaInfoFile) {
|
||||||
name = topName->toString();
|
name = topName->toString();
|
||||||
} else {
|
} else {
|
||||||
char* basec = strdup(metaInfoFile.c_str());
|
char* basec = strdup(metaInfoFile.c_str());
|
||||||
name = string(basename(basec));
|
name = string(basename(basec))+".file";
|
||||||
free(basec);
|
free(basec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ public:
|
||||||
bool isPeerAvailable() const;
|
bool isPeerAvailable() const;
|
||||||
int deleteOldErrorPeers(int maxNum);
|
int deleteOldErrorPeers(int maxNum);
|
||||||
|
|
||||||
Piece getMissingPiece(const unsigned char* peerBitfield, int len);
|
Piece getMissingPiece(const Peer* peer);
|
||||||
void completePiece(const Piece& piece);
|
void completePiece(const Piece& piece);
|
||||||
void cancelPiece(const Piece& piece);
|
void cancelPiece(const Piece& piece);
|
||||||
void updatePiece(const Piece& piece);
|
void updatePiece(const Piece& piece);
|
||||||
|
|
|
@ -33,11 +33,11 @@ CPPUNIT_TEST_SUITE_REGISTRATION( TorrentManTest );
|
||||||
|
|
||||||
Peers createPeers() {
|
Peers createPeers() {
|
||||||
Peers peers;
|
Peers peers;
|
||||||
Peer* peer1 = new Peer("192.168.0.1", 6881);
|
Peer* peer1 = new Peer("192.168.0.1", 6881, 512*1024, 5242870);
|
||||||
peer1->entryId = 1;
|
peer1->entryId = 1;
|
||||||
Peer* peer2 = new Peer("192.168.0.2", 6881);
|
Peer* peer2 = new Peer("192.168.0.2", 6881, 512*1024, 5242870);
|
||||||
peer2->entryId = 2;
|
peer2->entryId = 2;
|
||||||
Peer* peer3 = new Peer("192.168.0.3", 6881);
|
Peer* peer3 = new Peer("192.168.0.3", 6881, 512*1024, 5242870);
|
||||||
peer3->entryId = 3;
|
peer3->entryId = 3;
|
||||||
peers.push_back(peer1);
|
peers.push_back(peer1);
|
||||||
peers.push_back(peer2);
|
peers.push_back(peer2);
|
||||||
|
@ -93,10 +93,10 @@ void TorrentManTest::testGetPeer() {
|
||||||
TorrentMan tm;
|
TorrentMan tm;
|
||||||
Peers peers = createPeers();
|
Peers peers = createPeers();
|
||||||
tm.updatePeers(peers);
|
tm.updatePeers(peers);
|
||||||
CPPUNIT_ASSERT(tm.getPeer(1) != Peer::nullPeer);
|
CPPUNIT_ASSERT(tm.getPeer() != Peer::nullPeer);
|
||||||
CPPUNIT_ASSERT(tm.getPeer(2) != Peer::nullPeer);
|
CPPUNIT_ASSERT(tm.getPeer() != Peer::nullPeer);
|
||||||
CPPUNIT_ASSERT(tm.getPeer(3) != Peer::nullPeer);
|
CPPUNIT_ASSERT(tm.getPeer() != Peer::nullPeer);
|
||||||
CPPUNIT_ASSERT(tm.getPeer(4) == Peer::nullPeer);
|
CPPUNIT_ASSERT(tm.getPeer() == Peer::nullPeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentManTest::testGetMissingPiece() {
|
void TorrentManTest::testGetMissingPiece() {
|
||||||
|
@ -108,12 +108,12 @@ void TorrentManTest::testGetMissingPiece() {
|
||||||
|
|
||||||
unsigned char peerBitfield[2] = { 0xff, 0xff };
|
unsigned char peerBitfield[2] = { 0xff, 0xff };
|
||||||
Piece piece1 = tm.getMissingPiece(peerBitfield, 2);
|
Piece piece1 = tm.getMissingPiece(peerBitfield, 2);
|
||||||
CPPUNIT_ASSERT_EQUAL(0, piece1.index);
|
CPPUNIT_ASSERT_EQUAL(0, piece1.getIndex());
|
||||||
CPPUNIT_ASSERT_EQUAL(512*1024, piece1.length);
|
CPPUNIT_ASSERT_EQUAL(512*1024, piece1.getLength());
|
||||||
|
|
||||||
Piece piece2 = tm.getMissingPiece(peerBitfield, 2);
|
Piece piece2 = tm.getMissingPiece(peerBitfield, 2);
|
||||||
CPPUNIT_ASSERT_EQUAL(1, piece2.index);
|
CPPUNIT_ASSERT_EQUAL(1, piece2.getIndex());
|
||||||
CPPUNIT_ASSERT_EQUAL(512*1024, piece2.length);
|
CPPUNIT_ASSERT_EQUAL(512*1024, piece2.getLength());
|
||||||
|
|
||||||
tm.completePiece(piece1);
|
tm.completePiece(piece1);
|
||||||
|
|
||||||
|
@ -149,8 +149,8 @@ void TorrentManTest::testCancelPiece() {
|
||||||
|
|
||||||
unsigned char peerBitfield[2] = { 0xff, 0xff };
|
unsigned char peerBitfield[2] = { 0xff, 0xff };
|
||||||
Piece piece = tm.getMissingPiece(peerBitfield, 2);
|
Piece piece = tm.getMissingPiece(peerBitfield, 2);
|
||||||
CPPUNIT_ASSERT_EQUAL(0, piece.index);
|
CPPUNIT_ASSERT_EQUAL(0, piece.getIndex());
|
||||||
CPPUNIT_ASSERT_EQUAL(512*1024, piece.length);
|
CPPUNIT_ASSERT_EQUAL(512*1024, piece.getLength());
|
||||||
|
|
||||||
tm.cancelPiece(piece);
|
tm.cancelPiece(piece);
|
||||||
int len = tm.getBitfieldLength();
|
int len = tm.getBitfieldLength();
|
||||||
|
|
Loading…
Reference in New Issue