source: trunk/libtransmission/torrent.h @ 9965

Last change on this file since 9965 was 9965, checked in by charles, 12 years ago

(trunk) No code changes here... filling in some of the blanks in the "peers" and "utils" doxygen groups' documentation.

  • Property svn:keywords set to Date Rev Author Id
File size: 12.9 KB
Line 
1/*
2 * This file Copyright (C) 2009-2010 Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: torrent.h 9965 2010-01-19 19:37:00Z charles $
11 */
12
13#ifndef __TRANSMISSION__
14 #error only libtransmission should #include this header.
15#endif
16
17#ifndef TR_TORRENT_H
18#define TR_TORRENT_H 1
19
20#include "completion.h" /* tr_completion */
21#include "session.h" /* tr_sessionLock(), tr_sessionUnlock() */
22#include "utils.h" /* TR_GNUC_PRINTF */
23
24struct tr_bandwidth;
25struct tr_torrent_tiers;
26struct tr_magnet_info;
27
28/**
29***  Package-visible ctor API
30**/
31
32void        tr_ctorSetSave( tr_ctor * ctor,
33                            tr_bool   saveMetadataInOurTorrentsDir );
34
35int         tr_ctorGetSave( const tr_ctor * ctor );
36
37int         tr_ctorGetMagnet( const tr_ctor * ctor, const struct tr_magnet_info ** setme );
38
39void        tr_ctorInitTorrentPriorities( const tr_ctor * ctor, tr_torrent * tor );
40
41void        tr_ctorInitTorrentWanted( const tr_ctor * ctor, tr_torrent * tor );
42
43/**
44***
45**/
46
47/* just like tr_torrentSetFileDLs but doesn't trigger a fastresume save */
48void        tr_torrentInitFileDLs( tr_torrent *      tor,
49                                   tr_file_index_t * files,
50                                   tr_file_index_t   fileCount,
51                                   tr_bool           do_download );
52
53void        tr_torrentRecheckCompleteness( tr_torrent * );
54
55void        tr_torrentSetHasPiece( tr_torrent *     tor,
56                                   tr_piece_index_t pieceIndex,
57                                   tr_bool          has );
58
59void        tr_torrentChangeMyPort( tr_torrent * session );
60
61tr_torrent* tr_torrentFindFromHashString( tr_session * session,
62                                          const char * hashString );
63
64tr_torrent* tr_torrentFindFromObfuscatedHash( tr_session    * session,
65                                              const uint8_t * hash );
66
67tr_bool     tr_torrentIsPieceTransferAllowed( const tr_torrent * torrent,
68                                              tr_direction       direction );
69
70
71
72#define tr_block( a, b ) _tr_block( tor, a, b )
73tr_block_index_t _tr_block( const tr_torrent * tor,
74                            tr_piece_index_t   index,
75                            uint32_t           offset );
76
77tr_bool          tr_torrentReqIsValid( const tr_torrent * tor,
78                                       tr_piece_index_t   index,
79                                       uint32_t           offset,
80                                       uint32_t           length );
81
82uint64_t         tr_pieceOffset( const tr_torrent * tor,
83                                 tr_piece_index_t   index,
84                                 uint32_t           offset,
85                                 uint32_t           length );
86
87void             tr_torrentInitFilePriority( tr_torrent       * tor,
88                                             tr_file_index_t    fileIndex,
89                                             tr_priority_t      priority );
90
91int              tr_torrentCountUncheckedPieces( const tr_torrent * );
92
93tr_bool          tr_torrentIsFileChecked( const tr_torrent  * tor,
94                                          tr_file_index_t     file );
95
96void             tr_torrentSetPieceChecked( tr_torrent       * tor,
97                                            tr_piece_index_t   piece,
98                                            tr_bool            isChecked );
99
100void             tr_torrentSetFileChecked( tr_torrent       * tor,
101                                           tr_file_index_t    file,
102                                           tr_bool            isChecked );
103
104void             tr_torrentUncheck( tr_torrent * tor );
105
106int              tr_torrentPromoteTracker( tr_torrent   * tor,
107                                           int            trackerIndex );
108
109time_t*          tr_torrentGetMTimes( const tr_torrent  * tor,
110                                      size_t            * setmeCount );
111
112tr_torrent*      tr_torrentNext( tr_session  * session,
113                                 tr_torrent  * current );
114
115void             tr_torrentCheckSeedRatio( tr_torrent * tor );
116
117/** save a torrent's .resume file if it's changed since the last time it was saved */
118void             tr_torrentSave( tr_torrent * tor );
119
120void             tr_torrentSetLocalError( tr_torrent * tor, const char * fmt, ... ) TR_GNUC_PRINTF( 2, 3 );
121
122
123
124typedef enum
125{
126    TR_VERIFY_NONE,
127    TR_VERIFY_WAIT,
128    TR_VERIFY_NOW
129}
130tr_verify_state;
131
132void             tr_torrentSetVerifyState( tr_torrent      * tor,
133                                           tr_verify_state   state );
134
135struct tr_incomplete_metadata;
136
137/** @brief Torrent object */
138struct tr_torrent
139{
140    tr_session *             session;
141    tr_info                  info;
142
143    int                      magicNumber;
144
145    tr_stat_errtype          error;
146    char                     errorString[128];
147
148    uint8_t                  obfuscatedHash[SHA_DIGEST_LENGTH];
149
150    /* Used when the torrent has been created with a magnet link
151     * and we're in the process of downloading the metainfo from
152     * other peers */
153    struct tr_incomplete_metadata  * incompleteMetadata;
154
155    /* If the initiator of the connection receives a handshake in which the
156     * peer_id does not match the expected peerid, then the initiator is
157     * expected to drop the connection. Note that the initiator presumably
158     * received the peer information from the tracker, which includes the
159     * peer_id that was registered by the peer. The peer_id from the tracker
160     * and in the handshake are expected to match.
161     */
162    uint8_t * peer_id;
163
164    /* Where the files will be when it's complete */
165    char * downloadDir;
166
167    /* Where the files are when the torrent is incomplete */
168    char * incompleteDir;
169
170    /* Length, in bytes, of the "info" dict in the .torrent file */
171    int infoDictLength;
172
173    /* Offset, in bytes, of the beginning of the "info" dict in the .torrent file */
174    int infoDictOffset;
175
176    /* Where the files are now.
177     * This pointer will be equal to downloadDir or incompleteDir */
178    const char * currentDir;
179
180    /* How many bytes we ask for per request */
181    uint32_t                   blockSize;
182    tr_block_index_t           blockCount;
183
184    uint32_t                   lastBlockSize;
185    uint32_t                   lastPieceSize;
186
187    uint32_t                   blockCountInPiece;
188    uint32_t                   blockCountInLastPiece;
189
190    struct tr_completion       completion;
191
192    struct tr_bitfield         checkedPieces;
193    tr_completeness            completeness;
194
195    struct tr_torrent_tiers  * tiers;
196    struct tr_publisher_tag  * tiersSubscription;
197
198    time_t                     dhtAnnounceAt;
199    time_t                     dhtAnnounce6At;
200    tr_bool                    dhtAnnounceInProgress;
201    tr_bool                    dhtAnnounce6InProgress;
202
203    uint64_t                   downloadedCur;
204    uint64_t                   downloadedPrev;
205    uint64_t                   uploadedCur;
206    uint64_t                   uploadedPrev;
207    uint64_t                   corruptCur;
208    uint64_t                   corruptPrev;
209
210    uint64_t                   etaDLSpeedCalculatedAt;
211    double                     etaDLSpeed;
212    uint64_t                   etaULSpeedCalculatedAt;
213    double                     etaULSpeed;
214
215    time_t                     addedDate;
216    time_t                     activityDate;
217    time_t                     doneDate;
218    time_t                     startDate;
219    time_t                     anyDate;
220
221    tr_torrent_metadata_func  * metadata_func;
222    void                      * metadata_func_user_data;
223
224    tr_torrent_completeness_func  * completeness_func;
225    void                          *  completeness_func_user_data;
226
227    tr_torrent_ratio_limit_hit_func  * ratio_limit_hit_func;
228    void                             * ratio_limit_hit_func_user_data;
229
230    tr_bool                    isRunning;
231    tr_bool                    isDeleting;
232    tr_bool                    needsSeedRatioCheck;
233    tr_bool                    startAfterVerify;
234    tr_bool                    isDirty;
235
236    uint16_t                   maxConnectedPeers;
237
238    tr_verify_state            verifyState;
239
240    time_t                     lastStatTime;
241    tr_stat                    stats;
242
243    tr_torrent *               next;
244
245    int                        uniqueId;
246
247    struct tr_bandwidth      * bandwidth;
248
249    struct tr_torrent_peers  * torrentPeers;
250
251    double                     desiredRatio;
252    tr_ratiolimit              ratioLimitMode;
253
254    uint64_t                   preVerifyTotal;
255};
256
257/* get the index of this piece's first block */
258static inline tr_block_index_t
259tr_torPieceFirstBlock( const tr_torrent * tor, const tr_piece_index_t piece )
260{
261    return piece * tor->blockCountInPiece;
262}
263
264/* what piece index is this block in? */
265static inline tr_piece_index_t
266tr_torBlockPiece( const tr_torrent * tor, const tr_block_index_t block )
267{
268    return block / tor->blockCountInPiece;
269}
270
271/* how many blocks are in this piece? */
272static inline uint32_t
273tr_torPieceCountBlocks( const tr_torrent * tor, const tr_piece_index_t piece )
274{
275    return piece == tor->info.pieceCount - 1 ? tor->blockCountInLastPiece
276                                             : tor->blockCountInPiece;
277}
278
279/* how many bytes are in this piece? */
280static inline uint32_t
281tr_torPieceCountBytes( const tr_torrent * tor, const tr_piece_index_t piece )
282{
283    return piece == tor->info.pieceCount - 1 ? tor->lastPieceSize
284                                             : tor->info.pieceSize;
285}
286
287/* how many bytes are in this block? */
288static inline uint32_t
289tr_torBlockCountBytes( const tr_torrent * tor, const tr_block_index_t block )
290{
291    return block == tor->blockCount - 1 ? tor->lastBlockSize
292                                        : tor->blockSize;
293}
294
295static inline void tr_torrentLock( const tr_torrent * tor )
296{
297    tr_sessionLock( tor->session );
298}
299
300static inline void tr_torrentUnlock( const tr_torrent * tor )
301{
302    tr_sessionUnlock( tor->session );
303}
304
305static inline tr_bool
306tr_torrentExists( const tr_session * session, const uint8_t *   torrentHash )
307{
308    return tr_torrentFindFromHash( (tr_session*)session, torrentHash ) != NULL;
309}
310
311static inline tr_bool
312tr_torrentIsSeed( const tr_torrent * tor )
313{
314    return tor->completeness != TR_LEECH;
315}
316
317static inline tr_bool tr_torrentIsPrivate( const tr_torrent * tor )
318{
319    return ( tor != NULL ) && tor->info.isPrivate;
320}
321
322static inline tr_bool tr_torrentAllowsPex( const tr_torrent * tor )
323{
324    return ( tor != NULL )
325        && ( tor->session->isPexEnabled )
326        && ( !tr_torrentIsPrivate( tor ) );
327}
328
329static inline tr_bool tr_torrentAllowsDHT( const tr_torrent * tor )
330{
331    return ( tor != NULL )
332        && ( tr_sessionAllowsDHT( tor->session ) )
333        && ( !tr_torrentIsPrivate( tor ) );
334}
335
336static inline tr_bool tr_torrentIsPieceChecked( const tr_torrent  * tor,
337                                                   tr_piece_index_t    i )
338{
339    return tr_bitfieldHasFast( &tor->checkedPieces, i );
340}
341
342/***
343****
344***/
345
346enum
347{
348    TORRENT_MAGIC_NUMBER = 95549
349};
350
351static inline tr_bool tr_isTorrent( const tr_torrent * tor )
352{
353    return ( tor != NULL )
354        && ( tor->magicNumber == TORRENT_MAGIC_NUMBER )
355        && ( tr_isSession( tor->session ) );
356}
357
358/* set a flag indicating that the torrent's .resume file
359 * needs to be saved when the torrent is closed */
360static inline
361void tr_torrentSetDirty( tr_torrent * tor )
362{
363    assert( tr_isTorrent( tor ) );
364
365    tor->isDirty = TRUE;
366}
367
368static inline
369const char * tr_torrentName( const tr_torrent * tor )
370{
371    assert( tr_isTorrent( tor ) );
372
373    return tor->info.name;
374}
375
376/**
377 * Tell the tr_torrent that one of its files has become complete
378 */
379void tr_torrentFileCompleted( tr_torrent * tor, tr_file_index_t fileNo );
380
381
382/**
383 * @brief Like tr_torrentFindFile(), but splits the filename into base and subpath;
384 *
385 * If the file is found, "tr_buildPath( base, subpath, NULL )"
386 * will generate the complete filename.
387 *
388 * @return true if the file is found, false otherwise.
389 *
390 * @param base if the torrent is found, this will be either
391 *             tor->downloadDir or tor->incompleteDir
392 * @param subpath on success, this pointer is assigned a newly-allocated
393 *                string holding the second half of the filename.
394 */
395tr_bool tr_torrentFindFile2( const tr_torrent *, tr_file_index_t fileNo,
396                             const char ** base, char ** subpath );
397
398
399/* Returns a newly-allocated version of the tr_file.name string
400 * that's been modified to denote that it's not a complete file yet.
401 * In the current implementation this is done by appending ".part"
402 * a la Firefox. */
403char* tr_torrentBuildPartial( const tr_torrent *, tr_file_index_t fileNo );
404
405/* for when the info dict has been fundamentally changed wrt files,
406 * piece size, etc. such as in BEP 9 where peers exchange metadata */
407void tr_torrentGotNewInfoDict( tr_torrent * tor );
408
409#endif
Note: See TracBrowser for help on using the repository browser.