197
static void metainfoLookupRescan( tr_handle * h );
200
tr_sessionInitFull( const char * configDir,
202
const char * downloadDir,
204
int isPortForwardingEnabled,
206
tr_encryption_mode encryptionMode,
210
int useDownloadLimit,
214
int isMessageQueueingEnabled,
215
int isBlocklistEnabled,
219
int rpcWhitelistIsEnabled,
220
const char * rpcWhitelist,
221
int rpcAuthIsEnabled,
222
const char * rpcUsername,
223
const char * rpcPassword,
227
tr_proxy_type proxyType,
228
int proxyAuthIsEnabled,
229
const char * proxyUsername,
230
const char * proxyPassword )
212
#define TR_DEFAULT_ENCRYPTION TR_CLEAR_PREFERRED
214
#define TR_DEFAULT_ENCRYPTION TR_ENCRYPTION_PREFERRED
218
tr_sessionGetDefaultSettings( tr_benc * d )
220
assert( tr_bencIsDict( d ) );
222
tr_bencDictReserve( d, 30 );
223
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, FALSE );
224
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_getDefaultDownloadDir( ) );
225
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, 100 );
226
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 0 );
227
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_DEFAULT_ENCRYPTION );
228
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, TRUE );
229
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, TR_MSG_INF );
230
tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT, atoi( TR_DEFAULT_OPEN_FILE_LIMIT_STR ) );
231
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi( TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ) );
232
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, atoi( TR_DEFAULT_PEER_LIMIT_TORRENT_STR ) );
233
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, atoi( TR_DEFAULT_PEER_PORT_STR ) );
234
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, FALSE );
235
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, 1024 );
236
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, 65535 );
237
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, atoi( TR_DEFAULT_PEER_SOCKET_TOS_STR ) );
238
tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, TRUE );
239
tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, TRUE );
240
tr_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION, TR_PREALLOCATE_SPARSE );
241
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY, "" );
242
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED, FALSE );
243
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED, FALSE );
244
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD, "" );
245
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT, 80 );
246
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE, TR_PROXY_HTTP );
247
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME, "" );
248
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED, FALSE );
249
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED, TRUE );
250
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD, "" );
251
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, "" );
252
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST );
253
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, TRUE );
254
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, atoi( TR_DEFAULT_RPC_PORT_STR ) );
255
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, 100 );
256
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 );
257
tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 );
261
tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
266
assert( tr_bencIsDict( d ) );
268
tr_bencDictReserve( d, 30 );
269
tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) );
270
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, s->downloadDir );
271
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) );
272
tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
273
tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, s->encryptionMode );
274
tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, s->useLazyBitfield );
275
tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, tr_getMessageLevel( ) );
276
tr_bencDictAddInt( d, TR_PREFS_KEY_OPEN_FILE_LIMIT, s->openFileLimit );
277
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, tr_sessionGetPeerLimit( s ) );
278
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, s->peerLimitPerTorrent );
279
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
280
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, s->isPortRandom );
281
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, s->randomPortLow );
282
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, s->randomPortHigh );
283
tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, s->peerSocketTOS );
284
tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, s->isPexEnabled );
285
tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );
286
tr_bencDictAddInt( d, TR_PREFS_KEY_PREALLOCATION, s->preallocationMode );
287
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY, s->proxy );
288
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_AUTH_ENABLED, s->isProxyAuthEnabled );
289
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_ENABLED, s->isProxyEnabled );
290
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_PASSWORD, s->proxyPassword );
291
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_PORT, s->proxyPort );
292
tr_bencDictAddInt( d, TR_PREFS_KEY_PROXY_TYPE, s->proxyType );
293
tr_bencDictAddStr( d, TR_PREFS_KEY_PROXY_USERNAME, s->proxyUsername );
294
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_AUTH_REQUIRED, tr_sessionIsRPCPasswordEnabled( s ) );
295
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_ENABLED, tr_sessionIsRPCEnabled( s ) );
296
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_PASSWORD, freeme[n++] = tr_sessionGetRPCPassword( s ) );
297
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, tr_sessionGetRPCPort( s ) );
298
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, freeme[n++] = tr_sessionGetRPCUsername( s ) );
299
tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, freeme[n++] = tr_sessionGetRPCWhitelist( s ) );
300
tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, tr_sessionGetRPCWhitelistEnabled( s ) );
301
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) );
302
tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
303
tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );
306
tr_free( freeme[i] );
310
tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appName )
313
tr_benc fileSettings;
315
assert( tr_bencIsDict( d ) );
317
/* get the defaults */
318
tr_sessionGetDefaultSettings( d );
320
/* if caller didn't specify a config dir, use the default */
321
if( !configDir || !*configDir )
322
configDir = tr_getDefaultConfigDir( appName );
324
/* file settings override the defaults */
325
filename = tr_buildPath( configDir, "settings.json", NULL );
326
if( !tr_bencLoadJSONFile( filename, &fileSettings ) ) {
327
tr_bencMergeDicts( d, &fileSettings );
328
tr_bencFree( &fileSettings );
336
tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc * settings )
338
tr_benc fileSettings;
341
assert( tr_bencIsDict( settings ) );
343
filename = tr_buildPath( configDir, "settings.json", NULL );
345
tr_sessionGetSettings( session, settings );
347
if( tr_bencLoadJSONFile( filename, &fileSettings ) ) {
348
tr_bencSaveJSONFile( filename, settings );
350
tr_bencMergeDicts( &fileSettings, settings );
351
tr_bencSaveJSONFile( filename, &fileSettings );
352
tr_bencFree( &fileSettings );
355
tr_inf( "Saved \"%s\"", filename );
359
static void metainfoLookupRescan( tr_session * );
360
static void tr_sessionInitImpl( void * );
363
tr_sessionInit( const char * tag,
364
const char * configDir,
365
tr_bool messageQueuingEnabled,
366
tr_benc * clientSettings )
373
tr_session * session;
376
assert( tr_bencIsDict( clientSettings ) );
378
session = tr_new0( tr_session, 1 );
379
session->bandwidth = tr_bandwidthNew( session, NULL );
380
session->lock = tr_lockNew( );
381
session->tag = tr_strdup( tag );
382
session->magicNumber = SESSION_MAGIC_NUMBER;
384
dbgmsg( "tr_sessionInit: the session's top-level bandwidth object is %p", session->bandwidth );
386
tr_bencInitDict( &settings, 0 );
387
tr_sessionGetDefaultSettings( &settings );
388
tr_bencMergeDicts( &settings, clientSettings );
236
391
/* Don't exit when writing on a broken socket */
237
392
signal( SIGPIPE, SIG_IGN );
241
tr_setMessageLevel( messageLevel );
242
tr_setMessageQueuing( isMessageQueueingEnabled );
244
h = tr_new0( tr_handle, 1 );
245
h->lock = tr_lockNew( );
246
h->isPexEnabled = isPexEnabled ? 1 : 0;
247
h->encryptionMode = encryptionMode;
248
h->peerSocketTOS = peerSocketTOS;
249
h->downloadDir = tr_strdup( downloadDir );
250
h->isProxyEnabled = proxyIsEnabled ? 1 : 0;
251
h->proxy = tr_strdup( proxy );
252
h->proxyPort = proxyPort;
253
h->proxyType = proxyType;
254
h->isProxyAuthEnabled = proxyAuthIsEnabled != 0;
255
h->proxyUsername = tr_strdup( proxyUsername );
256
h->proxyPassword = tr_strdup( proxyPassword );
257
h->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */
260
if( configDir == NULL )
261
configDir = tr_getDefaultConfigDir( );
262
tr_setConfigDir( h, configDir );
395
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_TORRENT, &i );
397
session->peerLimitPerTorrent = i;
399
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_MSGLEVEL, &i );
401
tr_setMessageLevel( i );
402
tr_setMessageQueuing( messageQueuingEnabled );
405
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEX_ENABLED, &i );
407
session->isPexEnabled = i != 0;
409
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ENCRYPTION, &i );
411
assert( tr_isEncryptionMode( i ) );
412
session->encryptionMode = i;
414
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PREALLOCATION, &i );
416
assert( tr_isPreallocationMode( i ) );
417
session->preallocationMode = i;
419
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_SOCKET_TOS, &i );
421
session->peerSocketTOS = i;
423
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, &str );
425
session->downloadDir = tr_strdup( str );
427
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_ENABLED, &i );
429
session->isProxyEnabled = i != 0;
431
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY, &str );
433
session->proxy = tr_strdup( str );
435
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_PORT, &i );
437
session->proxyPort = i;
439
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_TYPE, &i );
441
session->proxyType = i;
443
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PROXY_AUTH_ENABLED, &i );
445
session->isProxyAuthEnabled = i != 0;
447
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_USERNAME, &str );
449
session->proxyUsername = tr_strdup( str );
451
found = tr_bencDictFindStr( &settings, TR_PREFS_KEY_PROXY_PASSWORD, &str );
453
session->proxyPassword = tr_strdup( str );
455
session->so_sndbuf = 1500 * 3; /* 3x MTU for most ethernet/wireless */
456
session->so_rcvbuf = 8192;
458
tr_setConfigDir( session, configDir );
264
460
tr_netInit( ); /* must go before tr_eventInit */
270
h->tag = tr_strdup( tag );
271
h->peerMgr = tr_peerMgrNew( h );
273
h->useLazyBitfield = useLazyBitfield != 0;
461
tr_eventInit( session );
462
assert( session->events != NULL );
464
session->peerMgr = tr_peerMgrNew( session );
466
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_LAZY_BITFIELD, &i );
468
session->useLazyBitfield = i != 0;
275
470
/* Initialize rate and file descripts controls */
277
tr_fdInit( globalPeerLimit );
278
h->shared = tr_sharedInit( h, isPortForwardingEnabled, publicPort );
279
h->isPortSet = publicPort >= 0;
281
h->bandwidth = tr_bandwidthNew( h, NULL );
282
tr_sessionSetSpeedLimit ( h, TR_UP, uploadLimit );
283
tr_sessionSetSpeedLimitEnabled( h, TR_UP, useUploadLimit );
284
tr_sessionSetSpeedLimit ( h, TR_DOWN, downloadLimit );
285
tr_sessionSetSpeedLimitEnabled( h, TR_DOWN, useDownloadLimit );
472
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_OPEN_FILE_LIMIT, &i );
474
session->openFileLimit = i;
475
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &j );
477
tr_fdInit( session->openFileLimit, j );
483
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED, &i );
485
session->isPortRandom = i != 0;
487
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, &i );
489
session->randomPortLow = i;
491
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, &i );
493
session->randomPortHigh = i;
495
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_PORT_FORWARDING, &i )
496
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_PEER_PORT, &j );
498
session->peerPort = session->isPortRandom ? getRandomPort( session ) : j;
499
session->shared = tr_sharedInit( session, i, session->peerPort );
500
session->isPortSet = session->isPortRandom || j>0;
505
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, &i );
507
session->uploadSlotsPerTorrent = i;
509
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED, &i )
510
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED_ENABLED, &j );
512
tr_sessionSetSpeedLimit( session, TR_UP, i );
513
tr_sessionSetSpeedLimitEnabled( session, TR_UP, j );
515
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED, &i )
516
&& tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED_ENABLED, &j );
518
tr_sessionSetSpeedLimit( session, TR_DOWN, i );
519
tr_sessionSetSpeedLimitEnabled( session, TR_DOWN, j );
521
/* initialize the blocklist */
522
filename = tr_buildPath( session->configDir, "blocklists", NULL );
523
tr_mkdirp( filename, 0777 );
525
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i );
527
session->isBlocklistEnabled = i;
528
loadBlocklists( session );
530
session->rpcServer = tr_rpcInit( session, &settings );
532
tr_bencFree( &settings );
534
session->isWaiting = TRUE;
535
tr_runInEventThread( session, tr_sessionInitImpl, session );
536
while( session->isWaiting )
542
tr_sessionInitImpl( void * vsession )
544
tr_session * session = vsession;
546
assert( tr_isSession( session ) );
287
548
/* first %s is the application name
288
549
second %s is the version number */
289
550
tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
291
/* initialize the blocklist */
292
filename = tr_buildPath( h->configDir, "blocklists", NULL );
293
tr_mkdirp( filename, 0777 );
295
h->isBlocklistEnabled = isBlocklistEnabled;
300
h->web = tr_webInit( h );
301
h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort,
302
rpcWhitelistIsEnabled, rpcWhitelist,
303
rpcAuthIsEnabled, rpcUsername, rpcPassword );
305
metainfoLookupRescan( h );
311
tr_sessionInit( const char * configDir,
312
const char * downloadDir,
315
return tr_sessionInitFull( configDir,
318
TR_DEFAULT_PEX_ENABLED,
319
TR_DEFAULT_PORT_FORWARDING_ENABLED,
320
-1, /* public port */
321
TR_DEFAULT_ENCRYPTION, /* encryption mode */
322
TR_DEFAULT_LAZY_BITFIELD_ENABLED,
323
FALSE, /* use upload speed limit? */
324
-1, /* upload speed limit */
325
FALSE, /* use download speed limit? */
326
-1, /* download speed limit */
327
TR_DEFAULT_GLOBAL_PEER_LIMIT,
328
TR_MSG_INF, /* message level */
329
FALSE, /* is message queueing enabled? */
330
FALSE, /* is the blocklist enabled? */
331
TR_DEFAULT_PEER_SOCKET_TOS,
332
TR_DEFAULT_RPC_ENABLED,
334
TR_DEFAULT_RPC_WHITELIST_ENABLED,
335
TR_DEFAULT_RPC_WHITELIST,
339
TR_DEFAULT_PROXY_ENABLED,
341
TR_DEFAULT_PROXY_PORT,
342
TR_DEFAULT_PROXY_TYPE,
343
TR_DEFAULT_PROXY_AUTH_ENABLED,
344
TR_DEFAULT_PROXY_USERNAME,
345
TR_DEFAULT_PROXY_PASSWORD );
552
tr_statsInit( session );
553
session->web = tr_webInit( session );
554
metainfoLookupRescan( session );
555
session->isWaiting = FALSE;