the new tracker code seems to be working, so now it's time for me to learn yet again how much better users are at noticing bugs than I am. :)

This commit is contained in:
Charles Kerr 2007-08-16 20:00:06 +00:00
parent 2ce4e9c7e3
commit 5f5a743790
10 changed files with 1140 additions and 1278 deletions

View File

@ -58,7 +58,7 @@ void tr_peerIdNew ( char* buf, int buflen );
void tr_torrentResetTransferStats( tr_torrent_t * );
int tr_torrentAddCompact( tr_torrent_t * tor, int from,
uint8_t * buf, int count );
const uint8_t * buf, int count );
int tr_torrentAttachPeer( tr_torrent_t * tor, struct tr_peer_s * );
void tr_torrentSetHasPiece( tr_torrent_t * tor, int pieceIndex, int has );
@ -68,6 +68,8 @@ void tr_torrentReaderUnlock ( const tr_torrent_t * );
void tr_torrentWriterLock ( tr_torrent_t * );
void tr_torrentWriterUnlock ( tr_torrent_t * );
void tr_torrentChangeMyPort ( tr_torrent_t *, int port );
/* get the index of this piece's first block */
#define tr_torPieceFirstBlock(tor,piece) ( (piece) * (tor)->blockCountInPiece )
@ -101,99 +103,93 @@ typedef enum
}
run_status_t;
#define TR_ID_LEN 20
#define TR_KEY_LEN 20
#define TR_ID_LEN 20
struct tr_torrent_s
{
tr_handle_t * handle;
tr_info_t info;
tr_handle_t * handle;
tr_info_t info;
tr_speedlimit_t uploadLimitMode;
tr_speedlimit_t downloadLimitMode;
struct tr_ratecontrol_s * upload;
struct tr_ratecontrol_s * download;
struct tr_ratecontrol_s * swarmspeed;
tr_speedlimit_t uploadLimitMode;
tr_speedlimit_t downloadLimitMode;
struct tr_ratecontrol_s * upload;
struct tr_ratecontrol_s * download;
struct tr_ratecontrol_s * swarmspeed;
int error;
char errorString[128];
int hasChangedState;
int error;
char errorString[128];
int hasChangedState;
char peer_id[TR_ID_LEN+1];
char * key;
uint8_t * azId;
int publicPort;
/* An escaped string used to include the hash in HTTP queries */
char escapedHashString[3*SHA_DIGEST_LENGTH+1];
uint8_t * azId;
int publicPort;
/* Where to download */
char * destination;
char * destination;
/* How many bytes we ask for per request */
int blockSize;
int blockCount;
int blockSize;
int blockCount;
int lastBlockSize;
int lastPieceSize;
int lastBlockSize;
int lastPieceSize;
int blockCountInPiece;
int blockCountInLastPiece;
int blockCountInPiece;
int blockCountInLastPiece;
struct tr_completion_s * completion;
struct tr_completion_s * completion;
volatile char dieFlag;
struct tr_bitfield_s * uncheckedPieces;
run_status_t runStatus;
cp_status_t cpStatus;
struct tr_thread_s * thread;
struct tr_rwlock_s * lock;
volatile char dieFlag;
struct tr_bitfield_s * uncheckedPieces;
run_status_t runStatus;
cp_status_t cpStatus;
struct tr_thread_s * thread;
struct tr_rwlock_s * lock;
struct tr_tracker_s * tracker;
struct tr_io_s * io;
uint64_t startDate;
uint64_t stopDate;
char ioLoaded;
char fastResumeDirty;
struct tr_tracker_s * tracker;
struct tr_publisher_tag * trackerSubscription;
struct tr_io_s * io;
uint64_t startDate;
uint64_t stopDate;
char ioLoaded;
char fastResumeDirty;
int peerCount;
struct tr_peer_s * peers[TR_MAX_PEER_COUNT];
int peerCount;
struct tr_peer_s * peers[TR_MAX_PEER_COUNT];
uint64_t downloadedCur;
uint64_t downloadedPrev;
uint64_t uploadedCur;
uint64_t uploadedPrev;
uint64_t activityDate;
uint64_t downloadedCur;
uint64_t downloadedPrev;
uint64_t uploadedCur;
uint64_t uploadedPrev;
uint64_t activityDate;
uint8_t pexDisabled;
uint8_t pexDisabled;
int8_t statCur;
tr_stat_t stats[2];
int8_t statCur;
tr_stat_t stats[2];
tr_torrent_t * next;
tr_torrent_t * next;
};
struct tr_handle_s
{
int torrentCount;
tr_torrent_t * torrentList;
int torrentCount;
tr_torrent_t * torrentList;
char * tag;
int isPortSet;
char * tag;
int isPortSet;
char useUploadLimit;
char useDownloadLimit;
struct tr_ratecontrol_s * upload;
struct tr_ratecontrol_s * download;
char useUploadLimit;
char useDownloadLimit;
struct tr_ratecontrol_s * upload;
struct tr_ratecontrol_s * download;
struct tr_shared_s * shared;
struct tr_shared_s * shared;
char key[TR_KEY_LEN+1];
tr_handle_status_t stats[2];
int statCur;
tr_handle_status_t stats[2];
int statCur;
#define TR_AZ_ID_LEN 20
uint8_t azId[TR_AZ_ID_LEN];
#define TR_AZ_ID_LEN 20
uint8_t azId[TR_AZ_ID_LEN];
};
#endif

View File

@ -419,6 +419,12 @@ static int getannounce( tr_info_t * inf, benc_val_t * meta )
continue;
}
if( !inf->primaryAddress ) {
char buf[1024];
snprintf( buf, sizeof(buf), "%s:%d", tmp.address, tmp.port );
inf->primaryAddress = tr_strdup( buf );
}
/* place the item info in a random location in the sublist */
random = tr_rand( subcount + 1 );
if( random != subcount )
@ -487,7 +493,6 @@ static int getannounce( tr_info_t * inf, benc_val_t * meta )
tr_err( "Invalid announce URL (%s)", val->val.s.s );
return TR_EINVALID;
}
sublist = calloc( 1, sizeof( sublist[0] ) );
sublist[0].address = address;
sublist[0].port = port;
@ -497,6 +502,13 @@ static int getannounce( tr_info_t * inf, benc_val_t * meta )
inf->trackerList[0].list = sublist;
inf->trackerList[0].count = 1;
inf->trackerTiers = 1;
if( !inf->primaryAddress ) {
char buf[1024];
snprintf( buf, sizeof(buf), "%s:%d", sublist[0].address, sublist[0].port );
inf->primaryAddress = tr_strdup( buf );
}
}
return TR_OK;

View File

@ -40,6 +40,7 @@
#include "peer.h"
#include "peertree.h"
#include "ratecontrol.h"
#include "trcompat.h" /* for strlcpy */
#include "utils.h"
/*****
@ -294,6 +295,16 @@ static void tr_htonl( uint32_t a, void * p )
memcpy ( p, &u, sizeof( uint32_t ) );
}
static const char* getPeerId( void )
{
static char * peerId = NULL;
if( !peerId ) {
peerId = tr_new0( char, TR_ID_LEN + 1 );
tr_peerIdNew( peerId, TR_ID_LEN + 1 );
}
return peerId;
}
#include "peerext.h"
#include "peeraz.h"
#include "peermessages.h"
@ -582,7 +593,7 @@ int tr_peerPulse( tr_peer_t * peer )
HANDSHAKE_SET_EXTPREF( buf + HANDSHAKE_FLAGS_OFF,
HANDSHAKE_EXTPREF_WANT_EXT );
memcpy( buf + HANDSHAKE_HASH_OFF, inf->hash, SHA_DIGEST_LENGTH );
memcpy( buf + HANDSHAKE_PEERID_OFF, tor->peer_id, TR_ID_LEN );
memcpy( buf + HANDSHAKE_PEERID_OFF, getPeerId(), TR_ID_LEN );
switch( tr_netSend( peer->socket, buf, 68 ) )
{

View File

@ -613,7 +613,7 @@ static int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer )
return TR_ERROR;
}
if( 0 == memcmp( peer->buf + HANDSHAKE_PEERID_OFF, tor->peer_id,
if( 0 == memcmp( peer->buf + HANDSHAKE_PEERID_OFF, getPeerId(),
TR_ID_LEN ) )
{
/* We are connected to ourselves... */

View File

@ -330,11 +330,7 @@ static void SetPublicPort( tr_shared_t * s, int port )
s->publicPort = port;
for( tor = h->torrentList; tor; tor = tor->next )
{
tr_torrentWriterLock( tor );
tor->publicPort = port;
tr_torrentWriterUnlock( tor );
}
tr_torrentChangeMyPort( tor, port );
}
/***********************************************************************

View File

@ -111,6 +111,44 @@ tr_torrentGetSpeedLimit( const tr_torrent_t * tor,
return tr_rcGetLimit( rc );
}
/***
****
***/
static void setRunState( tr_torrent_t *, run_status_t );
static void
onTrackerResponse( void * tracker UNUSED, void * vevent, void * user_data )
{
tr_torrent_t * tor = (tr_torrent_t *) user_data;
tr_tracker_event_t * event = (tr_tracker_event_t *) vevent;
switch( event->messageType )
{
case TR_TRACKER_PEERS:
tr_torrentAddCompact( tor, TR_PEER_FROM_TRACKER,
event->peerCompact, event->peerCount );
break;
case TR_TRACKER_WARNING:
tr_err( "Tracker: Warning - %s", event->text );
tor->error = TR_ERROR_TC_WARNING;
strlcpy( tor->errorString, event->text, sizeof(tor->errorString) );
break;
case TR_TRACKER_ERROR:
tr_err( "Tracker: Error - %s", event->text );
tor->error = TR_ERROR_TC_ERROR;
strlcpy( tor->errorString, event->text, sizeof(tor->errorString) );
break;
case TR_TRACKER_STOPPED:
if( tor->runStatus == TR_RUN_STOPPING_NET_WAIT )
setRunState( tor, TR_RUN_STOPPED );
break;
}
}
/***
****
**** TORRENT INSTANTIATION
@ -140,7 +178,6 @@ initFilePieces ( tr_info_t * info, int fileIndex )
lastByte = firstByte + (file->length ? file->length-1 : 0);
file->firstPiece = getBytePiece( info, firstByte );
file->lastPiece = getBytePiece( info, lastByte );
tr_dbg( "file #%d is in pieces [%d...%d] (%s)", fileIndex, file->firstPiece, file->lastPiece, file->name );
}
static tr_priority_t
@ -195,7 +232,6 @@ torrentRealInit( tr_handle_t * h,
const char * destination,
int flags )
{
int i;
uint64_t loaded;
uint64_t t;
char name[512];
@ -209,18 +245,8 @@ torrentRealInit( tr_handle_t * h,
tor->destination = tr_strdup( destination );
tor->handle = h;
tor->key = h->key;
tor->azId = h->azId;
tor->hasChangedState = -1;
/* Escaped info hash for HTTP queries */
for( i = 0; i < SHA_DIGEST_LENGTH; i++ )
{
snprintf( &tor->escapedHashString[3*i],
sizeof( tor->escapedHashString ) - 3 * i,
"%%%02x", tor->info.hash[i] );
}
tor->pexDisabled = 0;
/**
@ -316,6 +342,11 @@ torrentRealInit( tr_handle_t * h,
tor->cpStatus = tr_cpGetStatus( tor->completion );
tor->tracker = tr_trackerNew( tor );
tor->trackerSubscription = tr_trackerSubscribe( tor->tracker, onTrackerResponse, tor );
if( tor->runStatus == TR_RUN_RUNNING )
tr_trackerStart( tor->tracker );
tr_sharedLock( h->shared );
tor->next = h->torrentList;
h->torrentList = tor;
@ -560,6 +591,18 @@ tr_torrentGetFolder( const tr_torrent_t * tor )
return tor->destination;
}
void
tr_torrentChangeMyPort( tr_torrent_t * tor, int port )
{
tr_torrentWriterLock( tor );
tor->publicPort = port;
if( tor->tracker )
tr_trackerChangeMyPort( tor->tracker );
tr_torrentWriterUnlock( tor );
}
/***********************************************************************
* torrentReallyStop
@ -614,7 +657,7 @@ void
tr_manualUpdate( tr_torrent_t * tor )
{
if( tor->runStatus == TR_RUN_RUNNING )
tr_trackerManualAnnounce( tor->tracker );
tr_trackerReannounce( tor->tracker );
}
int
tr_torrentCanManualUpdate( const tr_torrent_t * tor )
@ -628,7 +671,7 @@ const tr_stat_t *
tr_torrentStat( tr_torrent_t * tor )
{
tr_stat_t * s;
tr_tracker_t * tc;
struct tr_tracker_s * tc;
int i;
tr_torrentReaderLock( tor );
@ -641,10 +684,7 @@ tr_torrentStat( tr_torrent_t * tor )
sizeof( s->errorString ) );
tc = tor->tracker;
s->cannotConnect = tr_trackerCannotConnect( tc );
s->tracker = tc
? tr_trackerGet( tc )
: &tor->info.trackerList[0].list[0];
s->tracker = tr_trackerGetAddress( tor->tracker );
/* peers... */
memset( s->peersFrom, 0, sizeof( s->peersFrom ) );
@ -705,10 +745,11 @@ tr_torrentStat( tr_torrent_t * tor )
? tr_rcRate( tor->download )
: 0.0;
s->rateUpload = tr_rcRate( tor->upload );
s->seeders = tr_trackerSeeders( tc );
s->leechers = tr_trackerLeechers( tc );
s->completedFromTracker = tr_trackerDownloaded( tc );
tr_trackerGetCounts( tc,
&s->completedFromTracker,
&s->leechers,
&s->seeders );
s->swarmspeed = tr_rcRate( tor->swarmspeed );
@ -994,7 +1035,7 @@ int tr_torrentAttachPeer( tr_torrent_t * tor, tr_peer_t * peer )
}
int tr_torrentAddCompact( tr_torrent_t * tor, int from,
uint8_t * buf, int count )
const uint8_t * buf, int count )
{
struct in_addr addr;
tr_port_t port;
@ -1002,15 +1043,16 @@ int tr_torrentAddCompact( tr_torrent_t * tor, int from,
tr_peer_t * peer;
added = 0;
for( i = 0; i < count; i++ )
for( i=0; i<count; ++i )
{
memcpy( &addr, buf, 4 ); buf += 4;
memcpy( &port, buf, 2 ); buf += 2;
peer = tr_peerInit( &addr, port, -1, from );
added += tr_torrentAttachPeer( tor, peer );
}
tr_inf( "tr_torrentAddCompact %d peers to %s", added, tor->info.name );
return added;
}
@ -1028,6 +1070,8 @@ static void setRunState( tr_torrent_t * tor, run_status_t run )
void tr_torrentStart( tr_torrent_t * tor )
{
setRunState( tor, TR_RUN_RUNNING );
tr_trackerStart( tor->tracker );
}
void tr_torrentStop( tr_torrent_t * tor )
@ -1058,6 +1102,10 @@ tr_torrentFree( tr_torrent_t * tor )
tr_rcClose( tor->download );
tr_rcClose( tor->swarmspeed );
tr_trackerUnsubscribe( tor->tracker, tor->trackerSubscription );
tr_trackerFree( tor->tracker );
tor->tracker = NULL;
tr_free( tor->destination );
tr_metainfoFree( inf );
@ -1093,7 +1141,6 @@ recheckCpState( tr_torrent_t * tor )
tor->cpStatus = cpStatus;
tor->hasChangedState = tor->cpStatus; /* tell the client... */
if( (cpStatus == TR_CP_COMPLETE) /* ...and if we're complete */
&& tor->tracker!=NULL /* and we have a tracker */
&& tor->downloadedCur ) { /* and it just happened */
tr_trackerCompleted( tor->tracker ); /* tell the tracker */
}
@ -1129,8 +1176,6 @@ torrentThreadLoop ( void * _tor )
if( tor->runStatus == TR_RUN_STOPPING )
{
int i;
int peerCount;
uint8_t * peerCompact;
tr_torrentWriterLock( tor );
/* close the IO */
@ -1149,8 +1194,7 @@ torrentThreadLoop ( void * _tor )
tr_rcReset( tor->swarmspeed );
/* tell the tracker we're stopping */
tr_trackerStopped( tor->tracker );
tr_trackerPulse( tor->tracker, &peerCount, &peerCompact );
tr_trackerStop( tor->tracker );
tor->runStatus = TR_RUN_STOPPING_NET_WAIT;
tor->stopDate = tr_date();
tr_torrentWriterUnlock( tor );
@ -1158,21 +1202,11 @@ torrentThreadLoop ( void * _tor )
if( tor->runStatus == TR_RUN_STOPPING_NET_WAIT )
{
uint64_t date;
int peerCount;
uint8_t * peerCompact;
tr_trackerPulse( tor->tracker, &peerCount, &peerCompact );
/* have we finished telling the tracker that we're stopping? */
date = tr_trackerLastResponseDate( tor->tracker );
if( date > tor->stopDate )
{
tr_torrentWriterLock( tor );
tr_trackerClose( tor->tracker );
tor->tracker = NULL;
tor->runStatus = TR_RUN_STOPPED;
tr_torrentWriterUnlock( tor );
}
#if 0
tr_torrentWriterLock( tor );
tor->runStatus = TR_RUN_STOPPED;
tr_torrentWriterUnlock( tor );
#endif
continue;
}
@ -1208,31 +1242,19 @@ torrentThreadLoop ( void * _tor )
if( tor->runStatus == TR_RUN_RUNNING )
{
int i;
int peerCount;
uint8_t * peerCompact;
/* starting to run... */
if( tor->io == NULL ) {
if( tor->io == NULL )
{
*tor->errorString = '\0';
tr_torrentResetTransferStats( tor );
tor->io = tr_ioNew( tor );
tr_peerIdNew ( tor->peer_id, sizeof(tor->peer_id) );
tor->tracker = tr_trackerInit( tor );
tor->startDate = tr_date();
}
/* refresh our completion state */
recheckCpState( tor );
/* ping the tracker... */
tr_trackerPulse( tor->tracker, &peerCount, &peerCompact );
if( peerCount > 0 ) {
int used = tr_torrentAddCompact( tor, TR_PEER_FROM_TRACKER,
peerCompact, peerCount );
tr_dbg( "got %i peers from announce, used %i", peerCount, used );
free( peerCompact );
}
/* Shuffle peers */
if ( tor->peerCount > 1 ) {
tr_peer_t * tmp = tor->peers[0];

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +1,86 @@
/******************************************************************************
* $Id$
/*
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
*
* Copyright (c) 2005-2006 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
* This file is licensed by the GPL version 2. Works owned by the
* Transmission project are granted a special exemption to clause 2(b)
* so that the bulk of its code can remain under the MIT license.
* This exemption does not extend to derived works not owned by
* the Transmission project.
*/
#ifndef TR_TRACKER_H
#define TR_TRACKER_H 1
#ifndef _TR_TRACKER_H_
#define _TR_TRACKER_H_
typedef struct tr_tracker_s tr_tracker_t;
#include <inttypes.h> /* for uint8_t */
#include "transmission.h"
#include "publish.h"
tr_tracker_t * tr_trackerInit ( tr_torrent_t * );
/**
*** Locating a tracker
**/
void tr_trackerPulse ( tr_tracker_t *,
int * peerCount,
uint8_t ** peerCompact );
struct tr_tracker_s * tr_trackerNew( tr_torrent_t * );
void tr_trackerCompleted( tr_tracker_t * );
void tr_trackerStopped ( tr_tracker_t * );
void tr_trackerClose ( tr_tracker_t * );
void tr_trackerFree ( struct tr_tracker_s * );
/* if a tracker is running, enqueue a manual announce. */
void tr_trackerManualAnnounce( tr_tracker_t * );
/**
*** Tracker Publish / Subscribe
**/
int tr_trackerCanManualAnnounce( const tr_tracker_t * );
typedef enum
{
TR_TRACKER_WARNING,
TR_TRACKER_ERROR,
TR_TRACKER_PEERS,
TR_TRACKER_STOPPED
}
TrackerEventType;
/***********************************************************************
* tr_trackerSeeders
***********************************************************************
* Looks for the seeders as returned by the tracker.
**********************************************************************/
int tr_trackerSeeders ( const tr_tracker_t * );
typedef struct
{
/* what type of event this is */
TrackerEventType messageType;
/***********************************************************************
* tr_trackerLeechers
***********************************************************************
* Looks for the leechers as returned by the tracker.
**********************************************************************/
int tr_trackerLeechers ( const tr_tracker_t * );
/* the torrent's 20-character sha1 hash */
const uint8_t * hash;
/***********************************************************************
* tr_trackerDownloaded
***********************************************************************
* Looks for number of completed downloads as returned by the tracker
* (from scrape).
**********************************************************************/
int tr_trackerDownloaded( const tr_tracker_t * tc );
/* for TR_TRACKER_WARNING and TR_TRACKER_ERROR */
const char * text;
/***********************************************************************
* tr_trackerGet
***********************************************************************
* Return the tracker currently in use.
**********************************************************************/
const tr_tracker_info_t * tr_trackerGet( const tr_tracker_t * tc );
/* for TR_TRACKER_PEERS */
const uint8_t * peerCompact;
int peerCount;
}
tr_tracker_event_t;
int tr_trackerCannotConnect( const tr_tracker_t * tc );
tr_publisher_tag tr_trackerSubscribe ( struct tr_tracker_s * tag,
tr_delivery_func func,
void * user );
/* the time of the tracker's last message to us */
uint64_t tr_trackerLastResponseDate ( const tr_tracker_t * );
void tr_trackerUnsubscribe ( struct tr_tracker_s * tracker,
tr_publisher_tag tag );
/***
****
***/
#if 0
/***********************************************************************
* tr_trackerScrape
***********************************************************************
* Attempt a blocking scrape and return the seeders, leechers, and
* completed downloads if successful.
**********************************************************************/
int tr_trackerScrape( tr_torrent_t * tor, int * s, int * l, int * d );
#endif
void tr_trackerStart ( struct tr_tracker_s * );
void tr_trackerCompleted ( struct tr_tracker_s * );
void tr_trackerStop ( struct tr_tracker_s * );
void tr_trackerReannounce ( struct tr_tracker_s * );
void tr_trackerChangeMyPort ( struct tr_tracker_s * );
const tr_tracker_info_t * tr_trackerGetAddress( const struct tr_tracker_s * );
int tr_trackerCanManualAnnounce ( const struct tr_tracker_s * );
void tr_trackerGetCounts ( const struct tr_tracker_s *,
int * setme_completedCount,
int * setme_leecherCount,
int * setme_seederCount );
#endif

View File

@ -93,30 +93,19 @@ tr_handle_t * tr_init( const char * tag )
tr_netResolveThreadInit();
h = calloc( 1, sizeof( tr_handle_t ) );
if( NULL == h )
{
if( !h )
return NULL;
}
h->tag = strdup( tag );
if( NULL == h->tag )
{
if( !h->tag ) {
free( h );
return NULL;
}
/* Random key */
for( i=0; i < TR_KEY_LEN; ++i )
{
const int r = tr_rand( 36 );
h->key[i] = ( r < 26 ) ? ( 'a' + r ) : ( '0' + r - 26 ) ;
}
/* Azureus identity */
for( i=0; i < TR_AZ_ID_LEN; ++i )
{
h->azId[i] = tr_rand( 0xff );
}
#ifndef WIN32
/* Don't exit when writing on a broken socket */

View File

@ -551,6 +551,7 @@ struct tr_info_s
int count;
} * trackerList;
int trackerTiers;
char * primaryAddress;
/* Torrent info */
char comment[MAX_PATH_LENGTH];
@ -606,7 +607,6 @@ struct tr_stat_s
int error;
char errorString[128];
int cannotConnect;
const tr_tracker_info_t * tracker;