浏览代码

* 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

Tatsuhiro Tsujikawa 19 年之前
父节点
当前提交
26aa28acb3
共有 8 个文件被更改,包括 108 次插入46 次删除
  1. 14 0
      ChangeLog
  2. 9 10
      src/AbstractDiskWriter.cc
  3. 7 0
      src/AbstractDiskWriter.h
  4. 43 24
      src/MetaFileUtil.cc
  5. 11 6
      src/PeerInteractionCommand.cc
  6. 5 2
      src/TorrentMan.cc
  7. 7 2
      src/TorrentMan.h
  8. 12 2
      src/Util.cc

+ 14 - 0
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>
 
 	* BitTorrent protocol support added.

+ 9 - 10
src/AbstractDiskWriter.cc

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

+ 7 - 0
src/AbstractDiskWriter.h

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

+ 43 - 24
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) {

+ 11 - 6
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<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();
   }
 }
 

+ 5 - 2
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;
   }
 }

+ 7 - 2
src/TorrentMan.h

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

+ 12 - 2
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) {