diff --git a/daemon/remote.c b/daemon/remote.c index a09c644b6..f6588f05b 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -81,6 +81,8 @@ static tr_option opts[] = { 'M', "no-portmap", "Disable portmapping", "M", 0, NULL }, { 'n', "auth", "Set authentication info", "n", 1, "" }, { 'N', "netrc", "Set authentication info from a .netrc file", "N", 1, "" }, + { 'o', "dht", "Enable distributed hash tables (DHT)", "o", 0, NULL }, + { 'O', "no-dht", "Disable distributed hash tables (DHT)", "O", 0, NULL }, { 'p', "port", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "p", 1, "" }, { 'P', "random-port", "Random port for incomping peers", "P", 0, NULL }, { 900, "priority-high", "Set the files' priorities as high", "ph", 1, "" }, @@ -495,6 +497,16 @@ readargs( int argc, break; } + case 'o': + tr_bencDictAddStr( &top, "method", "session-set" ); + tr_bencDictAddBool( args, TR_PREFS_KEY_DHT_ENABLED, TRUE ); + break; + + case 'O': + tr_bencDictAddStr( &top, "method", "session-set" ); + tr_bencDictAddBool( args, TR_PREFS_KEY_DHT_ENABLED, FALSE ); + break; + case 'x': tr_bencDictAddStr( &top, "method", "session-set" ); tr_bencDictAddBool( args, TR_PREFS_KEY_PEX_ENABLED, TRUE ); diff --git a/daemon/transmission-remote.1 b/daemon/transmission-remote.1 index 59aa0b104..68dec7233 100644 --- a/daemon/transmission-remote.1 +++ b/daemon/transmission-remote.1 @@ -27,6 +27,7 @@ and .Op Fl m | M .Op Fl n Ar user:pass .Op Fl N Ar netrc +.Op Fl o | O .Op Fl p Ar port .Op Fl ph Ar files .Op Fl pl Ar files @@ -134,6 +135,11 @@ Set the authentication information from a .Ar netrc file. See netrc(5) for more information. +.It Fl o Fl -dht +Enable distributed hash table (DHT). +.It Fl O Fl -no-dht +Disable distribued hash table (DHT). + .It Fl p Fl -port Ar port Set the .Ar port diff --git a/doc/rpc-spec.txt b/doc/rpc-spec.txt index 3c1702898..828d24756 100644 --- a/doc/rpc-spec.txt +++ b/doc/rpc-spec.txt @@ -374,6 +374,7 @@ "alt-speed-up" | number max global upload speed (in K/s) "blocklist-enabled" | boolean true means enabled "blocklist-size" | number number of rules in the blocklist + "dht-enabled" | boolean true means allow dht in public torrents "encryption" | string "required", "preferred", "tolerated" "download-dir" | string default path to download torrents "peer-limit-global" | number maximum global number of peers diff --git a/gtk/main.c b/gtk/main.c index afa730b28..80b825dc0 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1009,6 +1009,10 @@ prefschanged( TrCore * core UNUSED, { tr_sessionSetPexEnabled( tr, pref_flag_get( key ) ); } + else if( !strcmp( key, TR_PREFS_KEY_DHT_ENABLED ) ) + { + tr_sessionSetDHTEnabled( tr, pref_flag_get( key ) ); + } else if( !strcmp( key, TR_PREFS_KEY_RPC_PORT ) ) { tr_sessionSetRPCPort( tr, pref_int_get( key ) ); diff --git a/gtk/relocate.c b/gtk/relocate.c index 261aa1ef6..8fe5cdde9 100644 --- a/gtk/relocate.c +++ b/gtk/relocate.c @@ -25,7 +25,7 @@ static char * previousLocation = NULL; struct UpdateData { GtkDialog * dialog; - tr_bool done; + int done; }; /* every once in awhile, check to see if the move is done. diff --git a/gtk/tr-prefs.c b/gtk/tr-prefs.c index 01a8fcf61..081069e1a 100644 --- a/gtk/tr-prefs.c +++ b/gtk/tr-prefs.c @@ -538,10 +538,14 @@ peerPage( GObject * core ) w = new_encryption_combo( core, "encryption" ); hig_workarea_add_row( t, &row, s, w, NULL ); - s = _( "Use peer e_xchange" ); + s = _( "Use peer e_xchange (PEX)" ); w = new_check_button( s, TR_PREFS_KEY_PEX_ENABLED, core ); hig_workarea_add_wide_control( t, &row, w ); + s = _( "Use _distributed hash table (DHT)" ); + w = new_check_button( s, TR_PREFS_KEY_DHT_ENABLED, core ); + hig_workarea_add_wide_control( t, &row, w ); + hig_workarea_finish( t, &row ); g_object_weak_ref( G_OBJECT( t ), peerPageDestroyed, data ); return t; diff --git a/libtransmission/rpcimpl.c b/libtransmission/rpcimpl.c index 4ce251a01..2cb839f08 100644 --- a/libtransmission/rpcimpl.c +++ b/libtransmission/rpcimpl.c @@ -1136,6 +1136,8 @@ sessionSet( tr_session * session, tr_sessionSetPeerLimitPerTorrent( session, i ); if( tr_bencDictFindBool( args_in, TR_PREFS_KEY_PEX_ENABLED, &boolVal ) ) tr_sessionSetPexEnabled( session, boolVal ); + if( tr_bencDictFindBool( args_in, TR_PREFS_KEY_DHT_ENABLED, &boolVal ) ) + tr_sessionSetDHTEnabled( session, boolVal ); if( tr_bencDictFindBool( args_in, TR_PREFS_KEY_PEER_PORT_RANDOM_ON_START, &boolVal ) ) tr_sessionSetPeerPortRandomOnStart( session, boolVal ); if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_PORT, &i ) ) @@ -1238,6 +1240,7 @@ sessionGet( tr_session * 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_bencDictAddBool( d, TR_PREFS_KEY_PEX_ENABLED, tr_sessionIsPexEnabled( s ) ); + tr_bencDictAddBool( d, TR_PREFS_KEY_DHT_ENABLED, tr_sessionIsDHTEnabled( s ) ); tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) ); tr_bencDictAddInt ( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ON_START, tr_sessionGetPeerPortRandomOnStart( s ) ); tr_bencDictAddBool( d, TR_PREFS_KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) ); diff --git a/libtransmission/session.c b/libtransmission/session.c index 174bd4bb4..72dd5def6 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -347,6 +347,7 @@ tr_sessionGetDefaultSettings( tr_benc * d ) tr_bencDictReserve( d, 35 ); tr_bencDictAddBool( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, FALSE ); + tr_bencDictAddBool( d, TR_PREFS_KEY_DHT_ENABLED, TRUE ); tr_bencDictAddStr ( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_getDefaultDownloadDir( ) ); tr_bencDictAddInt ( d, TR_PREFS_KEY_DSPEED, 100 ); tr_bencDictAddBool( d, TR_PREFS_KEY_DSPEED_ENABLED, FALSE ); @@ -403,6 +404,7 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d ) tr_bencDictReserve( d, 30 ); tr_bencDictAddBool( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) ); + tr_bencDictAddBool( d, TR_PREFS_KEY_DHT_ENABLED, s->isDHTEnabled ); tr_bencDictAddStr ( d, TR_PREFS_KEY_DOWNLOAD_DIR, s->downloadDir ); tr_bencDictAddInt ( d, TR_PREFS_KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) ); tr_bencDictAddBool( d, TR_PREFS_KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimited( s, TR_DOWN ) ); @@ -622,7 +624,9 @@ tr_sessionInitImpl( void * vdata ) found = tr_bencDictFindBool( &settings, TR_PREFS_KEY_PEX_ENABLED, &boolVal ); assert( found ); session->isPexEnabled = boolVal; - /* This really ought to be a separate preference. */ + + found = tr_bencDictFindBool( &settings, TR_PREFS_KEY_DHT_ENABLED, &boolVal ); + assert( found ); session->isDHTEnabled = boolVal; found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ENCRYPTION, &i ); @@ -1596,6 +1600,23 @@ tr_sessionIsDHTEnabled( const tr_session * session ) return session->isDHTEnabled; } +void +tr_sessionSetDHTEnabled( tr_session * session, tr_bool enabled ) +{ + assert( tr_isSession( session ) ); + + if( ( enabled!=0 ) != (session->isDHTEnabled!=0) ) + { + if( session->isDHTEnabled ) + tr_dhtUninit( session ); + + session->isDHTEnabled = enabled!=0; + + if( session->isDHTEnabled ) + tr_dhtInit( session ); + } +} + /*** **** ***/ diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index d6dbb301e..a34ace525 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -179,6 +179,7 @@ static TR_INLINE tr_bool tr_isEncryptionMode( tr_encryption_mode m ) #define TR_PREFS_KEY_BIND_ADDRESS_IPV4 "bind-address-ipv4" #define TR_PREFS_KEY_BIND_ADDRESS_IPV6 "bind-address-ipv6" #define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled" +#define TR_PREFS_KEY_DHT_ENABLED "dht-enabled" #define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir" #define TR_PREFS_KEY_ENCRYPTION "encryption" #define TR_PREFS_KEY_LAZY_BITFIELD "lazy-bitfield-enabled" @@ -532,6 +533,8 @@ tr_bool tr_sessionIsPexEnabled( const tr_session * session ); tr_bool tr_sessionIsDHTEnabled( const tr_session * session ); +void tr_sessionSetDHTEnabled( tr_session * session, tr_bool ); + void tr_sessionSetLazyBitfieldEnabled( tr_session * session, tr_bool enabled ); diff --git a/qt/prefs-dialog.cc b/qt/prefs-dialog.cc index 5fac7a651..1d07c4d93 100644 --- a/qt/prefs-dialog.cc +++ b/qt/prefs-dialog.cc @@ -471,7 +471,8 @@ PrefsDialog :: createPeersTab( ) hig->addSectionDivider( ); hig->addSectionTitle( tr( "Privacy" ) ); hig->addRow( tr( "&Encryption mode:" ), box ); - hig->addWideControl( checkBoxNew( tr( "Use peer e&xchange" ), Prefs::PEX_ENABLED ) ); + hig->addWideControl( checkBoxNew( tr( "Use peer e&xchange (PEX)" ), Prefs::PEX_ENABLED ) ); + hig->addWideControl( checkBoxNew( tr( "Use &distributed hash table (DHT)" ), Prefs::PEX_ENABLED ) ); hig->finish( ); updateBlocklistCheckBox( ); diff --git a/qt/prefs.cc b/qt/prefs.cc index d7e0df4e9..6b5137c0e 100644 --- a/qt/prefs.cc +++ b/qt/prefs.cc @@ -87,6 +87,7 @@ Prefs::PrefItem Prefs::myItems[] = { PEER_PORT_RANDOM_HIGH, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, QVariant::Int }, { SOCKET_TOS, TR_PREFS_KEY_PEER_SOCKET_TOS, QVariant::Int }, { PEX_ENABLED, TR_PREFS_KEY_PEX_ENABLED, QVariant::Bool }, + { DHT_ENABLED, TR_PREFS_KEY_DHT_ENABLED, QVariant::Bool }, { PORT_FORWARDING, TR_PREFS_KEY_PORT_FORWARDING, QVariant::Bool }, { PROXY_AUTH_ENABLED, TR_PREFS_KEY_PROXY_AUTH_ENABLED, QVariant::Bool }, { PREALLOCATION, TR_PREFS_KEY_PREALLOCATION, QVariant::Int }, diff --git a/qt/prefs.h b/qt/prefs.h index 4be0b3e30..2f9cd865e 100644 --- a/qt/prefs.h +++ b/qt/prefs.h @@ -91,6 +91,7 @@ class Prefs: public QObject PEER_PORT_RANDOM_HIGH, SOCKET_TOS, PEX_ENABLED, + DHT_ENABLED, PORT_FORWARDING, PROXY_AUTH_ENABLED, PREALLOCATION, diff --git a/qt/session.cc b/qt/session.cc index a66a974d6..ad8fe5ae3 100644 --- a/qt/session.cc +++ b/qt/session.cc @@ -120,6 +120,7 @@ Session :: updatePref( int key ) case Prefs :: ALT_SPEED_LIMIT_TIME_DAY: case Prefs :: BLOCKLIST_ENABLED: case Prefs :: BLOCKLIST_DATE: + case Prefs :: DHT_ENABLED: case Prefs :: DOWNLOAD_DIR: case Prefs :: PEER_LIMIT_GLOBAL: case Prefs :: PEER_LIMIT_TORRENT: