Rework the port handling a bit to allow different bound and advertised ports.

This commit is contained in:
Josh Elsasser 2007-01-27 21:17:10 +00:00
parent 8d89e4f148
commit adfd4e7ca7
7 changed files with 75 additions and 46 deletions

View File

@ -163,7 +163,7 @@ struct tr_torrent_s
char * id;
char * key;
int * bindPort;
int publicPort;
/* An escaped string used to include the hash in HTTP queries */
char escapedHashString[3*SHA_DIGEST_LENGTH+1];
@ -210,7 +210,7 @@ struct tr_handle_s
int torrentCount;
tr_torrent_t * torrentList;
int bindPort;
int isPortSet;
int uploadLimit;
int downloadLimit;
tr_shared_t * shared;

View File

@ -36,6 +36,7 @@ struct tr_shared_s
tr_lock_t lock;
/* Incoming connections */
int publicPort;
int bindPort;
int bindSocket;
int peerCount;
@ -53,6 +54,7 @@ struct tr_shared_s
* Local prototypes
**********************************************************************/
static void SharedLoop( void * );
static void SetPublicPort( tr_shared_t *, int );
static void AcceptPeers( tr_shared_t * );
static void ReadPeers( tr_shared_t * );
static void DispatchPeers( tr_shared_t * );
@ -70,11 +72,12 @@ tr_shared_t * tr_sharedInit( tr_handle_t * h )
s->h = h;
tr_lockInit( &s->lock );
s->bindPort = -1;
s->publicPort = -1;
s->bindPort = -1;
s->bindSocket = -1;
s->natpmp = tr_natpmpInit();
s->upnp = tr_upnpInit();
s->choking = tr_chokingInit( h );
s->natpmp = tr_natpmpInit();
s->upnp = tr_upnpInit();
s->choking = tr_chokingInit( h );
/* Launch the thread */
s->die = 0;
@ -133,9 +136,6 @@ void tr_sharedUnlock( tr_shared_t * s )
**********************************************************************/
void tr_sharedSetPort( tr_shared_t * s, int port )
{
tr_handle_t * h = s->h;
tr_torrent_t * tor;
#ifdef BEOS_NETSERVER
/* BeOS net_server seems to be unable to set incoming connections
* to non-blocking. Too bad. */
@ -167,14 +167,9 @@ void tr_sharedSetPort( tr_shared_t * s, int port )
}
/* Notify the trackers */
for( tor = h->torrentList; tor; tor = tor->next )
if( port != s->publicPort )
{
tr_lockLock( &tor->lock );
if( NULL != tor->tracker )
{
tr_trackerChangePort( tor->tracker, port );
}
tr_lockUnlock( &tor->lock );
SetPublicPort( s, port );
}
/* Forward the new port */
@ -184,6 +179,16 @@ void tr_sharedSetPort( tr_shared_t * s, int port )
tr_sharedUnlock( s );
}
/***********************************************************************
* tr_sharedGetPublicPort
***********************************************************************
*
**********************************************************************/
int tr_sharedGetPublicPort( tr_shared_t * s )
{
return s->publicPort;
}
/***********************************************************************
* tr_sharedTraversalEnable, tr_natTraversalStatus
***********************************************************************
@ -289,6 +294,24 @@ static void SharedLoop( void * _s )
tr_sharedUnlock( s );
}
/***********************************************************************
* SetPublicPort
**********************************************************************/
static void SetPublicPort( tr_shared_t * s, int port )
{
tr_handle_t * h = s->h;
tr_torrent_t * tor;
s->publicPort = port;
for( tor = h->torrentList; tor; tor = tor->next )
{
tr_lockLock( &tor->lock );
tor->publicPort = port;
tr_lockUnlock( &tor->lock );
}
}
/***********************************************************************
* AcceptPeers
***********************************************************************

View File

@ -51,6 +51,7 @@ void tr_sharedUnlock ( tr_shared_t * );
* Changes the port for incoming connections
**********************************************************************/
void tr_sharedSetPort ( tr_shared_t *, int port );
int tr_sharedGetPublicPort ( tr_shared_t * s );
/***********************************************************************
* tr_sharedTraversalEnable, tr_natTraversalStatus

View File

@ -110,12 +110,11 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor,
}
}
tor->handle = h;
tor->status = TR_STATUS_PAUSE;
tor->id = h->id;
tor->key = h->key;
tor->bindPort = &h->bindPort;
tor->finished = 0;
tor->handle = h;
tor->status = TR_STATUS_PAUSE;
tor->id = h->id;
tor->key = h->key;
tor->finished = 0;
/* Escaped info hash for HTTP queries */
for( i = 0; i < SHA_DIGEST_LENGTH; i++ )
@ -138,8 +137,9 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor,
/* We have a new torrent */
tr_sharedLock( h->shared );
tor->prev = NULL;
tor->next = h->torrentList;
tor->publicPort = tr_sharedGetPublicPort( h->shared );
tor->prev = NULL;
tor->next = h->torrentList;
if( tor->next )
{
tor->next->prev = tor;
@ -148,7 +148,7 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor,
(h->torrentCount)++;
tr_sharedUnlock( h->shared );
if( 0 > h->bindPort )
if( !h->isPortSet )
{
tr_setBindPort( h, TR_DEFAULT_PORT );
}
@ -190,6 +190,8 @@ void tr_torrentStart( tr_torrent_t * tor )
torrentReallyStop( tor );
}
tr_lockLock( &tor->lock );
tor->downloadedPrev += tor->downloadedCur;
tor->downloadedCur = 0;
tor->uploadedPrev += tor->uploadedCur;
@ -202,6 +204,9 @@ void tr_torrentStart( tr_torrent_t * tor )
tor->date = tr_date();
tor->die = 0;
snprintf( name, sizeof( name ), "torrent %p", tor );
tr_lockUnlock( &tor->lock );
tr_threadCreate( &tor->thread, downloadLoop, tor, name );
}

View File

@ -23,6 +23,7 @@
*****************************************************************************/
#include "transmission.h"
#include "shared.h"
typedef struct tr_announce_list_ptr_s tr_announce_list_ptr_t;
struct tr_announce_list_ptr_s
@ -85,8 +86,7 @@ struct tr_tracker_s
tr_http_t * http;
tr_http_t * httpScrape;
int bindPort;
int newPort;
int publicPort;
};
static int announceToScrape ( char * announce, char * scrape );
@ -98,6 +98,7 @@ static void readAnswer ( tr_tracker_t * tc, const char *, int,
int * peerCount, uint8_t ** peerCompact );
static void readScrapeAnswer ( tr_tracker_t * tc, const char *, int );
static void killHttp ( tr_http_t ** http );
static int shouldChangePort( tr_tracker_t * tc );
tr_tracker_t * tr_trackerInit( tr_torrent_t * tor )
{
@ -122,8 +123,7 @@ tr_tracker_t * tr_trackerInit( tr_torrent_t * tor )
tc->lastError = 1;
tc->allUnreachIfError = 1;
tc->bindPort = *(tor->bindPort);
tc->newPort = -1;
tc->publicPort = tor->publicPort;
tc->trackerAnnounceListPtr = calloc( sizeof( int ), inf->trackerTiers );
for( ii = 0; ii < inf->trackerTiers; ii++ )
@ -251,7 +251,7 @@ static int shouldConnect( tr_tracker_t * tc )
}
/* Do we need to send an event? */
if( tc->started || tc->completed || tc->stopped || 0 < tc->newPort )
if( tc->started || tc->completed || tc->stopped || shouldChangePort( tc ) )
{
return 1;
}
@ -317,11 +317,6 @@ static int shouldScrape( tr_tracker_t * tc )
return now > tc->dateScrape + interval;
}
void tr_trackerChangePort( tr_tracker_t * tc, int port )
{
tc->newPort = port;
}
void tr_trackerAnnouncePulse( tr_tracker_t * tc, int * peerCount,
uint8_t ** peerCompact, int manual )
{
@ -423,7 +418,7 @@ void tr_trackerAnnouncePulse( tr_tracker_t * tc, int * peerCount,
tc->started ? "sending 'started'" :
( tc->completed ? "sending 'completed'" :
( tc->stopped ? "sending 'stopped'" :
( 0 < tc->newPort ? "sending 'stopped' to change port" :
( shouldChangePort( tc ) ? "sending 'stopped' to change port" :
"getting peers" ) ) ) );
}
@ -567,17 +562,16 @@ static tr_http_t * getQuery( tr_tracker_t * tc )
down = 0;
up = 0;
if( 0 < tc->newPort )
if( shouldChangePort( tc ) )
{
tc->bindPort = tc->newPort;
tc->newPort = -1;
tc->publicPort = tor->publicPort;
}
}
else if( tc->completed )
{
event = "&event=completed";
}
else if( tc->stopped || 0 < tc->newPort )
else if( tc->stopped || shouldChangePort( tc ) )
{
event = "&event=stopped";
numwant = 0;
@ -615,7 +609,7 @@ static tr_http_t * getQuery( tr_tracker_t * tc )
"%s%s"
"%s",
tc->trackerAnnounce, start, tor->escapedHashString,
tc->id, tc->bindPort, up, down, left, numwant,
tc->id, tc->publicPort, up, down, left, numwant,
tor->key, idparam, trackerid, event );
}
@ -713,7 +707,7 @@ static void readAnswer( tr_tracker_t * tc, const char * data, int len,
if( i >= bodylen )
{
if( tc->stopped || 0 < tc->newPort )
if( tc->stopped || shouldChangePort( tc ) )
{
tc->lastError = 0;
goto nodict;
@ -830,7 +824,7 @@ static void readAnswer( tr_tracker_t * tc, const char * data, int len,
bePeers = tr_bencDictFind( &beAll, "peers" );
if( !bePeers )
{
if( tc->stopped || 0 < tc->newPort )
if( tc->stopped || shouldChangePort( tc ) )
{
goto nodict;
}
@ -903,7 +897,7 @@ nodict:
tor->status = TR_STATUS_STOPPED;
tc->stopped = 0;
}
else if( 0 < tc->newPort )
else if( shouldChangePort( tc ) )
{
tc->started = 1;
}
@ -1155,3 +1149,10 @@ static void killHttp( tr_http_t ** http )
*http = NULL;
}
}
static int shouldChangePort( tr_tracker_t * tc )
{
tr_torrent_t * tor = tc->tor;
return ( tor->publicPort != tc->publicPort );
}

View File

@ -28,7 +28,6 @@
typedef struct tr_tracker_s tr_tracker_t;
tr_tracker_t * tr_trackerInit ( tr_torrent_t * );
void tr_trackerChangePort( tr_tracker_t *, int );
#define tr_trackerPulse(tc,a,b) tr_trackerAnnouncePulse((tc),(a),(b),0)
void tr_trackerAnnouncePulse( tr_tracker_t *, int * peerCount,

View File

@ -77,7 +77,7 @@ tr_handle_t * tr_init()
**********************************************************************/
void tr_setBindPort( tr_handle_t * h, int port )
{
h->bindPort = port;
h->isPortSet = 1;
tr_sharedSetPort( h->shared, port );
}