mirror of https://github.com/aria2/aria2
* PeerInteractionCommand.cc: added a call to
TorrentMan::unadvertisePiece in Destructor. * PeerInteractionCommand.cc: make have message sent immediately if the size of pending message queue is zero. * TorrentMan.cc: set the maximum size of peer list to 250. * TorrentMan.h: changed the container type of Peers and UsedPieces to deque. * Util.cc: fixed rangedFileCopy. * AbstractDiskWriter.{h,cc}: moved digest context initialization to Constructor. Also, moved digest cleanup to Destructor. * MetaFileUtil.cc: fixed memory leakpull/1/head
parent
bf336caa83
commit
26aa28acb3
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2006-03-23 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
* PeerInteractionCommand.cc: added a call to
|
||||||
|
TorrentMan::unadvertisePiece in Destructor.
|
||||||
|
* PeerInteractionCommand.cc: make have message sent immediately
|
||||||
|
if the size of pending message queue is zero.
|
||||||
|
* TorrentMan.cc: set the maximum size of peer list to 250.
|
||||||
|
* TorrentMan.h: changed the container type of Peers and UsedPieces
|
||||||
|
to deque.
|
||||||
|
* Util.cc: fixed rangedFileCopy.
|
||||||
|
* AbstractDiskWriter.{h,cc}: moved digest context initialization
|
||||||
|
to Constructor. Also, moved digest cleanup to Destructor.
|
||||||
|
* MetaFileUtil.cc: fixed memory leak
|
||||||
|
|
||||||
2006-03-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2006-03-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
* BitTorrent protocol support added.
|
* BitTorrent protocol support added.
|
||||||
|
|
|
@ -27,17 +27,21 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#ifdef HAVE_LIBSSL
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#endif // HAVE_LIBSSL
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
AbstractDiskWriter::AbstractDiskWriter():fd(0) {}
|
AbstractDiskWriter::AbstractDiskWriter():fd(0) {
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
EVP_MD_CTX_init(&ctx);
|
||||||
|
#endif // HAVE_LIBSSL
|
||||||
|
}
|
||||||
|
|
||||||
AbstractDiskWriter::~AbstractDiskWriter() {
|
AbstractDiskWriter::~AbstractDiskWriter() {
|
||||||
if(fd != 0) {
|
if(fd != 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
EVP_MD_CTX_cleanup(&ctx);
|
||||||
|
#endif // HAVE_LIBSSL
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::closeFile() {
|
void AbstractDiskWriter::closeFile() {
|
||||||
|
@ -85,12 +89,9 @@ int AbstractDiskWriter::readDataInternal(char* data, int len) {
|
||||||
|
|
||||||
string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
|
string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
EVP_MD_CTX_init(&ctx);
|
|
||||||
EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
|
EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int BUFSIZE = 4096;
|
int BUFSIZE = 16*1024;
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
for(int i = 0; i < length/BUFSIZE; i++) {
|
for(int i = 0; i < length/BUFSIZE; i++) {
|
||||||
if(BUFSIZE != readData(buf, BUFSIZE, offset)) {
|
if(BUFSIZE != readData(buf, BUFSIZE, offset)) {
|
||||||
|
@ -109,10 +110,8 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
|
||||||
unsigned char hashValue[20];
|
unsigned char hashValue[20];
|
||||||
int len;
|
int len;
|
||||||
EVP_DigestFinal_ex(&ctx, hashValue, (unsigned int*)&len);
|
EVP_DigestFinal_ex(&ctx, hashValue, (unsigned int*)&len);
|
||||||
EVP_MD_CTX_cleanup(&ctx);
|
|
||||||
return Util::toHex(hashValue, 20);
|
return Util::toHex(hashValue, 20);
|
||||||
} catch(string ex) {
|
} catch(string ex) {
|
||||||
EVP_MD_CTX_cleanup(&ctx);
|
|
||||||
throw new DlAbortEx(strerror(errno));
|
throw new DlAbortEx(strerror(errno));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -23,11 +23,18 @@
|
||||||
#define _D_ABSTRACT_DISK_WRITER_H_
|
#define _D_ABSTRACT_DISK_WRITER_H_
|
||||||
|
|
||||||
#include "DiskWriter.h"
|
#include "DiskWriter.h"
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#endif // HAVE_LIBSSL
|
||||||
|
|
||||||
class AbstractDiskWriter:public DiskWriter {
|
class AbstractDiskWriter:public DiskWriter {
|
||||||
protected:
|
protected:
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
EVP_MD_CTX ctx;
|
||||||
|
#endif // HAVE_LIBSSL
|
||||||
|
|
||||||
void createFile(string filename, int addFlags = 0);
|
void createFile(string filename, int addFlags = 0);
|
||||||
|
|
||||||
void writeDataInternal(const char* data, int len);
|
void writeDataInternal(const char* data, int len);
|
||||||
|
|
|
@ -31,6 +31,7 @@ MetaEntry* MetaFileUtil::parseMetaFile(string file) {
|
||||||
int len = f.size();
|
int len = f.size();
|
||||||
char* buf = new char[len];
|
char* buf = new char[len];
|
||||||
FILE* fp = fopen(file.c_str(), "r+");
|
FILE* fp = fopen(file.c_str(), "r+");
|
||||||
|
try {
|
||||||
if(fp == NULL) {
|
if(fp == NULL) {
|
||||||
throw new DlAbortEx("cannot open metainfo file");
|
throw new DlAbortEx("cannot open metainfo file");
|
||||||
}
|
}
|
||||||
|
@ -39,9 +40,17 @@ MetaEntry* MetaFileUtil::parseMetaFile(string file) {
|
||||||
throw new DlAbortEx("cannot read metainfo");
|
throw new DlAbortEx("cannot read metainfo");
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
MetaEntry* entry = bdecoding(buf, len);
|
MetaEntry* entry = bdecoding(buf, len);
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
return entry;
|
return entry;
|
||||||
|
} catch(Exception* ex) {
|
||||||
|
delete [] buf;
|
||||||
|
if(fp != NULL) {
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaEntry* MetaFileUtil::bdecoding(const char* buf, int len) {
|
MetaEntry* MetaFileUtil::bdecoding(const char* buf, int len) {
|
||||||
|
@ -88,6 +97,7 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
|
||||||
throw new DlAbortEx("mulformed metainfo");
|
throw new DlAbortEx("mulformed metainfo");
|
||||||
}
|
}
|
||||||
Dictionary* dic = new Dictionary();
|
Dictionary* dic = new Dictionary();
|
||||||
|
try {
|
||||||
while(1) {
|
while(1) {
|
||||||
if(**pp == 'e') {
|
if(**pp == 'e') {
|
||||||
(*pp)++;
|
(*pp)++;
|
||||||
|
@ -98,6 +108,10 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
|
||||||
dic->put(name, e);
|
dic->put(name, e);
|
||||||
}
|
}
|
||||||
return dic;
|
return dic;
|
||||||
|
} catch(Exception* ex) {
|
||||||
|
delete dic;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
||||||
|
@ -105,6 +119,7 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
||||||
throw new DlAbortEx("mulformed metainfo");
|
throw new DlAbortEx("mulformed metainfo");
|
||||||
}
|
}
|
||||||
List* lis = new List();
|
List* lis = new List();
|
||||||
|
try {
|
||||||
while(1) {
|
while(1) {
|
||||||
if(**pp == 'e') {
|
if(**pp == 'e') {
|
||||||
(*pp)++;
|
(*pp)++;
|
||||||
|
@ -114,6 +129,10 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
||||||
lis->add(e);
|
lis->add(e);
|
||||||
}
|
}
|
||||||
return lis;
|
return lis;
|
||||||
|
} catch(Exception* ex) {
|
||||||
|
delete lis;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Data* MetaFileUtil::decodeInt(const char** pp, const char* end) {
|
Data* MetaFileUtil::decodeInt(const char** pp, const char* end) {
|
||||||
|
|
|
@ -46,6 +46,7 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
||||||
PeerInteractionCommand::~PeerInteractionCommand() {
|
PeerInteractionCommand::~PeerInteractionCommand() {
|
||||||
delete peerConnection;
|
delete peerConnection;
|
||||||
delete requestSlotMan;
|
delete requestSlotMan;
|
||||||
|
e->torrentMan->unadvertisePiece(cuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerInteractionCommand::executeInternal() {
|
bool PeerInteractionCommand::executeInternal() {
|
||||||
|
@ -377,15 +378,19 @@ void PeerInteractionCommand::beforeSocketCheck() {
|
||||||
if(indexes.size() >= 20) {
|
if(indexes.size() >= 20) {
|
||||||
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection);
|
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection);
|
||||||
pendingMessages.push_back(pendingMessage);
|
pendingMessages.push_back(pendingMessage);
|
||||||
|
} else {
|
||||||
|
if(pendingMessages.size() == 0) {
|
||||||
|
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||||
|
peerConnection->sendHave(*itr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||||
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
|
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
|
||||||
pendingMessages.push_back(pendingMessage);
|
pendingMessages.push_back(pendingMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(indexes.size() == 0) {
|
|
||||||
keepAlive();
|
|
||||||
}
|
}
|
||||||
|
keepAlive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@ void TorrentMan::updatePeers(const Peers& peers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentMan::addPeer(Peer* peer, bool duplicate) {
|
bool TorrentMan::addPeer(Peer* peer, bool duplicate) {
|
||||||
|
if(peers.size() >= MAX_PEER_LIST_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(duplicate) {
|
if(duplicate) {
|
||||||
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
|
||||||
Peer* p = *itr;
|
Peer* p = *itr;
|
||||||
|
@ -446,9 +449,9 @@ void TorrentMan::read(FILE* file) {
|
||||||
if(fread(&uploadedSize, sizeof(uploadedSize), 1, file) < 1) {
|
if(fread(&uploadedSize, sizeof(uploadedSize), 1, file) < 1) {
|
||||||
throw new DlAbortEx(strerror(errno));
|
throw new DlAbortEx(strerror(errno));
|
||||||
}
|
}
|
||||||
delete savedBitfield;
|
delete [] savedBitfield;
|
||||||
} catch(Exception* ex) {
|
} catch(Exception* ex) {
|
||||||
delete savedBitfield;
|
delete [] savedBitfield;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "DiskWriter.h"
|
#include "DiskWriter.h"
|
||||||
#include "Piece.h"
|
#include "Piece.h"
|
||||||
#include "Directory.h"
|
#include "Directory.h"
|
||||||
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -45,6 +46,7 @@ using namespace std;
|
||||||
#define DEFAULT_ANNOUNCE_INTERVAL 1800
|
#define DEFAULT_ANNOUNCE_INTERVAL 1800
|
||||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 120
|
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 120
|
||||||
#define MAX_PEERS 55
|
#define MAX_PEERS 55
|
||||||
|
#define MAX_PEER_LIST_SIZE 250
|
||||||
#define END_GAME_PIECE_NUM 20
|
#define END_GAME_PIECE_NUM 20
|
||||||
|
|
||||||
class FileEntry {
|
class FileEntry {
|
||||||
|
@ -55,10 +57,10 @@ public:
|
||||||
~FileEntry() {}
|
~FileEntry() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<Peer*> Peers;
|
typedef deque<Peer*> Peers;
|
||||||
typedef multimap<int, int> Haves;
|
typedef multimap<int, int> Haves;
|
||||||
typedef vector<FileEntry> MultiFileEntries;
|
typedef vector<FileEntry> MultiFileEntries;
|
||||||
typedef vector<Piece> UsedPieces;
|
typedef deque<Piece> UsedPieces;
|
||||||
|
|
||||||
class TorrentMan {
|
class TorrentMan {
|
||||||
private:
|
private:
|
||||||
|
@ -208,6 +210,9 @@ public:
|
||||||
void setPort(int port) { this->port = port; }
|
void setPort(int port) { this->port = port; }
|
||||||
int getPort() const { return port; }
|
int getPort() const { return port; }
|
||||||
|
|
||||||
|
int countUsedPiece() const { return usedPieces.size(); }
|
||||||
|
int countAdvertisedPiece() const { return haves.size(); }
|
||||||
|
|
||||||
enum FILE_MODE {
|
enum FILE_MODE {
|
||||||
SINGLE,
|
SINGLE,
|
||||||
MULTI
|
MULTI
|
||||||
|
|
14
src/Util.cc
14
src/Util.cc
|
@ -204,10 +204,20 @@ void Util::rangedFileCopy(string dest, string src, long long int srcOffset, long
|
||||||
}
|
}
|
||||||
int BUF_SIZE = 16*1024;
|
int BUF_SIZE = 16*1024;
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
int x = length/BUF_SIZE+(length%BUF_SIZE ? 1 : 0);
|
int x = length/BUF_SIZE;
|
||||||
|
int r = length%BUF_SIZE;
|
||||||
for(int i = 0; i < x; i++) {
|
for(int i = 0; i < x; i++) {
|
||||||
int readLength;
|
int readLength;
|
||||||
if((readLength = read(srcFd, buf, BUF_SIZE)) == -1) {
|
if((readLength = read(srcFd, buf, BUF_SIZE)) == -1 || readLength != BUF_SIZE) {
|
||||||
|
throw new DlAbortEx(strerror(errno));
|
||||||
|
}
|
||||||
|
if(write(destFd, buf, readLength) == -1) {
|
||||||
|
throw new DlAbortEx(strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(r > 0) {
|
||||||
|
int readLength;
|
||||||
|
if((readLength = read(srcFd, buf, r)) == -1 || readLength != r) {
|
||||||
throw new DlAbortEx(strerror(errno));
|
throw new DlAbortEx(strerror(errno));
|
||||||
}
|
}
|
||||||
if(write(destFd, buf, readLength) == -1) {
|
if(write(destFd, buf, readLength) == -1) {
|
||||||
|
|
Loading…
Reference in New Issue