* 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
pull/1/head
Tatsuhiro Tsujikawa 2006-03-22 15:10:03 +00:00
parent bf336caa83
commit 26aa28acb3
8 changed files with 108 additions and 46 deletions

View File

@ -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>
* BitTorrent protocol support added.

View File

@ -27,17 +27,21 @@
#include <fcntl.h>
#include "DlAbortEx.h"
#include "File.h"
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
#endif // HAVE_LIBSSL
#include "Util.h"
AbstractDiskWriter::AbstractDiskWriter():fd(0) {}
AbstractDiskWriter::AbstractDiskWriter():fd(0) {
#ifdef HAVE_LIBSSL
EVP_MD_CTX_init(&ctx);
#endif // HAVE_LIBSSL
}
AbstractDiskWriter::~AbstractDiskWriter() {
if(fd != 0) {
close(fd);
}
#ifdef HAVE_LIBSSL
EVP_MD_CTX_cleanup(&ctx);
#endif // HAVE_LIBSSL
}
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) {
#ifdef HAVE_LIBSSL
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
try {
int BUFSIZE = 4096;
int BUFSIZE = 16*1024;
char buf[BUFSIZE];
for(int i = 0; i < length/BUFSIZE; i++) {
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];
int len;
EVP_DigestFinal_ex(&ctx, hashValue, (unsigned int*)&len);
EVP_MD_CTX_cleanup(&ctx);
return Util::toHex(hashValue, 20);
} catch(string ex) {
EVP_MD_CTX_cleanup(&ctx);
throw new DlAbortEx(strerror(errno));
}
#else

View File

@ -23,11 +23,18 @@
#define _D_ABSTRACT_DISK_WRITER_H_
#include "DiskWriter.h"
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
#endif // HAVE_LIBSSL
class AbstractDiskWriter:public DiskWriter {
protected:
int fd;
#ifdef HAVE_LIBSSL
EVP_MD_CTX ctx;
#endif // HAVE_LIBSSL
void createFile(string filename, int addFlags = 0);
void writeDataInternal(const char* data, int len);

View File

@ -31,17 +31,26 @@ MetaEntry* MetaFileUtil::parseMetaFile(string file) {
int len = f.size();
char* buf = new char[len];
FILE* fp = fopen(file.c_str(), "r+");
if(fp == NULL) {
throw new DlAbortEx("cannot open metainfo file");
}
if(fread(buf, len, 1, fp) != 1) {
try {
if(fp == NULL) {
throw new DlAbortEx("cannot open metainfo file");
}
if(fread(buf, len, 1, fp) != 1) {
fclose(fp);
throw new DlAbortEx("cannot read metainfo");
}
fclose(fp);
throw new DlAbortEx("cannot read metainfo");
fp = NULL;
MetaEntry* entry = bdecoding(buf, len);
delete [] buf;
return entry;
} catch(Exception* ex) {
delete [] buf;
if(fp != NULL) {
fclose(fp);
}
throw;
}
fclose(fp);
MetaEntry* entry = bdecoding(buf, len);
delete [] buf;
return entry;
}
MetaEntry* MetaFileUtil::bdecoding(const char* buf, int len) {
@ -88,16 +97,21 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
throw new DlAbortEx("mulformed metainfo");
}
Dictionary* dic = new Dictionary();
while(1) {
if(**pp == 'e') {
(*pp)++;
break;
try {
while(1) {
if(**pp == 'e') {
(*pp)++;
break;
}
string name = decodeWordAsString(pp, end);
MetaEntry* e = bdecodingR(pp, end);
dic->put(name, e);
}
string name = decodeWordAsString(pp, end);
MetaEntry* e = bdecodingR(pp, end);
dic->put(name, e);
return dic;
} catch(Exception* ex) {
delete dic;
throw;
}
return dic;
}
List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
@ -105,15 +119,20 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
throw new DlAbortEx("mulformed metainfo");
}
List* lis = new List();
while(1) {
if(**pp == 'e') {
(*pp)++;
break;
try {
while(1) {
if(**pp == 'e') {
(*pp)++;
break;
}
MetaEntry* e = bdecodingR(pp, end);
lis->add(e);
}
MetaEntry* e = bdecodingR(pp, end);
lis->add(e);
return lis;
} catch(Exception* ex) {
delete lis;
throw;
}
return lis;
}
Data* MetaFileUtil::decodeInt(const char** pp, const char* end) {

View File

@ -46,6 +46,7 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
PeerInteractionCommand::~PeerInteractionCommand() {
delete peerConnection;
delete requestSlotMan;
e->torrentMan->unadvertisePiece(cuid);
}
bool PeerInteractionCommand::executeInternal() {
@ -378,14 +379,18 @@ void PeerInteractionCommand::beforeSocketCheck() {
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection);
pendingMessages.push_back(pendingMessage);
} else {
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
pendingMessages.push_back(pendingMessage);
if(pendingMessages.size() == 0) {
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
peerConnection->sendHave(*itr);
}
} else {
for(vector<int>::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
pendingMessages.push_back(pendingMessage);
}
}
}
if(indexes.size() == 0) {
keepAlive();
}
keepAlive();
}
}

View File

@ -61,6 +61,9 @@ void TorrentMan::updatePeers(const Peers& peers) {
}
bool TorrentMan::addPeer(Peer* peer, bool duplicate) {
if(peers.size() >= MAX_PEER_LIST_SIZE) {
return false;
}
if(duplicate) {
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
Peer* p = *itr;
@ -446,9 +449,9 @@ void TorrentMan::read(FILE* file) {
if(fread(&uploadedSize, sizeof(uploadedSize), 1, file) < 1) {
throw new DlAbortEx(strerror(errno));
}
delete savedBitfield;
delete [] savedBitfield;
} catch(Exception* ex) {
delete savedBitfield;
delete [] savedBitfield;
throw;
}
}

View File

@ -29,6 +29,7 @@
#include "DiskWriter.h"
#include "Piece.h"
#include "Directory.h"
#include <deque>
#include <vector>
#include <map>
#include <string>
@ -45,6 +46,7 @@ using namespace std;
#define DEFAULT_ANNOUNCE_INTERVAL 1800
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 120
#define MAX_PEERS 55
#define MAX_PEER_LIST_SIZE 250
#define END_GAME_PIECE_NUM 20
class FileEntry {
@ -55,10 +57,10 @@ public:
~FileEntry() {}
};
typedef vector<Peer*> Peers;
typedef deque<Peer*> Peers;
typedef multimap<int, int> Haves;
typedef vector<FileEntry> MultiFileEntries;
typedef vector<Piece> UsedPieces;
typedef deque<Piece> UsedPieces;
class TorrentMan {
private:
@ -208,6 +210,9 @@ public:
void setPort(int port) { this->port = port; }
int getPort() const { return port; }
int countUsedPiece() const { return usedPieces.size(); }
int countAdvertisedPiece() const { return haves.size(); }
enum FILE_MODE {
SINGLE,
MULTI

View File

@ -204,10 +204,20 @@ void Util::rangedFileCopy(string dest, string src, long long int srcOffset, long
}
int BUF_SIZE = 16*1024;
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++) {
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));
}
if(write(destFd, buf, readLength) == -1) {