1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_TORRENT_MAN_H_
#define _D_TORRENT_MAN_H_
#include "Peer.h"
#include "common.h"
#include "Logger.h"
#include "BitfieldMan.h"
#include "DiskWriter.h"
#include "Piece.h"
#include "Dictionary.h"
#include "Option.h"
#include "FileEntry.h"
#include "DiskAdaptor.h"
#include "Request.h"
#include "TimeA2.h"
#include <deque>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
#define INFO_HASH_LENGTH 20
#define PEER_ID_LENGTH 20
#define DEFAULT_ANNOUNCE_INTERVAL 1800
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 1800
#define MAX_PEERS 55
#define MIN_PEERS 15
#define MAX_PEER_LIST_SIZE 100
#define END_GAME_PIECE_NUM 20
#define MAX_PEER_ERROR 5
class HaveEntry {
public:
int cuid;
int index;
Time registeredTime;
HaveEntry(int cuid, int index):
cuid(cuid),
index(index) {}
};
typedef deque<PeerHandle> Peers;
typedef deque<HaveEntry> Haves;
typedef deque<int> PieceIndexes;
typedef deque<Piece> Pieces;
class TorrentMan {
private:
Peers peers;
BitfieldMan* bitfield;
unsigned char infoHash[INFO_HASH_LENGTH];
deque<string> pieceHashes;
int peerEntryIdCounter;
int cuidCounter;
long long int totalLength;
long long int downloadLength;
long long int uploadLength;
long long int preDownloadLength;
long long int preUploadLength;
int deltaDownloadLength;
int deltaUploadLength;
int fileMode;
string storeDir;
int port;
Haves haves;
Pieces usedPieces;
bool setupComplete;
const Logger* logger;
Peers activePeers;
bool halt;
FILE* openSegFile(const string& segFilename, const string& mode) const;
void read(FILE* file);
Piece findUsedPiece(int index) const;
void addUsedPiece(const Piece& piece);
void deleteUsedPiece(const Piece& piece);
int deleteUsedPiecesByFillRate(int fillRate, int toDelete);
void reduceUsedPieces(int max);
void readFileEntry(FileEntries& fileEntries, Directory** pTopDir, const Dictionary* infoDic, const string& defaultName);
void setFileFilter(const Strings& filePaths);
void setupInternal1(const string& metaInfoFile);
void setupInternal2();
Piece checkOutPiece(int index);
public:
int pieceLength;
int pieces;
// TODO type char* would be better
string peerId;
string key;
string announce;
string trackerId;
string name;
int interval;
int minInterval;
int complete;
int incomplete;
int connections;
// The number of tracker request command currently in the command queue.
int trackers;
// tracker request
Request* req;
public:
TorrentMan();
~TorrentMan();
DiskAdaptor* diskAdaptor;
const Option* option;
int getNewCuid() { return ++cuidCounter; }
// TODO do not use this method
void updatePeers(const Peers& peers);
bool addPeer(const PeerHandle& peer);
//void updatePeer(const Peer* peer);
const Peers& getPeers() const { return peers; }
PeerHandle getPeer() const;
bool isPeerAvailable() const;
void deleteUnusedPeer(int delSize);
bool hasMissingPiece(const PeerHandle& peer) const;
int getMissingPieceIndex(const PeerHandle& peer) const;
int getMissingFastPieceIndex(const PeerHandle& peer) const;
Piece getMissingPiece(const PeerHandle& peer);
Piece getMissingFastPiece(const PeerHandle& peer);
void completePiece(const Piece& piece);
void cancelPiece(const Piece& piece);
void updatePiece(const Piece& piece);
void syncPiece(Piece& piece);
bool hasPiece(int index) const;
void initBitfield();
bool isEndGame() const;
bool downloadComplete() const;
bool hasAllPieces() const;
void setBitfield(unsigned char* bitfield, int len);
const unsigned char* getBitfield() const {
return bitfield->getBitfield();
}
int getBitfieldLength() const { return bitfield->getBitfieldLength(); }
int getPieceLength(int index) const {
return bitfield->getBlockLength(index);
}
int getPieceLength() const { return bitfield->getBlockLength(); }
void setInfoHash(const unsigned char* infoHash) {
memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
}
const unsigned char* getInfoHash() const {
return infoHash;
}
void setup(const string& metaInfoFile, const Strings& targetFilePaths);
void setup(const string& metaInfoFile, const Integers& targetFileIndexes);
string getPieceHash(int index) const;
// Addes piece index to advertise to other commands. They send have message
// based on this information.
void advertisePiece(int cuid, int index);
// Returns piece index which is not advertised by the caller command and
// newer than lastCheckTime.
PieceIndexes getAdvertisedPieceIndexes(int myCuid, const Time& lastCheckTime) const;
// Removes have entry if specified seconds have elapsed since its registration.
void removeAdvertisedPiece(int elapsed);
long long int getTotalLength() const { return totalLength; }
void setTotalLength(long long int length) { totalLength = length; }
void addDeltaDownloadLength(int length) { deltaDownloadLength += length; }
int getDeltaDownloadLength() const { return deltaDownloadLength; }
void resetDeltaDownloadLength() { deltaDownloadLength = 0; }
void addDeltaUploadLength(int length) { deltaUploadLength += length; }
int getDeltaUploadLength() const { return deltaUploadLength; }
void resetDeltaUploadLength() { deltaUploadLength = 0; }
void addDownloadLength(int deltaLength) { downloadLength += deltaLength; }
long long int getDownloadLength() const { return downloadLength; }
void setDownloadLength(long long int length) { downloadLength = length; }
void addUploadLength(int deltaLength) { uploadLength += deltaLength; }
long long int getUploadLength() const { return uploadLength; }
void setUploadLength(long long int length) { uploadLength = length; }
long long int getSessionDownloadLength() const {
return downloadLength-preDownloadLength;
}
long long int getSessionUploadLength() const {
return uploadLength-preUploadLength;
}
void setFileMode(int mode) {
fileMode = mode;
}
int getFileMode() const {
return fileMode;
}
string getStoreDir() const { return storeDir; }
void setStoreDir(const string& dir) { storeDir = dir; }
string getSegmentFilePath() const;
bool segmentFileExists() const;
void load();
void save() const;
void remove() const;
void copySingleFile() const;
void splitMultiFile();
void fixFilename();
void deleteTempFile() const;
void setPort(int port) { this->port = port; }
int getPort() const { return port; }
int countUsedPiece() const { return usedPieces.size(); }
int countAdvertisedPiece() const { return haves.size(); }
FileEntries readFileEntryFromMetaInfoFile(const string& metaInfoFile);
string getName() const;
void finishSelectiveDownloadingMode();
bool isSelectiveDownloadingMode() const;
long long int getCompletedLength() const;
long long int getSelectedTotalLength() const;
void onDownloadComplete();
void addActivePeer(const PeerHandle& peer) {
activePeers.push_back(peer);
}
Peers& getActivePeers() { return this->activePeers; }
void deleteActivePeer(const PeerHandle& peer) {
Peers::iterator itr = find(activePeers.begin(), activePeers.end(), peer);
if(itr != activePeers.end()) {
activePeers.erase(itr);
}
}
bool isHalt() const { return halt; }
void setHalt(bool halt) {
this->halt = halt;
}
enum FILE_MODE {
SINGLE,
MULTI
};
};
#endif // _D_TORRENT_MAN_H_
|