diff --git a/ChangeLog b/ChangeLog index 52b196bd..0a1c20d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-03-23 Tatsuhiro Tsujikawa + + * 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 * BitTorrent protocol support added. diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 755c116b..7d4a5844 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -27,17 +27,21 @@ #include #include "DlAbortEx.h" #include "File.h" -#ifdef HAVE_LIBSSL -#include -#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 diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h index b5221170..31c3a282 100644 --- a/src/AbstractDiskWriter.h +++ b/src/AbstractDiskWriter.h @@ -23,11 +23,18 @@ #define _D_ABSTRACT_DISK_WRITER_H_ #include "DiskWriter.h" +#ifdef HAVE_LIBSSL +#include +#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); diff --git a/src/MetaFileUtil.cc b/src/MetaFileUtil.cc index bfc662b6..b0c09bb7 100644 --- a/src/MetaFileUtil.cc +++ b/src/MetaFileUtil.cc @@ -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) { diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index 1b5f60d9..5b0174ee 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -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::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { - PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection); - pendingMessages.push_back(pendingMessage); + if(pendingMessages.size() == 0) { + for(vector::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { + peerConnection->sendHave(*itr); + } + } else { + for(vector::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { + PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection); + pendingMessages.push_back(pendingMessage); + } } } - if(indexes.size() == 0) { - keepAlive(); - } + keepAlive(); } } diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index 9e2cc82d..923c22a2 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -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; } } diff --git a/src/TorrentMan.h b/src/TorrentMan.h index 5e9a38b9..2d25c250 100644 --- a/src/TorrentMan.h +++ b/src/TorrentMan.h @@ -29,6 +29,7 @@ #include "DiskWriter.h" #include "Piece.h" #include "Directory.h" +#include #include #include #include @@ -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 Peers; +typedef deque Peers; typedef multimap Haves; typedef vector MultiFileEntries; -typedef vector UsedPieces; +typedef deque 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 diff --git a/src/Util.cc b/src/Util.cc index 91c89532..b0a03f51 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -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) {