source: trunk/libtransmission/torrent.h

Last change on this file was 14724, checked in by jordan, 5 years ago

use '#pragma once' instead of #ifndef..#define..#endif guards

  • Property svn:keywords set to Date Rev Author Id
File size: 15.5 KB
Line 
1/*
2 * This file Copyright (C) 2009-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: torrent.h 14724 2016-03-29 16:37:21Z mikedld $
8 */
9
10#ifndef __TRANSMISSION__
11 #error only libtransmission should #include this header.
12#endif
13
14#pragma once
15
16#include "bandwidth.h" /* tr_bandwidth */
17#include "completion.h" /* tr_completion */
18#include "session.h" /* tr_sessionLock (), tr_sessionUnlock () */
19#include "utils.h" /* TR_GNUC_PRINTF */
20
21struct tr_torrent_tiers;
22struct tr_magnet_info;
23
24/**
25***  Package-visible ctor API
26**/
27
28void        tr_torrentFree (tr_torrent * tor);
29
30void        tr_ctorSetSave (tr_ctor * ctor,
31                            bool      saveMetadataInOurTorrentsDir);
32
33bool        tr_ctorGetSave (const tr_ctor * ctor);
34
35void        tr_ctorInitTorrentPriorities (const tr_ctor * ctor, tr_torrent * tor);
36
37void        tr_ctorInitTorrentWanted (const tr_ctor * ctor, tr_torrent * tor);
38
39/**
40***
41**/
42
43/* just like tr_torrentSetFileDLs but doesn't trigger a fastresume save */
44void        tr_torrentInitFileDLs (tr_torrent              * tor,
45                                   const tr_file_index_t   * files,
46                                   tr_file_index_t           fileCount,
47                                   bool                      do_download);
48
49void        tr_torrentRecheckCompleteness (tr_torrent *);
50
51void        tr_torrentSetHasPiece (tr_torrent *     tor,
52                                   tr_piece_index_t pieceIndex,
53                                   bool             has);
54
55void        tr_torrentChangeMyPort (tr_torrent * session);
56
57tr_torrent* tr_torrentFindFromHashString (tr_session * session,
58                                          const char * hashString);
59
60tr_torrent* tr_torrentFindFromObfuscatedHash (tr_session    * session,
61                                              const uint8_t * hash);
62
63bool        tr_torrentIsPieceTransferAllowed (const tr_torrent  * torrent,
64                                              tr_direction        direction);
65
66
67
68#define tr_block(a, b) _tr_block (tor, a, b)
69tr_block_index_t _tr_block (const tr_torrent * tor,
70                            tr_piece_index_t   index,
71                            uint32_t           offset);
72
73bool             tr_torrentReqIsValid (const tr_torrent * tor,
74                                       tr_piece_index_t   index,
75                                       uint32_t           offset,
76                                       uint32_t           length);
77
78uint64_t         tr_pieceOffset (const tr_torrent * tor,
79                                 tr_piece_index_t   index,
80                                 uint32_t           offset,
81                                 uint32_t           length);
82
83void             tr_torrentGetBlockLocation (const tr_torrent * tor,
84                                             tr_block_index_t   block,
85                                             tr_piece_index_t * piece,
86                                             uint32_t         * offset,
87                                             uint32_t         * length);
88
89void             tr_torGetFileBlockRange (const tr_torrent        * tor,
90                                          const tr_file_index_t     file,
91                                          tr_block_index_t        * first,
92                                          tr_block_index_t        * last);
93
94void             tr_torGetPieceBlockRange (const tr_torrent        * tor,
95                                           const tr_piece_index_t    piece,
96                                           tr_block_index_t        * first,
97                                           tr_block_index_t        * last);
98
99void             tr_torrentInitFilePriority (tr_torrent       * tor,
100                                             tr_file_index_t    fileIndex,
101                                             tr_priority_t      priority);
102
103void             tr_torrentSetPieceChecked (tr_torrent       * tor,
104                                            tr_piece_index_t   piece);
105
106void             tr_torrentSetChecked (tr_torrent * tor, time_t when);
107
108void             tr_torrentCheckSeedLimit (tr_torrent * tor);
109
110/** save a torrent's .resume file if it's changed since the last time it was saved */
111void             tr_torrentSave (tr_torrent * tor);
112
113void             tr_torrentSetLocalError (tr_torrent * tor, const char * fmt, ...) TR_GNUC_PRINTF (2, 3);
114
115
116
117typedef enum
118{
119    TR_VERIFY_NONE,
120    TR_VERIFY_WAIT,
121    TR_VERIFY_NOW
122}
123tr_verify_state;
124
125void             tr_torrentSetVerifyState (tr_torrent      * tor,
126                                           tr_verify_state   state);
127
128tr_torrent_activity tr_torrentGetActivity (const tr_torrent * tor);
129
130struct tr_incomplete_metadata;
131
132/** @brief Torrent object */
133struct tr_torrent
134{
135    tr_session *             session;
136    tr_info                  info;
137
138    int                      magicNumber;
139
140    tr_stat_errtype          error;
141    char                     errorString[128];
142    char                     errorTracker[128];
143
144    uint8_t                  obfuscatedHash[SHA_DIGEST_LENGTH];
145
146    /* Used when the torrent has been created with a magnet link
147     * and we're in the process of downloading the metainfo from
148     * other peers */
149    struct tr_incomplete_metadata  * incompleteMetadata;
150
151    /* If the initiator of the connection receives a handshake in which the
152     * peer_id does not match the expected peerid, then the initiator is
153     * expected to drop the connection. Note that the initiator presumably
154     * received the peer information from the tracker, which includes the
155     * peer_id that was registered by the peer. The peer_id from the tracker
156     * and in the handshake are expected to match.
157     */
158    unsigned char peer_id[PEER_ID_LEN+1];
159
160    time_t peer_id_creation_time;
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    size_t 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    size_t 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    bool                       dhtAnnounceInProgress;
200    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    unsigned int               etaDLSpeed_Bps;
213    uint64_t                   etaULSpeedCalculatedAt;
214    unsigned int               etaULSpeed_Bps;
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    int                        queuePosition;
226
227    tr_torrent_metadata_func    metadata_func;
228    void                      * metadata_func_user_data;
229
230    tr_torrent_completeness_func    completeness_func;
231    void                          * completeness_func_user_data;
232
233    tr_torrent_ratio_limit_hit_func    ratio_limit_hit_func;
234    void                             * ratio_limit_hit_func_user_data;
235
236    tr_torrent_idle_limit_hit_func    idle_limit_hit_func;
237    void                            * idle_limit_hit_func_user_data;
238
239    void * queue_started_user_data;
240    void (* queue_started_callback)(tr_torrent *, void * queue_started_user_data);
241
242    bool                       isRunning;
243    bool                       isStopping;
244    bool                       isDeleting;
245    bool                       startAfterVerify;
246    bool                       isDirty;
247    bool                       isQueued;
248
249    bool                       magnetVerify;
250
251    bool                       infoDictOffsetIsCached;
252
253    uint16_t                   maxConnectedPeers;
254
255    tr_verify_state            verifyState;
256
257    time_t                     lastStatTime;
258    tr_stat                    stats;
259
260    tr_torrent *               next;
261
262    int                        uniqueId;
263
264    struct tr_bandwidth        bandwidth;
265
266    struct tr_swarm          * swarm;
267
268    float                      desiredRatio;
269    tr_ratiolimit              ratioLimitMode;
270
271    uint16_t                   idleLimitMinutes;
272    tr_idlelimit               idleLimitMode;
273    bool                       finishedSeedingByIdle;
274};
275
276static inline tr_torrent*
277tr_torrentNext (tr_session * session, tr_torrent * current)
278{
279    return current ? current->next : session->torrentList;
280}
281
282/* what piece index is this block in? */
283static inline tr_piece_index_t
284tr_torBlockPiece (const tr_torrent * tor, const tr_block_index_t block)
285{
286    return block / tor->blockCountInPiece;
287}
288
289/* how many bytes are in this piece? */
290static inline uint32_t
291tr_torPieceCountBytes (const tr_torrent * tor, const tr_piece_index_t piece)
292{
293    return piece + 1 == tor->info.pieceCount ? tor->lastPieceSize
294                                             : tor->info.pieceSize;
295}
296
297/* how many bytes are in this block? */
298static inline uint32_t
299tr_torBlockCountBytes (const tr_torrent * tor, const tr_block_index_t block)
300{
301    return block + 1 == tor->blockCount ? tor->lastBlockSize
302                                        : tor->blockSize;
303}
304
305static inline void tr_torrentLock (const tr_torrent * tor)
306{
307  tr_sessionLock (tor->session);
308}
309static inline bool tr_torrentIsLocked (const tr_torrent * tor)
310{
311  return tr_sessionIsLocked (tor->session);
312}
313static inline void tr_torrentUnlock (const tr_torrent * tor)
314{
315  tr_sessionUnlock (tor->session);
316}
317
318static inline bool
319tr_torrentExists (const tr_session * session, const uint8_t *   torrentHash)
320{
321    return tr_torrentFindFromHash ((tr_session*)session, torrentHash) != NULL;
322}
323
324static inline tr_completeness
325tr_torrentGetCompleteness (const tr_torrent * tor)
326{
327    return tor->completeness;
328}
329
330static inline bool
331tr_torrentIsSeed (const tr_torrent * tor)
332{
333    return tr_torrentGetCompleteness(tor) != TR_LEECH;
334}
335
336static inline bool tr_torrentIsPrivate (const tr_torrent * tor)
337{
338    return (tor != NULL) && tor->info.isPrivate;
339}
340
341static inline bool tr_torrentAllowsPex (const tr_torrent * tor)
342{
343    return (tor != NULL)
344        && (tor->session->isPexEnabled)
345        && (!tr_torrentIsPrivate (tor));
346}
347
348static inline bool tr_torrentAllowsDHT (const tr_torrent * tor)
349{
350    return (tor != NULL)
351        && (tr_sessionAllowsDHT (tor->session))
352        && (!tr_torrentIsPrivate (tor));
353}
354
355static inline bool tr_torrentAllowsLPD (const tr_torrent * tor)
356{
357    return (tor != NULL)
358        && (tr_sessionAllowsLPD (tor->session))
359        && (!tr_torrentIsPrivate (tor));
360}
361
362/***
363****
364***/
365
366enum
367{
368    TORRENT_MAGIC_NUMBER = 95549
369};
370
371static inline bool tr_isTorrent (const tr_torrent * tor)
372{
373    return (tor != NULL)
374        && (tor->magicNumber == TORRENT_MAGIC_NUMBER)
375        && (tr_isSession (tor->session));
376}
377
378/* set a flag indicating that the torrent's .resume file
379 * needs to be saved when the torrent is closed */
380static inline
381void tr_torrentSetDirty (tr_torrent * tor)
382{
383    assert (tr_isTorrent (tor));
384
385    tor->isDirty = true;
386}
387
388uint32_t tr_getBlockSize (uint32_t pieceSize);
389
390/**
391 * Tell the tr_torrent that it's gotten a block
392 */
393void tr_torrentGotBlock (tr_torrent * tor, tr_block_index_t blockIndex);
394
395
396
397/**
398 * @brief Like tr_torrentFindFile (), but splits the filename into base and subpath;
399 *
400 * If the file is found, "tr_buildPath (base, subpath, NULL)"
401 * will generate the complete filename.
402 *
403 * @return true if the file is found, false otherwise.
404 *
405 * @param base if the torrent is found, this will be either
406 *             tor->downloadDir or tor->incompleteDir
407 * @param subpath on success, this pointer is assigned a newly-allocated
408 *                string holding the second half of the filename.
409 */
410bool tr_torrentFindFile2 (const tr_torrent *, tr_file_index_t fileNo,
411                          const char ** base, char ** subpath, time_t * mtime);
412
413
414/* Returns a newly-allocated version of the tr_file.name string
415 * that's been modified to denote that it's not a complete file yet.
416 * In the current implementation this is done by appending ".part"
417 * a la Firefox. */
418char* tr_torrentBuildPartial (const tr_torrent *, tr_file_index_t fileNo);
419
420/* for when the info dict has been fundamentally changed wrt files,
421 * piece size, etc. such as in BEP 9 where peers exchange metadata */
422void tr_torrentGotNewInfoDict (tr_torrent * tor);
423
424void tr_torrentSetSpeedLimit_Bps (tr_torrent *, tr_direction, unsigned int Bps);
425unsigned int tr_torrentGetSpeedLimit_Bps (const tr_torrent *, tr_direction);
426
427/**
428 * @return true if this piece needs to be tested
429 */
430bool tr_torrentPieceNeedsCheck (const tr_torrent * tor, tr_piece_index_t pieceIndex);
431
432/**
433 * @brief Test a piece against its info dict checksum
434 * @return true if the piece's passes the checksum test
435 */
436bool tr_torrentCheckPiece (tr_torrent * tor, tr_piece_index_t pieceIndex);
437
438time_t tr_torrentGetFileMTime (const tr_torrent * tor, tr_file_index_t i);
439
440uint64_t tr_torrentGetCurrentSizeOnDisk (const tr_torrent * tor);
441
442bool tr_torrentIsStalled (const tr_torrent * tor);
443
444const unsigned char * tr_torrentGetPeerId (tr_torrent * tor);
445
446static inline uint64_t
447tr_torrentGetLeftUntilDone (const tr_torrent * tor)
448{
449  return tr_cpLeftUntilDone (&tor->completion);
450}
451
452static inline bool
453tr_torrentHasAll (const tr_torrent * tor)
454{
455  return tr_cpHasAll (&tor->completion);
456}
457
458static inline bool
459tr_torrentHasNone (const tr_torrent * tor)
460{
461  return tr_cpHasNone (&tor->completion);
462}
463
464static inline bool
465tr_torrentPieceIsComplete (const tr_torrent * tor, tr_piece_index_t i)
466{
467  return tr_cpPieceIsComplete (&tor->completion, i);
468}
469
470static inline bool
471tr_torrentBlockIsComplete (const tr_torrent * tor, tr_block_index_t i)
472{
473  return tr_cpBlockIsComplete (&tor->completion, i);
474}
475
476static inline size_t
477tr_torrentMissingBlocksInPiece (const tr_torrent * tor, tr_piece_index_t i)
478{
479  return tr_cpMissingBlocksInPiece (&tor->completion, i);
480}
481
482static inline size_t
483tr_torrentMissingBytesInPiece (const tr_torrent * tor, tr_piece_index_t i)
484{
485  return tr_cpMissingBytesInPiece (&tor->completion, i);
486}
487
488static inline void *
489tr_torrentCreatePieceBitfield (const tr_torrent * tor, size_t * byte_count)
490{
491  return tr_cpCreatePieceBitfield (&tor->completion, byte_count);
492}
493
494static inline uint64_t
495tr_torrentHaveTotal (const tr_torrent * tor)
496{
497  return tr_cpHaveTotal (&tor->completion);
498}
499
500
501static inline bool
502tr_torrentIsQueued (const tr_torrent * tor)
503{
504  return tor->isQueued;
505}
506
507static inline tr_direction
508tr_torrentGetQueueDirection (const tr_torrent * tor)
509{
510  return tr_torrentIsSeed (tor) ? TR_UP : TR_DOWN;
511}
512
Note: See TracBrowser for help on using the repository browser.