(trunk) #1950: Add off-peak hour bandwidth limiting to libtransmission, rpc

This commit is contained in:
Charles Kerr 2009-03-25 19:18:00 +00:00
parent 5df2570fdf
commit b1fc4ed8c4
12 changed files with 376 additions and 157 deletions

View File

@ -416,7 +416,7 @@ readargs( int argc,
case 'p':
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddInt( args, "port", numarg( optarg ) );
tr_bencDictAddInt( args, TR_PREFS_KEY_PEER_PORT, numarg( optarg ) );
break;
case 'r':
@ -469,19 +469,19 @@ readargs( int argc,
case 'w': {
char * path = absolutify( optarg );
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddStr( args, "download-dir", path );
tr_bencDictAddStr( args, TR_PREFS_KEY_DOWNLOAD_DIR, path );
tr_free( path );
break;
}
case 'x':
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddInt( args, "pex-allowed", 1 );
tr_bencDictAddInt( args, TR_PREFS_KEY_PEX_ENABLED, 1 );
break;
case 'X':
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddInt( args, "pex-allowed", 0 );
tr_bencDictAddInt( args, TR_PREFS_KEY_PEX_ENABLED, 0 );
break;
case 900:
@ -504,17 +504,17 @@ readargs( int argc,
case 910:
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddStr( args, "encryption", "required" );
tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "required" );
break;
case 911:
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddStr( args, "encryption", "preferred" );
tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "preferred" );
break;
case 912:
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddStr( args, "encryption", "tolerated" );
tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "tolerated" );
break;
case 920:
@ -530,7 +530,7 @@ readargs( int argc,
case 931:
tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddInt( args, "peer-limit", atoi(optarg) );
tr_bencDictAddInt( args, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi(optarg) );
break;
case 940:
@ -811,7 +811,7 @@ printSession( tr_benc * top )
printf( "\n" );
printf( "LIMITS\n" );
if( tr_bencDictFindInt( args, "peer-limit", &i ) )
if( tr_bencDictFindInt( args, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i ) )
printf( " Peer limit: %" PRId64 "\n", i );
if( tr_bencDictFindInt( args, "speed-limit-down-enabled", &i ) )
printf( " Downloadlimit enabled: %s\n", ( i ? "Yes" : "No" ) );

View File

@ -336,11 +336,18 @@
string | value type & description
---------------------------+-------------------------------------------------
"alt-speed-limit-enabled" | 'boolean' true means enabled
"alt-speed-limit-up" | number max global upload speed (in K/s)
"alt-speed-limit-down" | number max global download speed (in K/s)
"alt-speed-limit-begin" | number minutes after midnight. (ex: 60 means starting at 1 am)
"alt-speed-limit-end" | number minutes after midnight. (ex: 300 means ending at 5 am)
"blocklist-enabled" | 'boolean' true means enabled
"encryption" | string "required", "preferred", "tolerated"
"download-dir" | string default path to download torrents
"peer-limit" | number maximum global number of peers
"pex-allowed" | 'boolean' true means allow pex in public torrents
"port" | number port number
"peer-limit-global" | number maximum global number of peers
"peer-limit-per-torrent" | number maximum global number of peers
"pex-enabled" | 'boolean' true means allow pex in public torrents
"peer-port" | number port number
"port-forwarding-enabled" | 'boolean' true means enabled
"speed-limit-down" | number max global download speed (in K/s)
"speed-limit-down-enabled" | 'boolean' true means enabled
@ -435,10 +442,20 @@
| | yes | torrent-get | new arg "speed-limit-up-enabled"
| | yes | torrent-get | new arg "speed-limit-up-global-enabled"
| | yes | torrent-get | new ids option "recently-active"
| | yes | session-get | new arg "alt-speed-limit-enabled"
| | yes | session-get | new arg "alt-speed-limit-up"
| | yes | session-get | new arg "alt-speed-limit-down"
| | yes | session-get | new arg "alt-speed-limit-begin"
| | yes | session-get | new arg "alt-speed-limit-end"
| | yes | session-get | new arg "blocklist-enabled"
| | yes | session-get | new arg "peer-limit-per-torrent"
| | NO | torrent-get | removed arg "downloadLimit"
| | NO | torrent-get | removed arg "downloadLimitMode"
| | NO | torrent-get | removed arg "uploadLimit"
| | NO | torrent-get | removed arg "uploadLimitMode"
| | NO | session-get | renamed "pex-allowed" to "pex-enabled"
| | NO | session-get | renamed "port" to "peer-port"
| | NO | session-get | renamed "peer-limit" to "peer-limit-global"
------+---------+-----------+----------------+-------------------------------

View File

@ -178,12 +178,6 @@ tr_prefs_init_defaults( tr_benc * d )
tr_bencDictAddInt( d, PREF_KEY_SHOW_DESKTOP_NOTIFICATION, TRUE );
tr_bencDictAddStr( d, PREF_KEY_STATUSBAR_STATS, "total-ratio" );
tr_bencDictAddInt( d, PREF_KEY_SCHED_LIMIT_ENABLED, FALSE );
tr_bencDictAddInt( d, PREF_KEY_SCHED_BEGIN, 60 * 23 ); /* 11pm */
tr_bencDictAddInt( d, PREF_KEY_SCHED_END, 60 * 7 ); /* 7am */
tr_bencDictAddInt( d, PREF_KEY_SCHED_DL_LIMIT, 200 ); /* 2x the other limit */
tr_bencDictAddInt( d, PREF_KEY_SCHED_UL_LIMIT, 100 ); /* 2x the other limit */
tr_bencDictAddInt( d, PREF_KEY_OPTIONS_PROMPT, TRUE );
tr_bencDictAddInt( d, PREF_KEY_MAIN_WINDOW_HEIGHT, 500 );

View File

@ -459,96 +459,6 @@ main( int argc,
return 0;
}
static gboolean
updateScheduledLimits( gpointer data )
{
tr_session * tr = data;
static gboolean last_state = FALSE;
gboolean in_sched_state = FALSE;
if( !pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ) )
{
in_sched_state = FALSE;
}
else
{
const int begin_time = pref_int_get( PREF_KEY_SCHED_BEGIN );
const int end_time = pref_int_get( PREF_KEY_SCHED_END );
time_t t;
struct tm *tm;
int cur_time;
time( &t );
tm = localtime ( &t );
cur_time = ( tm->tm_hour * 60 ) + tm->tm_min;
if( end_time >= begin_time )
{
if( ( cur_time >= begin_time ) && ( cur_time <= end_time ) )
in_sched_state = TRUE;
}
else
{
if( ( cur_time >= begin_time ) || ( cur_time <= end_time ) )
in_sched_state = TRUE;
}
}
if( last_state != in_sched_state )
{
if( in_sched_state )
{
int limit;
tr_inf ( _( "Beginning to use scheduled bandwidth limits" ) );
tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, TRUE );
limit = pref_int_get( PREF_KEY_SCHED_DL_LIMIT );
tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
tr_sessionSetSpeedLimitEnabled( tr, TR_UP, TRUE );
limit = pref_int_get( PREF_KEY_SCHED_UL_LIMIT );
tr_sessionSetSpeedLimit( tr, TR_UP, limit );
}
else
{
gboolean b;
int limit;
tr_inf ( _( "Ending use of scheduled bandwidth limits" ) );
b = pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED );
tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b );
limit = pref_int_get( TR_PREFS_KEY_DSPEED );
tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
b = pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED );
tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b );
limit = pref_int_get( TR_PREFS_KEY_USPEED );
tr_sessionSetSpeedLimit( tr, TR_UP, limit );
}
last_state = in_sched_state;
}
else if( in_sched_state )
{
static int old_dl_limit = 0, old_ul_limit = 0;
int dl_limit = pref_int_get( PREF_KEY_SCHED_DL_LIMIT );
int ul_limit = pref_int_get( PREF_KEY_SCHED_UL_LIMIT );
if( ( dl_limit != old_dl_limit ) || ( ul_limit != old_ul_limit ) )
{
tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, TRUE );
tr_sessionSetSpeedLimit( tr, TR_DOWN, dl_limit );
tr_sessionSetSpeedLimitEnabled( tr, TR_UP, TRUE );
tr_sessionSetSpeedLimit( tr, TR_UP, ul_limit );
old_dl_limit = dl_limit;
old_ul_limit = ul_limit;
}
}
return TRUE;
}
static void
appsetup( TrWindow * wind,
GSList * torrentFiles,
@ -601,10 +511,6 @@ appsetup( TrWindow * wind,
cbdata->timer = gtr_timeout_add_seconds( REFRESH_INTERVAL_SECONDS, updatemodel, cbdata );
updatemodel( cbdata );
/* start scheduled rate timer */
updateScheduledLimits ( tr_core_session( cbdata->core ) );
gtr_timeout_add_seconds( 60, updateScheduledLimits, tr_core_session( cbdata->core ) );
/* either show the window or iconify it */
if( !isIconified )
gtk_widget_show( GTK_WIDGET( wind ) );
@ -1087,10 +993,6 @@ prefschanged( TrCore * core UNUSED,
const double limit = pref_double_get( key );
tr_sessionSetRatioLimit( tr, limit );
}
else if( !strncmp( key, "sched-", 6 ) )
{
updateScheduledLimits( tr );
}
else if( !strcmp( key, TR_PREFS_KEY_PORT_FORWARDING ) )
{
tr_sessionSetPortForwardingEnabled( tr, pref_flag_get( key ) );
@ -1170,6 +1072,31 @@ prefschanged( TrCore * core UNUSED,
const char * s = pref_string_get( key );
tr_sessionSetProxyPassword( tr, s );
}
else if( !strcmp( key, TR_PREFS_KEY_ALT_LIMIT_ENABLED ) )
{
const gboolean enabled = pref_flag_get( key );
tr_sessionSetAltSpeedLimitEnabled( tr, enabled );
}
else if( !strcmp( key, TR_PREFS_KEY_ALT_BEGIN ) )
{
const int minutes = pref_int_get( key );
tr_sessionSetAltSpeedLimitBegin( tr, minutes );
}
else if( !strcmp( key, TR_PREFS_KEY_ALT_DL_LIMIT ) )
{
const int speed = pref_int_get( key );
tr_sessionSetAltSpeedLimit( tr, TR_DOWN, speed );
}
else if( !strcmp( key, TR_PREFS_KEY_ALT_END ) )
{
const int minutes = pref_int_get( key );
tr_sessionSetAltSpeedLimitEnd( tr, minutes );
}
else if( !strcmp( key, TR_PREFS_KEY_ALT_UL_LIMIT ) )
{
const int speed = pref_int_get( key );
tr_sessionSetAltSpeedLimit( tr, TR_UP, speed );
}
}
static gboolean

View File

@ -990,8 +990,7 @@ static void
refreshSchedSensitivity( struct BandwidthPage * p )
{
GSList * l;
const gboolean sched_enabled = pref_flag_get(
PREF_KEY_SCHED_LIMIT_ENABLED );
const gboolean sched_enabled = pref_flag_get( TR_PREFS_KEY_ALT_LIMIT_ENABLED );
for( l = p->sched_widgets; l != NULL; l = l->next )
gtk_widget_set_sensitive( GTK_WIDGET( l->data ), sched_enabled );
@ -1111,27 +1110,27 @@ bandwidthPage( GObject * core )
hig_workarea_add_section_title( t, &row, _( "Scheduled Limits" ) );
h = gtk_hbox_new( FALSE, 0 );
w2 = new_time_combo( core, PREF_KEY_SCHED_BEGIN );
w2 = new_time_combo( core, TR_PREFS_KEY_ALT_BEGIN );
page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
w2 = gtk_label_new ( _( " and " ) );
page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
w2 = new_time_combo( core, PREF_KEY_SCHED_END );
w2 = new_time_combo( core, TR_PREFS_KEY_ALT_END );
page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
s = _( "_Limit bandwidth between" );
w = new_check_button( s, PREF_KEY_SCHED_LIMIT_ENABLED, core );
w = new_check_button( s, TR_PREFS_KEY_ALT_LIMIT_ENABLED, core );
g_signal_connect( w, "toggled", G_CALLBACK( onSchedToggled ), page );
hig_workarea_add_row_w( t, &row, w, h, NULL );
w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 );
w = new_spin_button( TR_PREFS_KEY_ALT_DL_LIMIT, core, 0, INT_MAX, 5 );
page->sched_widgets = g_slist_append( page->sched_widgets, w );
l = hig_workarea_add_row( t, &row, _( "Limit d_ownload speed (KB/s):" ), w, NULL );
page->sched_widgets = g_slist_append( page->sched_widgets, l );
w = new_spin_button( PREF_KEY_SCHED_UL_LIMIT, core, 0, INT_MAX, 5 );
w = new_spin_button( TR_PREFS_KEY_ALT_UL_LIMIT, core, 0, INT_MAX, 5 );
page->sched_widgets = g_slist_append( page->sched_widgets, w );
l = hig_workarea_add_row( t, &row, _( "Limit u_pload speed (KB/s):" ), w, NULL );
page->sched_widgets = g_slist_append( page->sched_widgets, l );

View File

@ -21,11 +21,6 @@ GtkWidget * tr_prefs_dialog_new( GObject * core,
/* if you add a key here, you /must/ add its
* default in tr_prefs_init_defaults( void ) */
#define PREF_KEY_SCHED_LIMIT_ENABLED "sched-limit-enabled"
#define PREF_KEY_SCHED_BEGIN "sched-begin"
#define PREF_KEY_SCHED_END "sched-end"
#define PREF_KEY_SCHED_DL_LIMIT "sched-download-limit"
#define PREF_KEY_SCHED_UL_LIMIT "sched-upload-limit"
#define PREF_KEY_OPTIONS_PROMPT "show-options-window"
#define PREF_KEY_OPEN_DIALOG_FOLDER "open-dialog-dir"
#define PREF_KEY_INHIBIT_HIBERNATION "inhibit-desktop-hibernation"

View File

@ -842,15 +842,29 @@ sessionSet( tr_session * session,
assert( idle_data == NULL );
if( tr_bencDictFindStr( args_in, "download-dir", &str ) )
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i ) )
tr_sessionSetAltSpeedLimitEnabled( session, i!=0 );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_BEGIN, &i ) )
tr_sessionSetAltSpeedLimitBegin( session, i );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_END, &i ) )
tr_sessionSetAltSpeedLimitEnd( session, i );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_DL_LIMIT, &i ) )
tr_sessionSetAltSpeedLimit( session, TR_DOWN, i );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_UL_LIMIT, &i ) )
tr_sessionSetAltSpeedLimit( session, TR_UP, i );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i ) )
tr_blocklistSetEnabled( session, i!=0 );
if( tr_bencDictFindStr( args_in, TR_PREFS_KEY_DOWNLOAD_DIR, &str ) )
tr_sessionSetDownloadDir( session, str );
if( tr_bencDictFindInt( args_in, "peer-limit", &i ) )
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i ) )
tr_sessionSetPeerLimit( session, i );
if( tr_bencDictFindInt( args_in, "pex-allowed", &i ) )
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_LIMIT_TORRENT, &i ) )
tr_sessionSetPeerLimitPerTorrent( session, i );
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEX_ENABLED, &i ) )
tr_sessionSetPexEnabled( session, i );
if( tr_bencDictFindInt( args_in, "port", &i ) )
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_PORT, &i ) )
tr_sessionSetPeerPort( session, i );
if( tr_bencDictFindInt( args_in, "port-forwarding-enabled", &i ) )
if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PORT_FORWARDING, &i ) )
tr_sessionSetPortForwardingEnabled( session, i );
if( tr_bencDictFindInt( args_in, "speed-limit-down", &i ) )
tr_sessionSetSpeedLimit( session, TR_DOWN, i );
@ -927,7 +941,7 @@ sessionStats( tr_session * session,
}
static const char*
sessionGet( tr_session * session,
sessionGet( tr_session * s,
tr_benc * args_in UNUSED,
tr_benc * args_out,
struct tr_rpc_idle_data * idle_data )
@ -936,22 +950,28 @@ sessionGet( tr_session * session,
tr_benc * d = args_out;
assert( idle_data == NULL );
tr_bencDictAddStr( d, "download-dir", tr_sessionGetDownloadDir( session ) );
tr_bencDictAddInt( d, "peer-limit", tr_sessionGetPeerLimit( session ) );
tr_bencDictAddInt( d, "pex-allowed", tr_sessionIsPexEnabled( session ) );
tr_bencDictAddInt( d, "port", tr_sessionGetPeerPort( session ) );
tr_bencDictAddInt( d, "port-forwarding-enabled", tr_sessionIsPortForwardingEnabled( session ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, tr_sessionIsAltSpeedLimitEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_UP ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_DOWN ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, tr_sessionGetAltSpeedLimitBegin( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, tr_sessionGetAltSpeedLimitEnd( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_sessionGetDownloadDir( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, tr_sessionGetPeerLimit( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, tr_sessionGetPeerLimitPerTorrent( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, tr_sessionIsPexEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );
tr_bencDictAddInt( d, "rpc-version", 4 );
tr_bencDictAddInt( d, "rpc-version-minimum", 1 );
tr_bencDictAddInt( d, "speed-limit-up", tr_sessionGetSpeedLimit( session, TR_UP ) );
tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimitEnabled( session, TR_UP ) );
tr_bencDictAddInt( d, "speed-limit-down", tr_sessionGetSpeedLimit( session, TR_DOWN ) );
tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimitEnabled( session, TR_DOWN ) );
tr_bencDictAddDouble( d, "ratio-limit", tr_sessionGetRatioLimit( session ) );
tr_bencDictAddInt( d, "ratio-limit-enabled", tr_sessionIsRatioLimited( session ) );
tr_bencDictAddInt( d, "speed-limit-up", tr_sessionGetSpeedLimit( s, TR_UP ) );
tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
tr_bencDictAddInt( d, "speed-limit-down", tr_sessionGetSpeedLimit( s, TR_DOWN ) );
tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
tr_bencDictAddDouble( d, "ratio-limit", tr_sessionGetRatioLimit( s ) );
tr_bencDictAddInt( d, "ratio-limit-enabled", tr_sessionIsRatioLimited( s ) );
tr_bencDictAddStr( d, "version", LONG_VERSION_STRING );
switch( tr_sessionGetEncryption( session ) ) {
switch( tr_sessionGetEncryption( s ) ) {
case TR_CLEAR_PREFERRED: str = "tolerated"; break;
case TR_ENCRYPTION_REQUIRED: str = "required"; break;
default: str = "preferred"; break;

View File

@ -219,7 +219,7 @@ tr_sessionGetDefaultSettings( tr_benc * d )
{
assert( tr_bencIsDict( d ) );
tr_bencDictReserve( d, 30 );
tr_bencDictReserve( d, 35 );
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, FALSE );
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_getDefaultDownloadDir( ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, 100 );
@ -254,6 +254,11 @@ tr_sessionGetDefaultSettings( tr_benc * d )
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, TRUE );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, atoi( TR_DEFAULT_RPC_PORT_STR ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, FALSE );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, 1320 ); /* 10pm */
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, 300 ); /* 5am */
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, 200 ); /* double the regular default */
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, 200 ); /* double the regular default */
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, 100 );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 );
tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 );
@ -302,6 +307,11 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, freeme[n++] = tr_sessionGetRPCUsername( s ) );
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, freeme[n++] = tr_sessionGetRPCWhitelist( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, tr_sessionGetRPCWhitelistEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, tr_sessionIsAltSpeedLimitEnabled( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, tr_sessionGetAltSpeedLimitBegin( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, tr_sessionGetAltSpeedLimitEnd( s ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_DOWN ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_UP ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );
@ -369,6 +379,7 @@ tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc *
static void metainfoLookupRescan( tr_session * );
static void tr_sessionInitImpl( void * );
static int onBandwidthTimer( void * );
struct init_data
{
@ -573,6 +584,25 @@ tr_sessionInitImpl( void * vdata )
tr_sessionSetRatioLimit( session, d );
tr_sessionSetRatioLimited( session, j );
/**
*** Alternate speed limits for off-peak hours
**/
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i );
assert( found );
session->isAltSpeedLimited = i != 0;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_BEGIN, &i )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_END, &j );
assert( found );
session->altSpeedBeginTime = i;
session->altSpeedEndTime = j;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_DL_LIMIT, &i )
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_UL_LIMIT, &j );
assert( found );
session->altSpeedLimit[TR_DOWN] = i;
session->altSpeedLimit[TR_UP] = j;
/* initialize the blocklist */
filename = tr_buildPath( session->configDir, "blocklists", NULL );
tr_mkdirp( filename, 0777 );
@ -588,6 +618,8 @@ tr_sessionInitImpl( void * vdata )
assert( tr_isSession( session ) );
session->bandwidthTimer = tr_timerNew( session, onBandwidthTimer, session, 60000 );
/* first %s is the application name
second %s is the version number */
tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
@ -776,18 +808,79 @@ tr_sessionGetRatioLimit( const tr_session * session )
****
***/
static tr_bool
isAltTime( const tr_session * session )
{
const time_t now = time( NULL );
struct tm tm;
int minutes;
tr_localtime_r( &now, &tm );
minutes = tm.tm_hour*60 + tm.tm_min;
if( session->altSpeedBeginTime <= session->altSpeedEndTime )
{
return ( session->altSpeedBeginTime <= minutes )
&& ( minutes < session->altSpeedEndTime );
}
else /* goes past midnight */
{
return ( minutes >= session->altSpeedBeginTime )
|| ( minutes < session->altSpeedEndTime );
}
}
static int
getActiveSpeedLimit( const tr_session * session, tr_direction dir )
{
int val;
if( tr_sessionIsAltSpeedLimitEnabled( session ) && session->isAltTime )
val = tr_sessionGetAltSpeedLimit( session, dir );
else if( tr_sessionIsSpeedLimitEnabled( session, dir ) )
val = tr_sessionGetSpeedLimit( session, dir );
else
val = -1;
return val;
}
static void
updateBandwidth( tr_session * session, tr_direction dir )
{
tr_bool zeroCase;
const int limit = getActiveSpeedLimit( session, dir );
const tr_bool isLimited = limit >= 0;
const tr_bool zeroCase = isLimited && !limit;
tr_bandwidthSetLimited( session->bandwidth, dir, isLimited && !zeroCase );
tr_bandwidthSetDesiredSpeed( session->bandwidth, dir, limit );
}
/* this is called once a minute to:
* (1) update session->isAltTime
* (2) alter the speed limits when the alt limits go on and off */
static int
onBandwidthTimer( void * vsession )
{
tr_session * session = vsession;
tr_bool wasAltTime;
assert( tr_isSession( session ) );
zeroCase = session->speedLimit[dir] < 1 && session->isSpeedLimited[dir];
wasAltTime = session->isAltTime;
session->isAltTime = isAltTime( session );
tr_bandwidthSetLimited( session->bandwidth, dir, session->isSpeedLimited[dir] && !zeroCase );
if( tr_sessionIsAltSpeedLimitEnabled( session ) && ( wasAltTime != session->isAltTime ) )
{
updateBandwidth( session, TR_UP );
updateBandwidth( session, TR_DOWN );
tr_bandwidthSetDesiredSpeed( session->bandwidth, dir, session->speedLimit[dir] );
if( session->altCallback != NULL )
(*session->altCallback)( session, session->isAltTime, session->altCallbackUserData );
}
return TRUE; /* invoke again when another minute's passed */
}
void
@ -832,6 +925,107 @@ tr_sessionGetSpeedLimit( const tr_session * session, tr_direction dir )
return session->speedLimit[dir];
}
tr_bool
tr_sessionIsAltSpeedLimitTime( const tr_session * session )
{
assert( tr_isSession( session ) );
return session->isAltTime;
}
void
tr_sessionSetAltSpeedLimitEnabled( tr_session * session,
tr_bool isEnabled )
{
assert( tr_isSession( session ) );
assert( tr_isBool( isEnabled ) );
session->isAltSpeedLimited = isEnabled;
onBandwidthTimer( session );
}
tr_bool
tr_sessionIsAltSpeedLimitEnabled( const tr_session * session )
{
assert( tr_isSession( session ) );
return session->isAltSpeedLimited;
}
void
tr_sessionSetAltSpeedLimit( tr_session * session,
tr_direction dir,
int desiredSpeed )
{
assert( tr_isSession( session ) );
assert( tr_isDirection( dir ) );
assert( desiredSpeed >= 0 );
session->altSpeedLimit[dir] = desiredSpeed;
updateBandwidth( session, dir );
}
int
tr_sessionGetAltSpeedLimit( const tr_session * session,
tr_direction dir )
{
assert( tr_isSession( session ) );
assert( tr_isDirection( dir ) );
return session->altSpeedLimit[dir];
}
void
tr_sessionSetAltSpeedLimitBegin( tr_session * session, int minutesSinceMidnight )
{
assert( tr_isSession( session ) );
session->altSpeedBeginTime = minutesSinceMidnight;
}
int
tr_sessionGetAltSpeedLimitBegin( const tr_session * session )
{
assert( tr_isSession( session ) );
return session->altSpeedBeginTime;
}
void
tr_sessionSetAltSpeedLimitEnd( tr_session * session, int minutesSinceMidnight )
{
assert( tr_isSession( session ) );
session->altSpeedEndTime = minutesSinceMidnight;
}
int
tr_sessionGetAltSpeedLimitEnd( const tr_session * session )
{
assert( tr_isSession( session ) );
return session->altSpeedEndTime;
}
void
tr_sessionSetAltSpeedCallback( tr_session * session,
tr_alt_speed_func func,
void * userData )
{
assert( tr_isSession( session ) );
session->altCallback = func;
session->altCallbackUserData = userData;
}
void
tr_sessionClearAltSpeedCallback( tr_session * session )
{
tr_sessionSetAltSpeedCallback( session, NULL, NULL );
}
/***
****
***/
@ -914,6 +1108,7 @@ tr_closeAllConnections( void * vsession )
assert( tr_isSession( session ) );
tr_timerFree( &session->bandwidthTimer );
tr_statsClose( session );
tr_sharedShuttingDown( session->shared );
tr_rpcClose( &session->rpcServer );

View File

@ -70,6 +70,15 @@ struct tr_session
tr_bool isSpeedLimited[2];
int speedLimit[2];
tr_bool isAltSpeedLimited;
int altSpeedBeginTime;
int altSpeedEndTime;
int altSpeedLimit[2];
tr_bool isAltTime;
tr_alt_speed_func * altCallback;
void * altCallbackUserData;
int magicNumber;
tr_encryption_mode encryptionMode;
@ -122,6 +131,8 @@ struct tr_session
struct tr_metainfo_lookup * metainfoLookup;
int metainfoLookupCount;
struct tr_timer * bandwidthTimer;
/* the size of the output buffer for peer connections */
int so_sndbuf;

View File

@ -151,6 +151,11 @@ static TR_INLINE tr_bool tr_isEncryptionMode( tr_encryption_mode m )
#define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "240"
#define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "60"
#define TR_PREFS_KEY_ALT_LIMIT_ENABLED "alt-speed-limit-enabled"
#define TR_PREFS_KEY_ALT_BEGIN "alt-speed-limit-begin"
#define TR_PREFS_KEY_ALT_DL_LIMIT "alt-speed-limit-down"
#define TR_PREFS_KEY_ALT_END "alt-speed-limit-end"
#define TR_PREFS_KEY_ALT_UL_LIMIT "alt-speed-limit-up"
#define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled"
#define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir"
#define TR_PREFS_KEY_DSPEED "download-limit"
@ -230,9 +235,9 @@ void tr_sessionGetSettings( tr_session *, struct tr_benc * dictionary );
*
* FIXME: this belongs in libtransmissionapp
*
* @param dictionary pointer to an uninitialized tr_benc
* @param configDir the configuration directory to find settings.json
* @param initme pointer to an uninitialized tr_benc
* @param appName examples: Transmission, transmission-daemon
* @param appName if configDir is empty, appName is used to get the default config dir.
* @see tr_sessionGetDefaultSettings()
* @see tr_sessionInit()
* @see tr_sessionSaveSettings()
@ -548,6 +553,10 @@ typedef enum
}
tr_direction;
/***
****
***/
void tr_sessionSetSpeedLimitEnabled ( tr_session * session,
tr_direction direction,
tr_bool isEnabled );
@ -562,6 +571,58 @@ void tr_sessionSetSpeedLimit ( tr_session * session,
int tr_sessionGetSpeedLimit ( const tr_session * session,
tr_direction direction );
/***
****
***/
typedef void ( tr_alt_speed_func )( tr_session * session,
tr_bool isAltActive,
void * userData );
/**
* Register to be notified whenever the alternate speed limits go on and off.
*
* func is invoked FROM LIBTRANSMISSION'S THREAD!
* This means func must be fast (to avoid blocking peers),
* shouldn't call libtransmission functions (to avoid deadlock),
* and shouldn't modify client-level memory without using a mutex!
*/
void tr_sessionSetAltSpeedCallback( tr_session * session,
tr_alt_speed_func func,
void * userData );
void tr_sessionClearAltSpeedCallback( tr_session * session );
void tr_sessionSetAltSpeedLimitEnabled( tr_session * session,
tr_bool isEnabled );
tr_bool tr_sessionIsAltSpeedLimitEnabled( const tr_session * session );
/** @return true if the current time is between the alt begin and end times */
tr_bool tr_sessionIsAltSpeedLimitTime( const tr_session * session );
void tr_sessionSetAltSpeedLimitBegin( tr_session * session,
int minutesSinceMidnight );
int tr_sessionGetAltSpeedLimitBegin( const tr_session * session );
void tr_sessionSetAltSpeedLimitEnd( tr_session * session,
int minutesSinceMidnight );
int tr_sessionGetAltSpeedLimitEnd( const tr_session * session );
void tr_sessionSetAltSpeedLimit( tr_session * session,
tr_direction direction,
int KiB_sec );
int tr_sessionGetAltSpeedLimit( const tr_session * session,
tr_direction direction );
/***
****
***/
void tr_sessionSetRatioLimited ( tr_session * session,
tr_bool isEnabled );

View File

@ -723,8 +723,8 @@ Transmission.prototype =
var up_limit = prefs[RPC._UpSpeedLimit];
var up_limited = prefs[RPC._UpSpeedLimited];
$('div.download_location input')[0].value = prefs['download-dir'];
$('div.port input')[0].value = prefs['port'];
$('div.download_location input')[0].value = prefs[RPC._DownloadDir];
$('div.port input')[0].value = prefs[RPC._PeerPort];
$('div.auto_start input')[0].checked = prefs[Prefs._AutoStart];
$('input#limit_download')[0].checked = down_limited == 1;
$('input#download_rate')[0].value = down_limit;

View File

@ -17,7 +17,7 @@ RPC._EncryptionRequired = 'required';
RPC._UpSpeedLimit = 'speed-limit-up';
RPC._DownSpeedLimit = 'speed-limit-down';
RPC._DownloadDir = 'download-dir';
RPC._PeerPort = 'port';
RPC._PeerPort = 'peer-port';
RPC._UpSpeedLimited = 'speed-limit-up-enabled';
RPC._DownSpeedLimited = 'speed-limit-down-enabled';