diff --git a/libtransmission/peer-mgr-private.h b/libtransmission/peer-mgr-private.h index 539e14a4c..c4c7ee7cd 100644 --- a/libtransmission/peer-mgr-private.h +++ b/libtransmission/peer-mgr-private.h @@ -34,27 +34,6 @@ enum ENCRYPTION_PREFERENCE_NO }; -/** -*** The "SWIFT" system is described by Karthik Tamilmani, -*** Vinay Pai, and Alexander Mohr of Stony Brook University -*** in their paper "SWIFT: A System With Incentives For Trading" -*** http://citeseer.ist.psu.edu/tamilmani04swift.html -*** -*** More SWIFT constants are defined in peer-mgr.c -**/ - -/** - * Use SWIFT? - */ -static const int SWIFT_ENABLED = 0; - -/** - * For every byte the peer uploads to us, - * allow them to download this many bytes from us - */ -static const double SWIFT_REPAYMENT_RATIO = 1.33; - - typedef struct tr_peer { unsigned int peerIsChoked : 1; @@ -88,10 +67,8 @@ typedef struct tr_peer struct tr_ratecontrol * rcToClient; struct tr_ratecontrol * rcToPeer; - double rateToClient; - double rateToPeer; - - int64_t credit; + float rateToClient; + float rateToPeer; } tr_peer; diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index a69cbc2ae..f196c281d 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -35,35 +35,6 @@ #include "trevent.h" #include "utils.h" -/** -*** The "SWIFT" system is described by Karthik Tamilmani, -*** Vinay Pai, and Alexander Mohr of Stony Brook University -*** in their paper "SWIFT: A System With Incentives For Trading" -*** http://citeseer.ist.psu.edu/tamilmani04swift.html -*** -*** More SWIFT constants are defined in peer-mgr-private.h -**/ - -/** - * Allow new peers to download this many bytes from - * us when getting started. This can prevent gridlock - * with other peers using tit-for-tat algorithms - */ -static const int SWIFT_INITIAL_CREDIT = 64 * 1024; /* 64 KiB */ - -/** - * We expend a fraction of our torrent's total upload speed - * on largesse by uniformly distributing free credit to - * all of our peers. This too helps prevent gridlock. - */ -static const double SWIFT_LARGESSE = 0.15; /* 15% of our UL */ - -/** - * How frequently to extend largesse-based credit - */ -static const int SWIFT_PERIOD_MSEC = 5000; - - enum { /* how frequently to change which peers are choked */ @@ -135,7 +106,6 @@ typedef struct tr_timer * reconnectTimer; tr_timer * rechokeTimer; tr_timer * refillTimer; - tr_timer * swiftTimer; tr_torrent * tor; tr_peer * optimistic; /* the optimistic peer, or NULL if none */ tr_bitfield * requested; @@ -308,7 +278,6 @@ peerConstructor( const struct in_addr * in_addr ) { tr_peer * p; p = tr_new0( tr_peer, 1 ); - p->credit = SWIFT_INITIAL_CREDIT; p->rcToClient = tr_rcInit( ); p->rcToPeer = tr_rcInit( ); memcpy( &p->in_addr, in_addr, sizeof(struct in_addr) ); @@ -392,7 +361,6 @@ torrentDestructor( Torrent * t ) tr_timerFree( &t->reconnectTimer ); tr_timerFree( &t->rechokeTimer ); tr_timerFree( &t->refillTimer ); - tr_timerFree( &t->swiftTimer ); tr_bitfieldFree( t->requested ); tr_ptrArrayFree( t->pool, (PtrArrayForeachFunc)tr_free ); @@ -1235,7 +1203,6 @@ tr_peerMgrGetPeers( tr_peerMgr * manager, static int reconnectPulse( void * vtorrent ); static int rechokePulse( void * vtorrent ); -static int swiftPulse( void * vtorrent ); void tr_peerMgrStartTorrent( tr_peerMgr * manager, @@ -1250,7 +1217,6 @@ tr_peerMgrStartTorrent( tr_peerMgr * manager, assert( t != NULL ); assert( ( t->isRunning != 0 ) == ( t->reconnectTimer != NULL ) ); assert( ( t->isRunning != 0 ) == ( t->rechokeTimer != NULL ) ); - assert( ( t->isRunning != 0 ) == ( t->swiftTimer != NULL ) ); if( !t->isRunning ) { @@ -1264,15 +1230,9 @@ tr_peerMgrStartTorrent( tr_peerMgr * manager, rechokePulse, t, RECHOKE_PERIOD_MSEC ); - t->swiftTimer = tr_timerNew( t->manager->handle, - swiftPulse, t, - SWIFT_PERIOD_MSEC ); - reconnectPulse( t ); rechokePulse( t ); - - swiftPulse( t ); } managerUnlock( manager ); @@ -1286,7 +1246,6 @@ stopTorrent( Torrent * t ) t->isRunning = 0; tr_timerFree( &t->rechokeTimer ); tr_timerFree( &t->reconnectTimer ); - tr_timerFree( &t->swiftTimer ); /* disconnect the peers. */ tr_ptrArrayForeach( t->peers, (PtrArrayForeachFunc)peerDestructor ); @@ -1563,7 +1522,7 @@ isSame( const tr_peer * peer ) *** **/ -static double +static int getWeightedRate( const tr_peer * peer, int clientIsSeed ) { return (int)( 10.0 * ( clientIsSeed ? peer->rateToPeer @@ -1658,55 +1617,6 @@ rechokePulse( void * vtorrent ) return TRUE; } -/*** -**** -***/ - -static int -swiftPulse( void * vtorrent ) -{ - Torrent * t = vtorrent; - torrentLock( t ); - - if( !tr_torrentIsSeed( t->tor ) ) - { - int i; - int peerCount = 0; - int deadbeatCount = 0; - tr_peer ** peers = getConnectedPeers( t, &peerCount ); - tr_peer ** deadbeats = tr_new( tr_peer*, peerCount ); - - const double ul_KiBsec = tr_rcRate( t->tor->upload ); - const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0); - const double ul_bytes = ul_KiB * 1024; - const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE; - int freeCreditPerPeer; - - for( i=0; icredit <= 0 ) - deadbeats[deadbeatCount++] = peer; - } - - freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount ); - for( i=0; icredit = freeCreditPerPeer; - - tordbg( t, "%d deadbeats, " - "who are each being granted %d bytes' credit " - "for a total of %.1f KiB, " - "%d%% of the torrent's ul speed %.1f\n", - deadbeatCount, freeCreditPerPeer, - ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec ); - - tr_free( deadbeats ); - tr_free( peers ); - } - - torrentUnlock( t ); - return TRUE; -} - /*** **** **** Life and Death @@ -1752,9 +1662,9 @@ shouldPeerBeClosed( const Torrent * t, const tr_peer * peer, int peerCount ) const int relaxStrictnessIfFewerThanN = (int)((getMaxPeerCount(tor) * 0.9) + 0.5); /* if we have >= relaxIfFewerThan, strictness is 100%. * if we have zero connections, strictness is 0% */ - const double strictness = peerCount >= relaxStrictnessIfFewerThanN + const float strictness = peerCount >= relaxStrictnessIfFewerThanN ? 1.0 - : peerCount / (double)relaxStrictnessIfFewerThanN; + : peerCount / (float)relaxStrictnessIfFewerThanN; const int lo = MIN_UPLOAD_IDLE_SECS; const int hi = MAX_UPLOAD_IDLE_SECS; const int limit = lo + ((hi-lo) * strictness); diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index 440074e25..11fce99eb 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -1160,7 +1160,6 @@ clientGotBytes( tr_peermsgs * msgs, uint32_t byteCount ) tor->activityDate = now; tor->downloadedCur += byteCount; msgs->info->pieceDataActivityDate = now; - msgs->info->credit += (int)(byteCount * SWIFT_REPAYMENT_RATIO); tr_rcTransferred( msgs->info->rcToClient, byteCount ); tr_rcTransferred( tor->download, byteCount ); tr_rcTransferred( tor->handle->download, byteCount ); @@ -1383,7 +1382,6 @@ peerGotBytes( tr_peermsgs * msgs, uint32_t byteCount ) tor->activityDate = now; tor->uploadedCur += byteCount; msgs->info->pieceDataActivityDate = now; - msgs->info->credit -= byteCount; tr_rcTransferred( msgs->info->rcToPeer, byteCount ); tr_rcTransferred( tor->upload, byteCount ); tr_rcTransferred( tor->handle->upload, byteCount ); @@ -1578,27 +1576,13 @@ sendKeepalive( tr_peermsgs * msgs ) *** **/ -static int -isSwiftEnabled( const tr_peermsgs * msgs ) -{ - /* rationale: SWIFT is good for getting rid of deadbeats, but most - * private trackers have ratios where you _want_ to feed deadbeats - * as much as possible. So we disable SWIFT on private torrents */ - return SWIFT_ENABLED - && !tr_torrentIsSeed( msgs->torrent ) - && !tr_torrentIsPrivate( msgs->torrent ); -} - static size_t getUploadMax( const tr_peermsgs * msgs ) { static const size_t maxval = ~0; const tr_torrent * tor = msgs->torrent; - const int useSwift = isSwiftEnabled( msgs ); - const size_t swiftLeft = msgs->info->credit; int speedLeft; int bufLeft; - size_t ret; if( tor->uploadLimitMode == TR_SPEEDLIMIT_GLOBAL ) speedLeft = tor->handle->useUploadLimit ? tr_rcBytesLeft( tor->handle->upload ) : maxval; @@ -1611,10 +1595,7 @@ getUploadMax( const tr_peermsgs * msgs ) * queued up in it... blocksize, +13 for the size of the BT protocol's * block message overhead */ bufLeft = tor->blockSize + 13 - tr_peerIoWriteBytesWaiting( msgs->io ); - ret = MIN( speedLeft, bufLeft ); - if( useSwift) - ret = MIN( ret, swiftLeft ); - return ret; + return MIN( speedLeft, bufLeft ); } static int diff --git a/libtransmission/ratecontrol.c b/libtransmission/ratecontrol.c index 84aa1034b..0d782bb67 100644 --- a/libtransmission/ratecontrol.c +++ b/libtransmission/ratecontrol.c @@ -42,8 +42,8 @@ struct tr_transfer struct tr_ratecontrol { - int limit; - int newest; + int8_t limit; + int8_t newest; struct tr_transfer transfers[HISTORY_SIZE]; }; diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index e1babc443..9d26c6e04 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -52,6 +52,20 @@ typedef uint32_t tr_file_index_t; typedef uint32_t tr_piece_index_t; typedef uint64_t tr_block_index_t; +/** + * @brief returns Transmission's default configuration file directory. + * + * The default configuration directory is determined this way: + * - If the TRANSMISSION_HOME environmental variable is set, + * its value is returned. + * - otherwise, if we're running on Darwin, + * "$HOME/Library/Application Support/Transmission" is returned. + * - otherwise, if we're running on WIN32, + * "$CSIDL_APPDATA/Transmission" is returned. + * - otherwise, if XDG_CONFIG_HOME is set, + * "$XDG_CONFIG_HOME/transmission" is returned. + * - lastly, $HOME/.config/transmission" is used. + */ const char* tr_getDefaultConfigDir( void ); typedef struct tr_ctor tr_ctor; @@ -72,61 +86,123 @@ typedef struct tr_torrent tr_torrent; * @{ */ +/** @see tr_sessionInitFull */ #define TR_DEFAULT_CONFIG_DIR tr_getDefaultConfigDir() +/** @see tr_sessionInitFull */ #define TR_DEFAULT_PEX_ENABLED 1 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_PORT_FORWARDING_ENABLED 0 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_PORT 51413 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_GLOBAL_PEER_LIMIT 200 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_PEER_SOCKET_TOS 8 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_BLOCKLIST_ENABLED 0 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_RPC_ENABLED 0 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_RPC_PORT 9091 +/** @see tr_sessionInitFull */ #define TR_DEFAULT_RPC_PORT_STR "9091" +/** @see tr_sessionInitFull */ #define TR_DEFAULT_RPC_ACL "+127.0.0.1" /** - * Create and return a Transmission session handle. + * @brief Start a libtransmission session. + * @return an opaque handle to the new session * - * @param configDir the config directory where libtransmission config - * subdirectories will be found, such as "torrents", - * "resume", and "blocklists". - * TR_DEFAULT_CONFIG_DIR can be used as a default. - * @param downloadDir The default directory to save added torrents. - * This can be changed per-session with - * tr_sessionSetDownloadDir() and per-torrent with - * tr_ctorSetDownloadDir(). - * @param tag Obsolete. Only used now for locating legacy fastresume files. - * Valid tags: beos, cli, daemon, gtk, macos, wx - * @param isPexEnabled whether or not PEX is allowed for non-private torrents. - * This can be changed per-session with - * tr_sessionSetPexEnabled(). - * TR_DEFAULT_PEX_ENABLED is the default. - * @param isPortForwardingEnabled If true, libtransmission will attempt - * to find a local UPnP-enabled or NATPMP-enabled - * router and forward a port from there to the local - * machine. This is so remote peers can initiate - * connections with us. - * TR_DEFAULT_PORT_FORWARDING_ENABLED is the default. - * @param publicPort Port number to open for incoming peer connections. - * TR_DEFAULT_PORT is the default. - * @param encryptionMode must be one of TR_PLAINTEXT_PREFERRED, - * TR_ENCRYPTION_PREFERRED, or TR_ENCRYPTION_REQUIRED. - * @param isUploadLimitEnabled If true, libtransmission will limit the entire - * session's upload speed from `uploadLimit'. - * @param uploadLimit The speed limit to use for the entire session when - * isUploadLimitEnabled is true. - * @param isDownloadLimitEnabled If true, libtransmission will limit the entire - * session's download speed from `downloadLimit'. - * @param downloadLimit The speed limit to use for the entire session when - * isDownloadLimitEnabled is true. - * @param peerLimit The maximum number of peer connections allowed in a session. - * TR_DEFAULT_GLOBAL_PEER_LIMIT can be used as a default. + * @param configDir + * The config directory where libtransmission config subdirectories + * will be found, such as "torrents", "resume", and "blocklists". + * #TR_DEFAULT_CONFIG_DIR can be used as a default. + * + * @param downloadDir + * The default directory to save added torrents. + * This can be changed per-session with + * tr_sessionSetDownloadDir() and per-torrent with + * tr_ctorSetDownloadDir(). + * + * @param tag + * Obsolete. Only used now for locating legacy fastresume files. + * This will be removed at some point in the future. + * Valid tags: beos cli daemon gtk macos wx + * + * @param isPexEnabled + * whether or not PEX is allowed for non-private torrents. + * This can be changed per-session with + * tr_sessionSetPexEnabled(). + * #TR_DEFAULT_PEX_ENABLED is the default. + * + * @param isPortForwardingEnabled + * If true, libtransmission will attempt + * to find a local UPnP-enabled or NATPMP-enabled + * router and forward a port from there to the local + * machine. This is so remote peers can initiate + * connections with us. + * #TR_DEFAULT_PORT_FORWARDING_ENABLED is the default. + * + * @param publicPort + * Port number to open for incoming peer connections. + * #TR_DEFAULT_PORT is the default. + * + * @param encryptionMode + * Must be one of #TR_PLAINTEXT_PREFERRED, + * #TR_ENCRYPTION_PREFERRED, or #TR_ENCRYPTION_REQUIRED. + * + * @param isUploadLimitEnabled + * If true, libtransmission will limit the entire + * session's upload speed from "uploadLimit". + * + * @param uploadLimit + * The speed limit to use for the entire session when + * "isUploadLimitEnabled" is true. + * + * @param isDownloadLimitEnabled + * If true, libtransmission will limit the entire + * session's download speed from "downloadLimit". + * + * @param downloadLimit + * The speed limit to use for the entire session when + * "isDownloadLimitEnabled" is true. + * + * @param peerLimit + * The maximum number of peer connections allowed in a session. + * #TR_DEFAULT_GLOBAL_PEER_LIMIT can be used as a default. + * + * @param messageLevel + * Verbosity level of libtransmission's logging mechanism. + * Must be one of #TR_MSG_ERR, #TR_MSG_INF, #TR_MSG_DBG. + * + * @param isMessageQueueingEnabled + * If true, then messages will build up in a queue until + * processed by the client application. + * + * @param isBlocklistEnabled + * If true, then Transmission will not allow peer connections + * to the IP addressess specified in the blocklist. + * + * @param peerSocketTOS + * + * @param rpcIsEnabled + * If true, then libtransmission will open an http server port + * to listen for incoming RPC requests. + * + * @param rpcPort + * The port on which to listen for incoming RPC requests + * + * @param rpcACL + * The access control list for allowing/denying RPC requests + * from specific IP ranges. + * @see tr_sessionSetRPCACL() * * @see TR_DEFAULT_PEER_SOCKET_TOS * @see TR_DEFAULT_BLOCKLIST_ENABLED * @see TR_DEFAULT_RPC_ENABLED * @see TR_DEFAULT_RPC_PORT * @see TR_DEFAULT_RPC_ACL + * @see tr_sessionClose() */ tr_handle * tr_sessionInitFull( const char * configDir, const char * downloadDir, @@ -146,17 +222,20 @@ tr_handle * tr_sessionInitFull( const char * configDir, int peerSocketTOS, int rpcIsEnabled, int rpcPort, - const char * rpcACL ); + const char * rpcAccessControlList ); /** - * Like tr_sessionInitFull() but with default values supplied. + * @brief shorter form of tr_sessionInitFull() + * + * @deprecated Use tr_sessionInitFull() instead. */ tr_handle * tr_sessionInit( const char * configDir, const char * downloadDir, const char * tag ); /** - * Shut down a libtransmission instance created by tr_sessionInit*() + * @brief end a libtransmission session + * @see tr_sessionInitFull() */ void tr_sessionClose( tr_handle * ); @@ -170,18 +249,43 @@ const char * tr_sessionGetConfigDir( const tr_handle * ); /** * Set the per-session default download folder for new torrents. * @see tr_sessionInitFull() + * @see tr_sessionGetDownloadDir() * @see tr_ctorSetDownloadDir() */ void tr_sessionSetDownloadDir( tr_handle *, const char * downloadDir ); +/** + * Get the default download folder for new torrents. + * + * This is set by tr_sessionInitFull() or tr_sessionSetDownloadDir(), + * and can be overridden on a per-torrent basis by tr_ctorSetDownloadDir(). + */ const char * tr_sessionGetDownloadDir( const tr_handle * ); +/** + * @brief Set whether or not RPC calls are allowed in this session. + * + * @details If true, libtransmission will open a server socket to listen + * for incoming http RPC requests as described in docs/rpc-spec.txt. + * + * This is intially set by tr_sessionInitFull() and can be + * queried by tr_sessionIsRPCEnabled(). + */ void tr_sessionSetRPCEnabled( tr_handle *, int isEnabled ); +/** @brief Get whether or not RPC calls are allowed in this session. + @see tr_sessionInitFull() + @see tr_sessionSetRPCEnabled() */ int tr_sessionIsRPCEnabled( const tr_handle * handle ); +/** @brief Specify which port to listen for RPC requests on. + @see tr_sessionInitFull() + @see tr_sessionGetRPCPort */ void tr_sessionSetRPCPort( tr_handle *, int port ); +/** @brief Get which port to listen for RPC requests on. + @see tr_sessionInitFull() + @see tr_sessionSetRPCPort */ int tr_sessionGetRPCPort( const tr_handle * ); /** @@ -197,9 +301,15 @@ int tr_sessionGetRPCPort( const tr_handle * ); * Client applications need to validate user input, or better yet * generate it from a higher-level interface that doesn't allow user error, * before calling this function. + * + * @see tr_sessionInitFull + * @see tr_sessionGetRPCACL */ void tr_sessionSetRPCACL( tr_handle *, const char * acl ); +/** Returns the Access Control List for allowing/denying RPC requests. + @see tr_sessionInitFull + @see tr_sessionSetRPCACL */ const char* tr_sessionGetRPCACL( const tr_handle * ); typedef enum @@ -231,9 +341,9 @@ void tr_sessionSetRPCCallback( tr_handle * handle, typedef struct tr_session_stats { + float ratio; /* TR_RATIO_INF, TR_RATIO_NA, or total up/down */ uint64_t uploadedBytes; /* total up */ uint64_t downloadedBytes; /* total down */ - double ratio; /* TR_RATIO_INF, TR_RATIO_NA, or total up/down */ uint64_t filesAdded; /* number of files added */ uint64_t sessionCount; /* program started N times */ uint64_t secondsActive; /* how long Transmisson's been running */