* 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> 2006-03-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* BitTorrent protocol support added. * BitTorrent protocol support added.

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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();
} }
} }

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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) {