source: trunk/libtransmission/session.c @ 6120

Last change on this file since 6120 was 6120, checked in by charles, 14 years ago

wire up the backend proxy support.

  • Property svn:keywords set to Date Rev Author Id
File size: 24.2 KB
Line 
1/******************************************************************************
2 * $Id: session.c 6120 2008-06-10 16:16:31Z charles $
3 *
4 * Copyright (c) 2005-2008 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include <assert.h>
26#include <stdlib.h>
27#include <string.h> /* memcpy */
28
29#include <signal.h>
30#include <sys/types.h> /* stat */
31#include <sys/stat.h> /* stat */
32#include <unistd.h> /* stat */
33#include <dirent.h> /* opendir */
34
35#include "transmission.h"
36#include "blocklist.h"
37#include "fdlimit.h"
38#include "list.h"
39#include "metainfo.h" /* tr_metainfoFree */
40#include "net.h"
41#include "peer-mgr.h"
42#include "platform.h" /* tr_lock */
43#include "port-forwarding.h"
44#include "ratecontrol.h"
45#include "rpc-server.h"
46#include "stats.h"
47#include "torrent.h"
48#include "tracker.h"
49#include "trevent.h"
50#include "utils.h"
51#include "web.h"
52
53/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
54   characters, where x is the major version number, y is the
55   minor version number, z is the maintenance number, and b
56   designates beta (Azureus-style) */
57uint8_t*
58tr_peerIdNew( void )
59{
60    int i;
61    int val;
62    int total = 0;
63    uint8_t * buf = tr_new( uint8_t, 21 );
64    const char * pool = "0123456789abcdefghijklmnopqrstuvwxyz";
65    const int base = 36;
66
67    memcpy( buf, PEERID_PREFIX, 8 );
68
69    for( i=8; i<19; ++i ) {
70        val = tr_rand( base );
71        total += val;
72        buf[i] = pool[val];
73    }
74
75    val = total % base ? base - (total % base) : 0;
76    total += val;
77    buf[19] = pool[val];
78    buf[20] = '\0';
79
80    return buf;
81}
82
83const uint8_t*
84tr_getPeerId( void )
85{
86    static uint8_t * id = NULL;
87    if( id == NULL )
88        id = tr_peerIdNew( );
89    return id;
90}
91
92/***
93****
94***/
95
96tr_encryption_mode
97tr_sessionGetEncryption( tr_session * session )
98{
99    assert( session != NULL );
100
101    return session->encryptionMode;
102}
103
104void
105tr_sessionSetEncryption( tr_session * session, tr_encryption_mode mode )
106{
107    assert( session != NULL );
108    assert( mode==TR_ENCRYPTION_PREFERRED
109         || mode==TR_ENCRYPTION_REQUIRED
110         || mode==TR_PLAINTEXT_PREFERRED );
111
112    session->encryptionMode = mode;
113}
114
115/***
116****
117***/
118
119static void metainfoLookupRescan( tr_handle * h );
120
121tr_handle *
122tr_sessionInitFull( const char  * configDir,
123                    const char  * downloadDir,
124                    const char  * tag,
125                    int           isPexEnabled,
126                    int           isPortForwardingEnabled,
127                    int           publicPort,
128                    int           encryptionMode,
129                    int           isUploadLimitEnabled,
130                    int           uploadLimit,
131                    int           isDownloadLimitEnabled,
132                    int           downloadLimit,
133                    int           globalPeerLimit,
134                    int           messageLevel,
135                    int           isMessageQueueingEnabled,
136                    int           isBlocklistEnabled,
137                    int           peerSocketTOS,
138                    int           rpcIsEnabled,
139                    int           rpcPort,
140                    const char  * rpcACL,
141                    int           rpcAuthIsEnabled,
142                    const char  * rpcUsername,
143                    const char  * rpcPassword,
144                    int           proxyIsEnabled,
145                    const char  * proxy,
146                    int           proxyAuthIsEnabled,
147                    const char  * proxyUsername,
148                    const char  * proxyPassword )
149{
150    tr_handle * h;
151    char filename[MAX_PATH_LENGTH];
152
153#ifndef WIN32
154    /* Don't exit when writing on a broken socket */
155    signal( SIGPIPE, SIG_IGN );
156#endif
157
158    if( configDir == NULL )
159        configDir = tr_getDefaultConfigDir( );
160
161    tr_msgInit( );
162    tr_setMessageLevel( messageLevel );
163    tr_setMessageQueuing( isMessageQueueingEnabled );
164
165    h = tr_new0( tr_handle, 1 );
166    h->lock = tr_lockNew( );
167    h->isPexEnabled = isPexEnabled ? 1 : 0;
168    h->encryptionMode = encryptionMode;
169    h->peerSocketTOS = peerSocketTOS;
170    h->downloadDir = tr_strdup( downloadDir );
171    h->isProxyEnabled = proxyIsEnabled ? 1 : 0;
172    h->proxy = tr_strdup( proxy );
173    h->isProxyAuthEnabled = proxyAuthIsEnabled ? 1 : 0;
174    h->proxyUsername = tr_strdup( proxyUsername );
175    h->proxyPassword = tr_strdup( proxyPassword );
176
177    tr_setConfigDir( h, configDir );
178
179    tr_netInit(); /* must go before tr_eventInit */
180
181    tr_eventInit( h );
182    while( !h->events )
183        tr_wait( 50 );
184
185    h->tag = tr_strdup( tag );
186    h->peerMgr = tr_peerMgrNew( h );
187
188    /* Initialize rate and file descripts controls */
189
190    h->upload = tr_rcInit();
191    tr_rcSetLimit( h->upload, uploadLimit );
192    h->useUploadLimit = isUploadLimitEnabled;
193
194    h->download = tr_rcInit();
195    tr_rcSetLimit( h->download, downloadLimit );
196    h->useDownloadLimit = isDownloadLimitEnabled;
197
198    tr_fdInit( globalPeerLimit );
199    h->shared = tr_sharedInit( h, isPortForwardingEnabled, publicPort );
200    h->isPortSet = publicPort >= 0;
201
202    /* first %s is the application name
203       second %s is the version number */
204    tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
205
206    /* initialize the blocklist */
207    tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", NULL );
208    tr_mkdirp( filename, 0777 );
209    tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", "level1.bin", NULL );
210    h->blocklist = _tr_blocklistNew( filename, isBlocklistEnabled );
211
212    tr_statsInit( h );
213
214    h->web = tr_webInit( h );
215    h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcACL,
216                                  rpcAuthIsEnabled, rpcUsername, rpcPassword );
217
218    metainfoLookupRescan( h );
219
220    return h;
221}
222
223tr_handle *
224tr_sessionInit( const char * configDir,
225                const char * downloadDir,
226                const char * tag )
227{
228    return tr_sessionInitFull( configDir,
229                               downloadDir,
230                               tag,
231                               TR_DEFAULT_PEX_ENABLED,
232                               TR_DEFAULT_PORT_FORWARDING_ENABLED,
233                               -1, /* public port */
234                               TR_ENCRYPTION_PREFERRED, /* encryption mode */
235                               FALSE, /* use upload speed limit? */ 
236                               -1, /* upload speed limit */
237                               FALSE, /* use download speed limit? */
238                               -1, /* download speed limit */
239                               TR_DEFAULT_GLOBAL_PEER_LIMIT,
240                               TR_MSG_INF, /* message level */
241                               FALSE, /* is message queueing enabled? */
242                               FALSE, /* is the blocklist enabled? */
243                               TR_DEFAULT_PEER_SOCKET_TOS,
244                               TR_DEFAULT_RPC_ENABLED,
245                               TR_DEFAULT_RPC_PORT,
246                               TR_DEFAULT_RPC_ACL,
247                               FALSE,
248                               "fnord",
249                               "potzrebie",
250                               TR_DEFAULT_PROXY_ENABLED,
251                               TR_DEFAULT_PROXY,
252                               TR_DEFAULT_PROXY_AUTH_ENABLED,
253                               TR_DEFAULT_PROXY_USERNAME,
254                               TR_DEFAULT_PROXY_PASSWORD );
255
256}
257
258/***
259****
260***/
261
262void
263tr_sessionSetDownloadDir( tr_handle * handle, const char * dir )
264{
265    if( handle->downloadDir != dir )
266    {
267        tr_free( handle->downloadDir );
268        handle->downloadDir = tr_strdup( dir );
269    }
270}
271
272const char *
273tr_sessionGetDownloadDir( const tr_handle * handle )
274{
275    return handle->downloadDir;
276}
277
278/***
279****
280***/
281
282void
283tr_globalLock( struct tr_handle * handle )
284{
285    tr_lockLock( handle->lock );
286}
287
288void
289tr_globalUnlock( struct tr_handle * handle )
290{
291    tr_lockUnlock( handle->lock );
292}
293
294int
295tr_globalIsLocked( const struct tr_handle * handle )
296{
297    return handle && tr_lockHave( handle->lock );
298}
299
300/***********************************************************************
301 * tr_setBindPort
302 ***********************************************************************
303 *
304 **********************************************************************/
305
306struct bind_port_data
307{
308    tr_handle * handle;
309    int port;
310};
311
312static void
313tr_setBindPortImpl( void * vdata )
314{
315    struct bind_port_data * data = vdata;
316    tr_handle * handle = data->handle;
317    const int port = data->port;
318
319    handle->isPortSet = 1;
320    tr_sharedSetPort( handle->shared, port );
321
322    tr_free( data );
323}
324
325void
326tr_sessionSetPeerPort( tr_handle * handle, int port )
327{
328    struct bind_port_data * data = tr_new( struct bind_port_data, 1 );
329    data->handle = handle;
330    data->port = port;
331    tr_runInEventThread( handle, tr_setBindPortImpl, data );
332}
333
334int
335tr_sessionGetPeerPort( const tr_handle * h )
336{
337    assert( h != NULL );
338    return tr_sharedGetPeerPort( h->shared );
339}
340
341tr_port_forwarding
342tr_sessionGetPortForwarding( const tr_handle * h )
343{
344    return tr_sharedTraversalStatus( h->shared );
345}
346
347/***
348****
349***/
350
351void
352tr_sessionSetSpeedLimitEnabled( tr_handle  * h,
353                                int          up_or_down,
354                                int          use_flag )
355{
356    if( up_or_down == TR_UP )
357        h->useUploadLimit = use_flag ? 1 : 0;
358    else
359        h->useDownloadLimit = use_flag ? 1 : 0;
360}
361
362int
363tr_sessionIsSpeedLimitEnabled( const tr_handle * h, int up_or_down )
364{
365       return up_or_down==TR_UP ? h->useUploadLimit : h->useDownloadLimit;
366}
367
368void
369tr_sessionSetSpeedLimit( tr_handle  * h,
370                         int          up_or_down,
371                         int          KiB_sec )
372{
373    if( up_or_down == TR_DOWN )
374        tr_rcSetLimit( h->download, KiB_sec );
375    else
376        tr_rcSetLimit( h->upload, KiB_sec );
377}
378
379int
380tr_sessionGetSpeedLimit( const tr_handle * h, int up_or_down )
381{
382    return tr_rcGetLimit( up_or_down==TR_UP ? h->upload : h->download );
383}
384
385/***
386****
387***/
388
389void
390tr_sessionSetPeerLimit( tr_handle * handle UNUSED,
391                        uint16_t    maxGlobalPeers )
392{
393    tr_fdSetPeerLimit( maxGlobalPeers );
394}
395
396uint16_t
397tr_sessionGetPeerLimit( const tr_handle * handle UNUSED )
398{
399    return tr_fdGetPeerLimit( );
400}
401
402/***
403****
404***/
405
406void
407tr_sessionGetSpeed( const tr_handle  * session,
408                    float            * toClient,
409                    float            * toPeer )
410{
411    if( session && toClient )
412        *toClient = tr_rcRate( session->download );
413    if( session && toPeer )
414        *toPeer = tr_rcRate( session->upload );
415}
416
417int
418tr_sessionCountTorrents( const tr_handle * h )
419{
420    return h->torrentCount;
421}
422
423/* close the biggest torrents first */
424static int
425compareTorrentByCur( const void * va, const void * vb )
426{
427    const tr_torrent * a = *(const tr_torrent**)va;
428    const tr_torrent * b = *(const tr_torrent**)vb;
429    return -tr_compareUint64( a->downloadedCur + a->uploadedCur,
430                              b->downloadedCur + b->uploadedCur );
431}
432
433static void
434tr_closeAllConnections( void * vh )
435{
436    tr_handle * h = vh;
437    tr_torrent * tor;
438    int i, n;
439    tr_torrent ** torrents;
440
441    tr_sharedShuttingDown( h->shared );
442    tr_trackerShuttingDown( h );
443    tr_rpcClose( &h->rpcServer );
444
445    /* close the torrents.  get the most active ones first so that
446     * if we can't get them all closed in a reasonable amount of time,
447     * at least we get the most important ones first. */
448    tor = NULL;
449    n = h->torrentCount;
450    torrents = tr_new( tr_torrent*, h->torrentCount );
451    for( i=0; i<n; ++i )
452        torrents[i] = tor = tr_torrentNext( h, tor );
453    qsort( torrents, n, sizeof(tr_torrent*), compareTorrentByCur );
454    for( i=0; i<n; ++i )
455        tr_torrentFree( torrents[i] );
456    tr_free( torrents );
457
458    tr_peerMgrFree( h->peerMgr );
459
460    tr_rcClose( h->upload );
461    tr_rcClose( h->download );
462   
463    h->isClosed = TRUE;
464}
465
466static int
467deadlineReached( const uint64_t deadline )
468{
469    return tr_date( ) >= deadline;
470}
471
472#define SHUTDOWN_MAX_SECONDS 30
473
474void
475tr_sessionClose( tr_handle * h )
476{
477    int i;
478    const int maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000;
479    const uint64_t deadline = tr_date( ) + maxwait_msec;
480
481    tr_deepLog( __FILE__, __LINE__, NULL, "shutting down transmission session %p", h );
482    tr_statsClose( h );
483
484    tr_runInEventThread( h, tr_closeAllConnections, h );
485    while( !h->isClosed && !deadlineReached( deadline ) )
486        tr_wait( 100 );
487
488    _tr_blocklistFree( h->blocklist );
489    h->blocklist = NULL;
490    tr_webClose( &h->web );
491
492    tr_eventClose( h );
493    while( h->events && !deadlineReached( deadline ) )
494        tr_wait( 100 );
495
496    tr_fdClose( );
497    tr_lockFree( h->lock );
498    for( i=0; i<h->metainfoLookupCount; ++i )
499        tr_free( h->metainfoLookup[i].filename );
500    tr_free( h->metainfoLookup );
501    tr_free( h->tag );
502    tr_free( h->configDir );
503    tr_free( h->resumeDir );
504    tr_free( h->torrentDir );
505    tr_free( h->downloadDir );
506    tr_free( h->proxy );
507    tr_free( h->proxyUsername );
508    tr_free( h->proxyPassword );
509    free( h );
510}
511
512tr_torrent **
513tr_sessionLoadTorrents ( tr_handle   * h,
514                         tr_ctor     * ctor,
515                         int         * setmeCount )
516{
517    int i, n = 0;
518    struct stat sb;
519    DIR * odir = NULL;
520    const char * dirname = tr_getTorrentDir( h );
521    tr_torrent ** torrents;
522    tr_list *l=NULL, *list=NULL;
523
524    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
525
526    if( !stat( dirname, &sb )
527        && S_ISDIR( sb.st_mode )
528        && (( odir = opendir ( dirname ) )) )
529    {
530        struct dirent *d;
531        for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
532        {
533            if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
534            {
535                tr_torrent * tor;
536                char filename[MAX_PATH_LENGTH];
537                tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
538                tr_ctorSetMetainfoFromFile( ctor, filename );
539                tor = tr_torrentNew( h, ctor, NULL );
540                if( tor ) {
541                    tr_list_append( &list, tor );
542                    n++;
543                }
544            }
545        }
546        closedir( odir );
547    }
548
549    torrents = tr_new( tr_torrent*, n );
550    for( i=0, l=list; l!=NULL; l=l->next )
551        torrents[i++] = (tr_torrent*) l->data;
552    assert( i==n );
553
554    tr_list_free( &list, NULL );
555
556    if( n )
557        tr_inf( _( "Loaded %d torrents" ), n );
558
559    if( setmeCount )
560        *setmeCount = n;
561    return torrents;
562}
563
564/***
565****
566***/
567
568void
569tr_sessionSetPexEnabled( tr_handle * handle, int isPexEnabled )
570{
571    handle->isPexEnabled = isPexEnabled ? 1 : 0;
572}
573
574int
575tr_sessionIsPexEnabled( const tr_handle * handle )
576{
577    return handle->isPexEnabled;
578}
579
580/***
581****
582***/
583
584void
585tr_sessionSetPortForwardingEnabled( tr_handle * h, int enable )
586{
587    tr_globalLock( h );
588    tr_sharedTraversalEnable( h->shared, enable );
589    tr_globalUnlock( h );
590}
591
592int
593tr_sessionIsPortForwardingEnabled( const tr_handle * h )
594{
595    return tr_sharedTraversalIsEnabled( h->shared );
596}
597
598/***
599****
600***/
601
602int
603tr_blocklistGetRuleCount( tr_handle * handle )
604{
605    return _tr_blocklistGetRuleCount( handle->blocklist );
606}
607
608int
609tr_blocklistIsEnabled( const tr_handle * handle )
610{
611    return _tr_blocklistIsEnabled( handle->blocklist );
612}
613
614void
615tr_blocklistSetEnabled( tr_handle * handle, int isEnabled )
616{
617    _tr_blocklistSetEnabled( handle->blocklist, isEnabled );
618}
619
620int
621tr_blocklistExists( const tr_handle * handle )
622{
623    return _tr_blocklistExists( handle->blocklist );
624}
625
626int
627tr_blocklistSetContent( tr_handle  * handle, const char * filename )
628{
629    return _tr_blocklistSetContent( handle->blocklist, filename );
630}
631
632int
633tr_blocklistHasAddress( tr_handle * handle, const struct in_addr * addr )
634{
635    return _tr_blocklistHasAddress( handle->blocklist, addr );
636}
637
638/***
639****
640***/
641
642static int
643compareLookupEntries( const void * va, const void * vb )
644{
645    const struct tr_metainfo_lookup * a = va;
646    const struct tr_metainfo_lookup * b = vb;
647    return strcmp( a->hashString, b->hashString );
648}
649
650static void
651metainfoLookupResort( tr_handle * h )
652{
653    qsort( h->metainfoLookup, 
654           h->metainfoLookupCount,
655           sizeof( struct tr_metainfo_lookup ),
656           compareLookupEntries );
657}
658
659static int
660compareHashStringToLookupEntry( const void * va, const void * vb )
661{
662    const char * a = va;
663    const struct tr_metainfo_lookup * b = vb;
664    return strcmp( a, b->hashString );
665}
666
667const char*
668tr_sessionFindTorrentFile( const tr_handle  * h,
669                           const char       * hashStr )
670{
671    struct tr_metainfo_lookup * l = bsearch( hashStr,
672                                             h->metainfoLookup,
673                                             h->metainfoLookupCount,
674                                             sizeof( struct tr_metainfo_lookup ),
675                                             compareHashStringToLookupEntry );
676    return l ? l->filename : NULL;
677}
678
679static void
680metainfoLookupRescan( tr_handle * h )
681{
682    int i;
683    int n;
684    struct stat sb;
685    const char * dirname = tr_getTorrentDir( h );
686    DIR * odir = NULL;
687    tr_ctor * ctor = NULL;
688    tr_list * list = NULL;
689
690    /* walk through the directory and find the mappings */
691    ctor = tr_ctorNew( h );
692    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
693    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && (( odir = opendir( dirname ))))
694    {
695        struct dirent *d;
696        for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
697        {
698            if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
699            {
700                tr_info inf;
701                char filename[MAX_PATH_LENGTH];
702                tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
703                tr_ctorSetMetainfoFromFile( ctor, filename );
704                if( !tr_torrentParse( h, ctor, &inf ) )
705                {
706                    tr_list_append( &list, tr_strdup( inf.hashString ) );
707                    tr_list_append( &list, tr_strdup( filename ) );
708                    tr_metainfoFree( &inf );
709                }
710            }
711        }
712        closedir( odir );
713    }
714    tr_ctorFree( ctor );
715
716    n = tr_list_size( list ) / 2;
717    h->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
718    h->metainfoLookupCount = n;
719    for( i=0; i<n; ++i )
720    {
721        char * hashString = tr_list_pop_front( &list );
722        char * filename = tr_list_pop_front( &list );
723
724        memcpy( h->metainfoLookup[i].hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
725        tr_free( hashString );
726        h->metainfoLookup[i].filename = filename;
727    }
728
729    metainfoLookupResort( h );
730    tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
731}
732
733void
734tr_sessionSetTorrentFile( tr_handle    * h,
735                          const char   * hashString,
736                          const char   * filename )
737{
738    struct tr_metainfo_lookup * l = bsearch( hashString,
739                                             h->metainfoLookup,
740                                             h->metainfoLookupCount,
741                                             sizeof( struct tr_metainfo_lookup ),
742                                             compareHashStringToLookupEntry );
743    if( l != NULL )
744    {
745        if( l->filename != filename )
746        {
747            tr_free( l->filename );
748            l->filename = tr_strdup( filename );
749        }
750    }
751    else
752    {
753        const int n = h->metainfoLookupCount++;
754        struct tr_metainfo_lookup * node;
755        h->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
756                                      h->metainfoLookup,
757                                      h->metainfoLookupCount );
758        node = h->metainfoLookup + n;
759        memcpy( node->hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
760        node->filename = tr_strdup( filename );
761        metainfoLookupResort( h );
762    }
763}
764
765tr_torrent*
766tr_torrentNext( tr_handle * session, tr_torrent * tor )
767{
768    return tor ? tor->next : session->torrentList;
769}
770
771/***
772****
773***/
774
775void
776tr_sessionSetRPCEnabled( tr_session * session, int isEnabled )
777{
778    tr_rpcSetEnabled( session->rpcServer, isEnabled );
779}
780int
781tr_sessionIsRPCEnabled( const tr_session * session )
782{
783    return tr_rpcIsEnabled( session->rpcServer );
784}
785void
786tr_sessionSetRPCPort( tr_session * session, int port )
787{
788    tr_rpcSetPort( session->rpcServer, port );
789}
790int
791tr_sessionGetRPCPort( const tr_session * session )
792{
793    return tr_rpcGetPort( session->rpcServer );
794}
795void
796tr_sessionSetRPCCallback( tr_session    * session,
797                          tr_rpc_func    func,
798                          void         * user_data )
799{
800    session->rpc_func = func;
801    session->rpc_func_user_data = user_data;
802}
803int
804tr_sessionTestRPCACL( const tr_session  * session,
805                      const char       * acl,
806                      char            ** allocme_errmsg )
807{
808    return tr_rpcTestACL( session->rpcServer, acl, allocme_errmsg );
809}
810int
811tr_sessionSetRPCACL( tr_session    * session,
812                     const char   * acl,
813                     char        ** allocme_errmsg )
814{
815    return tr_rpcSetACL( session->rpcServer, acl, allocme_errmsg );
816}
817char*
818tr_sessionGetRPCACL( const tr_session * session )
819{
820    return tr_rpcGetACL( session->rpcServer );
821}
822void
823tr_sessionSetRPCPassword( tr_session * session, const char * password )
824{
825    tr_rpcSetPassword( session->rpcServer, password );
826}
827char*
828tr_sessionGetRPCPassword( const tr_session * session )
829{
830    return tr_rpcGetPassword( session->rpcServer );
831}
832void
833tr_sessionSetRPCUsername( tr_session * session, const char * username )
834{
835    tr_rpcSetUsername( session->rpcServer, username );
836}
837char*
838tr_sessionGetRPCUsername( const tr_session * session )
839{
840    return tr_rpcGetUsername( session->rpcServer );
841}
842void
843tr_sessionSetRPCPasswordEnabled( tr_session * session, int isEnabled )
844{
845    tr_rpcSetPasswordEnabled( session->rpcServer, isEnabled );
846}
847int
848tr_sessionIsRPCPasswordEnabled( const tr_session * session )
849{
850    return tr_rpcIsPasswordEnabled( session->rpcServer );
851}
852
853/***
854****
855***/
856
857int
858tr_sessionIsProxyEnabled( const tr_session * session )
859{
860    return session->isProxyEnabled;
861}
862void
863tr_sessionSetProxyEnabled( tr_session * session, int isEnabled )
864{
865    session->isProxyEnabled = isEnabled ? 1 : 0;
866}
867const char*
868tr_sessionGetProxy( const tr_session * session )
869{
870    return session->proxy;
871}
872void
873tr_sessionSetProxy( tr_session * session, const char * proxy )
874{
875    if( proxy != session->proxy )
876    {
877        tr_free( session->proxy );
878        session->proxy = tr_strdup( proxy );
879    }
880}
881int
882tr_sessionIsProxyAuthEnabled( const tr_session * session )
883{
884    return session->isProxyAuthEnabled;
885}
886void
887tr_sessionSetProxyAuthEnabled( tr_session * session, int isEnabled )
888{
889    session->isProxyAuthEnabled = isEnabled ? 1 : 0;
890}
891const char*
892tr_sessionGetProxyUsername( const tr_session * session )
893{
894    return session->proxyUsername;
895}
896void
897tr_sessionSetProxyUsername( tr_session * session, const char * username )
898{
899    if( username != session->proxyUsername )
900    {
901        tr_free( session->proxyUsername );
902        session->proxyUsername = tr_strdup( username );
903    }
904}
905const char*
906tr_sessionGetProxyPassword( const tr_session * session )
907{
908    return session->proxyPassword;
909}
910void
911tr_sessionSetProxyPassword( tr_session * session, const char * password )
912{
913    if( password != session->proxyPassword )
914    {
915        tr_free( session->proxyPassword );
916        session->proxyPassword = tr_strdup( password );
917    }
918}
Note: See TracBrowser for help on using the repository browser.