mirror of
https://github.com/transmission/transmission
synced 2025-02-23 14:40:43 +00:00
this should improve download speeds. test it!
This commit is contained in:
parent
f3c153234f
commit
e371009606
3 changed files with 90 additions and 75 deletions
|
@ -30,7 +30,7 @@
|
||||||
#define IO_TIMEOUT_SECS 8
|
#define IO_TIMEOUT_SECS 8
|
||||||
|
|
||||||
/* arbitrary */
|
/* arbitrary */
|
||||||
#define TR_RDBUF (1024*3)
|
#define TR_RDBUF (1024*8)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
***
|
***
|
||||||
|
@ -407,8 +407,9 @@ void
|
||||||
tr_peerIoWriteBuf( tr_peerIo * io,
|
tr_peerIoWriteBuf( tr_peerIo * io,
|
||||||
struct evbuffer * buf )
|
struct evbuffer * buf )
|
||||||
{
|
{
|
||||||
tr_peerIoWrite( io, EVBUFFER_DATA(buf), EVBUFFER_LENGTH(buf) );
|
const size_t n = EVBUFFER_LENGTH( buf );
|
||||||
evbuffer_drain( buf, ~0 );
|
tr_peerIoWrite( io, EVBUFFER_DATA(buf), n );
|
||||||
|
evbuffer_drain( buf, n );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1593,28 +1593,28 @@ swiftPulse( void * vtorrent )
|
||||||
tr_peer ** peers = getConnectedPeers( t, &peerCount );
|
tr_peer ** peers = getConnectedPeers( t, &peerCount );
|
||||||
tr_peer ** deadbeats = tr_new( tr_peer*, peerCount );
|
tr_peer ** deadbeats = tr_new( tr_peer*, peerCount );
|
||||||
|
|
||||||
for( i=0; i<peerCount; ++i ) {
|
|
||||||
tr_peer * peer = peers[i];
|
|
||||||
if( peer->credit < 0 )
|
|
||||||
deadbeats[deadbeatCount++] = peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( deadbeatCount )
|
|
||||||
{
|
|
||||||
const double ul_KiBsec = tr_rcRate( t->tor->upload );
|
const double ul_KiBsec = tr_rcRate( t->tor->upload );
|
||||||
const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0);
|
const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0);
|
||||||
const double ul_bytes = ul_KiB * 1024;
|
const double ul_bytes = ul_KiB * 1024;
|
||||||
const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE;
|
const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE;
|
||||||
const int freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount );
|
int freeCreditPerPeer;
|
||||||
|
|
||||||
|
for( i=0; i<peerCount; ++i ) {
|
||||||
|
tr_peer * peer = peers[i];
|
||||||
|
if( peer->credit <= 0 )
|
||||||
|
deadbeats[deadbeatCount++] = peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount );
|
||||||
for( i=0; i<deadbeatCount; ++i )
|
for( i=0; i<deadbeatCount; ++i )
|
||||||
deadbeats[i]->credit = freeCreditPerPeer;
|
deadbeats[i]->credit = freeCreditPerPeer;
|
||||||
|
|
||||||
tordbg( t, "%d deadbeats, "
|
tordbg( t, "%d deadbeats, "
|
||||||
"who are each being granted %d bytes' credit "
|
"who are each being granted %d bytes' credit "
|
||||||
"for a total of %.1f KiB, "
|
"for a total of %.1f KiB, "
|
||||||
"%d%% of the torrent's ul speed %.1f\n",
|
"%d%% of the torrent's ul speed %.1f\n",
|
||||||
deadbeatCount, freeCreditPerPeer,
|
deadbeatCount, freeCreditPerPeer,
|
||||||
ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec );
|
ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec );
|
||||||
}
|
|
||||||
|
|
||||||
tr_free( deadbeats );
|
tr_free( deadbeats );
|
||||||
tr_free( peers );
|
tr_free( peers );
|
||||||
|
@ -1731,29 +1731,37 @@ getPeerCandidates( Torrent * t, int * setmeSize )
|
||||||
/* peer fed us too much bad data ... we only keep it around
|
/* peer fed us too much bad data ... we only keep it around
|
||||||
* now to weed it out in case someone sends it to us via pex */
|
* now to weed it out in case someone sends it to us via pex */
|
||||||
if( atom->myflags & MYFLAG_BANNED ) {
|
if( atom->myflags & MYFLAG_BANNED ) {
|
||||||
|
#if 0
|
||||||
tordbg( t, "RECONNECT peer %d (%s) is banned...",
|
tordbg( t, "RECONNECT peer %d (%s) is banned...",
|
||||||
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't need two connections to the same peer... */
|
/* we don't need two connections to the same peer... */
|
||||||
if( peerIsInUse( t, &atom->addr ) ) {
|
if( peerIsInUse( t, &atom->addr ) ) {
|
||||||
|
#if 0
|
||||||
tordbg( t, "RECONNECT peer %d (%s) is in use..",
|
tordbg( t, "RECONNECT peer %d (%s) is in use..",
|
||||||
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no need to connect if we're both seeds... */
|
/* no need to connect if we're both seeds... */
|
||||||
if( seed && (atom->flags & ADDED_F_SEED_FLAG) ) {
|
if( seed && (atom->flags & ADDED_F_SEED_FLAG) ) {
|
||||||
|
#if 0
|
||||||
tordbg( t, "RECONNECT peer %d (%s) is a seed and so are we..",
|
tordbg( t, "RECONNECT peer %d (%s) is a seed and so are we..",
|
||||||
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we're wasting our time trying to connect to this bozo. */
|
/* we're wasting our time trying to connect to this bozo. */
|
||||||
if( atom->numFails > 10 ) {
|
if( atom->numFails > 10 ) {
|
||||||
|
#if 0
|
||||||
tordbg( t, "RECONNECT peer %d (%s) gives us nothing but failure.",
|
tordbg( t, "RECONNECT peer %d (%s) gives us nothing but failure.",
|
||||||
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
i, tr_peerIoAddrStr(&atom->addr,atom->port) );
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ struct tr_peermsgs
|
||||||
unsigned int peerSupportsPex : 1;
|
unsigned int peerSupportsPex : 1;
|
||||||
unsigned int clientSentLtepHandshake : 1;
|
unsigned int clientSentLtepHandshake : 1;
|
||||||
unsigned int peerSentLtepHandshake : 1;
|
unsigned int peerSentLtepHandshake : 1;
|
||||||
|
unsigned int sendingBlock : 1;
|
||||||
|
|
||||||
tr_bitfield * clientAllowedPieces;
|
tr_bitfield * clientAllowedPieces;
|
||||||
tr_bitfield * peerAllowedPieces;
|
tr_bitfield * peerAllowedPieces;
|
||||||
|
@ -565,6 +566,8 @@ pumpRequestQueue( tr_peermsgs * msgs )
|
||||||
while( ( count < max ) && ( msgs->clientWillAskFor != NULL ) )
|
while( ( count < max ) && ( msgs->clientWillAskFor != NULL ) )
|
||||||
{
|
{
|
||||||
struct peer_request * r = tr_list_pop_front( &msgs->clientWillAskFor );
|
struct peer_request * r = tr_list_pop_front( &msgs->clientWillAskFor );
|
||||||
|
assert( requestIsValid( msgs, r ) );
|
||||||
|
assert( tr_bitfieldHas( msgs->info->have, r->index ) );
|
||||||
protocolSendRequest( msgs, r );
|
protocolSendRequest( msgs, r );
|
||||||
r->time_requested = msgs->lastReqAddedAt = time( NULL );
|
r->time_requested = msgs->lastReqAddedAt = time( NULL );
|
||||||
tr_list_append( &msgs->clientAskedFor, r );
|
tr_list_append( &msgs->clientAskedFor, r );
|
||||||
|
@ -639,7 +642,6 @@ tr_peerMsgsAddRequest( tr_peermsgs * msgs,
|
||||||
req = tr_new0( struct peer_request, 1 );
|
req = tr_new0( struct peer_request, 1 );
|
||||||
*req = tmp;
|
*req = tmp;
|
||||||
tr_list_append( &msgs->clientWillAskFor, req );
|
tr_list_append( &msgs->clientWillAskFor, req );
|
||||||
pulse( msgs );
|
|
||||||
return TR_ADDREQ_OK;
|
return TR_ADDREQ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1442,15 +1444,7 @@ static int
|
||||||
canWrite( const tr_peermsgs * msgs )
|
canWrite( const tr_peermsgs * msgs )
|
||||||
{
|
{
|
||||||
/* don't let our outbuffer get too large */
|
/* don't let our outbuffer get too large */
|
||||||
if( tr_peerIoWriteBytesWaiting( msgs->io ) > 4096 )
|
return tr_peerIoWriteBytesWaiting( msgs->io ) < 4096;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* SWIFT */
|
|
||||||
if( SWIFT_ENABLED && !tr_torrentIsSeed( msgs->torrent )
|
|
||||||
&& ( msgs->info->credit < 0 ) )
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
|
@ -1458,18 +1452,22 @@ getUploadMax( const tr_peermsgs * msgs )
|
||||||
{
|
{
|
||||||
static const size_t maxval = ~0;
|
static const size_t maxval = ~0;
|
||||||
const tr_torrent * tor = msgs->torrent;
|
const tr_torrent * tor = msgs->torrent;
|
||||||
|
const int useSwift = SWIFT_ENABLED && !tr_torrentIsSeed( msgs->torrent );
|
||||||
|
const size_t swiftBytes = msgs->info->credit;
|
||||||
|
size_t speedBytes;
|
||||||
|
|
||||||
if( !canWrite( msgs ) )
|
if( !canWrite( msgs ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( tor->uploadLimitMode == TR_SPEEDLIMIT_GLOBAL )
|
if( tor->uploadLimitMode == TR_SPEEDLIMIT_GLOBAL )
|
||||||
return tor->handle->useUploadLimit
|
speedBytes = tor->handle->useUploadLimit ? tr_rcBytesLeft( tor->handle->upload ) : maxval;
|
||||||
? tr_rcBytesLeft( tor->handle->upload ) : maxval;
|
else if( tor->uploadLimitMode == TR_SPEEDLIMIT_SINGLE )
|
||||||
|
speedBytes = tr_rcBytesLeft( tor->upload );
|
||||||
|
else
|
||||||
|
speedBytes = ~0;
|
||||||
|
|
||||||
if( tor->uploadLimitMode == TR_SPEEDLIMIT_SINGLE )
|
return useSwift ? MIN( speedBytes, swiftBytes )
|
||||||
return tr_rcBytesLeft( tor->upload );
|
: speedBytes;
|
||||||
|
|
||||||
return maxval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1533,32 +1531,36 @@ pulse( void * vmsgs )
|
||||||
pumpRequestQueue( msgs );
|
pumpRequestQueue( msgs );
|
||||||
updatePeerStatus( msgs );
|
updatePeerStatus( msgs );
|
||||||
|
|
||||||
if( !canWrite( msgs ) )
|
if( msgs->sendingBlock )
|
||||||
{
|
|
||||||
}
|
|
||||||
else if(( len = EVBUFFER_LENGTH( msgs->outBlock ) ))
|
|
||||||
{
|
{
|
||||||
const size_t uploadMax = getUploadMax( msgs );
|
const size_t uploadMax = getUploadMax( msgs );
|
||||||
|
size_t len = EVBUFFER_LENGTH( msgs->outBlock );
|
||||||
const size_t outlen = MIN( len, uploadMax );
|
const size_t outlen = MIN( len, uploadMax );
|
||||||
|
|
||||||
|
assert( len );
|
||||||
|
|
||||||
|
if( outlen && canWrite( msgs ) )
|
||||||
|
{
|
||||||
tr_peerIoWrite( msgs->io, EVBUFFER_DATA( msgs->outBlock ), outlen );
|
tr_peerIoWrite( msgs->io, EVBUFFER_DATA( msgs->outBlock ), outlen );
|
||||||
evbuffer_drain( msgs->outBlock, outlen );
|
evbuffer_drain( msgs->outBlock, outlen );
|
||||||
msgs->clientSentAnythingAt = now;
|
|
||||||
peerGotBytes( msgs, outlen );
|
peerGotBytes( msgs, outlen );
|
||||||
|
|
||||||
len -= outlen;
|
len -= outlen;
|
||||||
|
msgs->clientSentAnythingAt = now;
|
||||||
|
msgs->sendingBlock = len!=0;
|
||||||
|
|
||||||
dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len );
|
dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len );
|
||||||
fflush( stdout );
|
|
||||||
}
|
}
|
||||||
else if(( len = EVBUFFER_LENGTH( msgs->outMessages ) ))
|
}
|
||||||
|
|
||||||
|
if( !msgs->sendingBlock )
|
||||||
|
{
|
||||||
|
if(( len = EVBUFFER_LENGTH( msgs->outMessages ) ))
|
||||||
{
|
{
|
||||||
tr_peerIoWriteBuf( msgs->io, msgs->outMessages );
|
tr_peerIoWriteBuf( msgs->io, msgs->outMessages );
|
||||||
msgs->clientSentAnythingAt = now;
|
msgs->clientSentAnythingAt = now;
|
||||||
}
|
}
|
||||||
else if( ( now - msgs->clientSentAnythingAt ) > KEEPALIVE_INTERVAL_SECS )
|
else if( !EVBUFFER_LENGTH( msgs->outBlock )
|
||||||
{
|
|
||||||
sendKeepalive( msgs );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !EVBUFFER_LENGTH( msgs->outBlock )
|
|
||||||
&& (( r = popNextRequest( msgs )))
|
&& (( r = popNextRequest( msgs )))
|
||||||
&& requestIsValid( msgs, r )
|
&& requestIsValid( msgs, r )
|
||||||
&& tr_cpPieceIsComplete( msgs->torrent->completion, r->index ) )
|
&& tr_cpPieceIsComplete( msgs->torrent->completion, r->index ) )
|
||||||
|
@ -1576,12 +1578,16 @@ pulse( void * vmsgs )
|
||||||
tr_peerIoWriteUint32( io, out, r->index );
|
tr_peerIoWriteUint32( io, out, r->index );
|
||||||
tr_peerIoWriteUint32( io, out, r->offset );
|
tr_peerIoWriteUint32( io, out, r->offset );
|
||||||
tr_peerIoWriteBytes ( io, out, buf, r->length );
|
tr_peerIoWriteBytes ( io, out, buf, r->length );
|
||||||
|
msgs->sendingBlock = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free( buf );
|
tr_free( buf );
|
||||||
tr_free( r );
|
tr_free( r );
|
||||||
|
}
|
||||||
pulse( msgs ); /* start sending it right away */
|
else if( ( now - msgs->clientSentAnythingAt ) > KEEPALIVE_INTERVAL_SECS )
|
||||||
|
{
|
||||||
|
sendKeepalive( msgs );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE; /* loop forever */
|
return TRUE; /* loop forever */
|
||||||
|
|
Loading…
Reference in a new issue