source: trunk/libtransmission/torrent.h @ 12121

Last change on this file since 12121 was 12121, checked in by jordan, 11 years ago

(trunk libT) Add an enumeration for the peer id length. Use that enum for the peer_id fields in tr_session and tr_torrent.

This also avoids an extra malloc/free per-torrent and per-session, but mostly this tweak is for the extra readability of the PEER_ID_LEN=20 enum.

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