mirror of
https://github.com/transmission/transmission
synced 2025-03-15 16:29:34 +00:00
"corruption" fix part 2: lots of assertions, and try to complete pieces & ban bad peers sooner
This commit is contained in:
parent
4584417bf0
commit
a6206b036c
5 changed files with 33 additions and 11 deletions
|
@ -137,7 +137,11 @@ tr_cpInvalidateDND ( tr_completion * cp )
|
|||
int
|
||||
tr_cpPieceIsComplete( const tr_completion * cp, int piece )
|
||||
{
|
||||
return cp->completeBlocks[piece] >= tr_torPieceCountBlocks(cp->tor,piece);
|
||||
assert( piece >= 0 );
|
||||
assert( piece < cp->tor->info.pieceCount );
|
||||
assert( cp->completeBlocks[piece] <= tr_torPieceCountBlocks(cp->tor,piece) );
|
||||
|
||||
return cp->completeBlocks[piece] == tr_torPieceCountBlocks(cp->tor,piece);
|
||||
}
|
||||
|
||||
const tr_bitfield * tr_cpPieceBitfield( const tr_completion * cp )
|
||||
|
|
|
@ -207,9 +207,9 @@ tr_ioWrite( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf
|
|||
****/
|
||||
|
||||
static int
|
||||
tr_ioRecalculateHash ( tr_torrent * tor,
|
||||
int pieceIndex,
|
||||
uint8_t * setme )
|
||||
tr_ioRecalculateHash( tr_torrent * tor,
|
||||
int pieceIndex,
|
||||
uint8_t * setme )
|
||||
{
|
||||
int n;
|
||||
int ret;
|
||||
|
@ -223,17 +223,17 @@ tr_ioRecalculateHash ( tr_torrent * tor,
|
|||
info = &tor->info;
|
||||
n = tr_torPieceCountBytes( tor, pieceIndex );
|
||||
|
||||
buf = malloc( n );
|
||||
ret = readOrWritePiece ( tor, TR_IO_READ, pieceIndex, 0, buf, n );
|
||||
buf = tr_new( uint8_t, n );
|
||||
ret = tr_ioRead( tor, pieceIndex, 0, n, buf );
|
||||
if( !ret )
|
||||
tr_sha1( setme, buf, n, NULL );
|
||||
free( buf );
|
||||
tr_free( buf );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
checkPiece ( tr_torrent * tor, int pieceIndex )
|
||||
checkPiece( tr_torrent * tor, int pieceIndex )
|
||||
{
|
||||
uint8_t hash[SHA_DIGEST_LENGTH];
|
||||
int ret = tr_ioRecalculateHash( tor, pieceIndex, hash )
|
||||
|
|
|
@ -544,6 +544,7 @@ getConnectedPeers( Torrent * t, int * setmeCount )
|
|||
struct tr_refill_piece
|
||||
{
|
||||
tr_priority_t priority;
|
||||
int percentDone;
|
||||
uint16_t random;
|
||||
uint32_t piece;
|
||||
uint32_t peerCount;
|
||||
|
@ -566,6 +567,10 @@ compareRefillPiece (const void * aIn, const void * bIn)
|
|||
/* if one piece has a higher priority, it goes first */
|
||||
if (a->priority != b->priority)
|
||||
return a->priority > b->priority ? -1 : 1;
|
||||
|
||||
/* try to fill partial pieces */
|
||||
if( a->percentDone != b->percentDone )
|
||||
return a->percentDone > b->percentDone ? -1 : 1;
|
||||
|
||||
/* otherwise if one has fewer peers, it goes first */
|
||||
if (a->peerCount != b->peerCount)
|
||||
|
@ -625,6 +630,7 @@ getPreferredPieces( Torrent * t,
|
|||
setme->peerCount = 0;
|
||||
setme->fastAllowed = 0;
|
||||
setme->random = tr_rand( UINT16_MAX );
|
||||
setme->percentDone = (int)( 100.0 * tr_cpPercentBlocksInPiece( tor->completion, piece ) );
|
||||
|
||||
for( k=0; k<peerCount; ++k ) {
|
||||
const tr_peer * peer = peers[k];
|
||||
|
@ -637,7 +643,7 @@ getPreferredPieces( Torrent * t,
|
|||
}
|
||||
}
|
||||
|
||||
qsort (p, poolSize, sizeof(struct tr_refill_piece), compareRefillPiece);
|
||||
qsort( p, poolSize, sizeof(struct tr_refill_piece), compareRefillPiece );
|
||||
|
||||
for( j=0; j<poolSize; ++j )
|
||||
pool[j] = p[j].piece;
|
||||
|
|
|
@ -937,7 +937,7 @@ messageLengthIsCorrect( const tr_peermsgs * msg, uint8_t id, uint32_t len )
|
|||
return len==13;
|
||||
|
||||
case BT_PIECE:
|
||||
return len > 9;
|
||||
return len>9 && len<=16393;
|
||||
|
||||
case BT_PORT:
|
||||
return len==3;
|
||||
|
@ -1210,7 +1210,7 @@ gotBlock( tr_peermsgs * msgs,
|
|||
dbgmsg( msgs, "we didn't ask for this message..." );
|
||||
return;
|
||||
}
|
||||
dbgmsg( msgs, "Got block %u:%u->%u (turnaround time %d secs)",
|
||||
dbgmsg( msgs, "got block %u:%u->%u (turnaround time %d secs)",
|
||||
req->index, req->offset, req->length,
|
||||
(int)(time(NULL) - req->time_requested) );
|
||||
tr_free( req );
|
||||
|
@ -1242,6 +1242,15 @@ gotBlock( tr_peermsgs * msgs,
|
|||
if( tr_ioWrite( tor, index, offset, length, EVBUFFER_DATA( inbuf )))
|
||||
return;
|
||||
|
||||
#warning this sanity check is here to help track down the excess corrupt data bug, but is expensive and should be removed before the next release
|
||||
{
|
||||
uint8_t * tmp = tr_new( uint8_t, length );
|
||||
const int val = tr_ioRead( tor, index, offset, length, tmp );
|
||||
assert( !val );
|
||||
assert( !memcmp( tmp, EVBUFFER_DATA(inbuf), length ) );
|
||||
tr_free( tmp );
|
||||
}
|
||||
|
||||
tr_cpBlockAdd( tor->completion, block );
|
||||
|
||||
addUsToBlamefield( msgs, index );
|
||||
|
|
|
@ -787,6 +787,7 @@ tr_bitfieldAdd( tr_bitfield * bitfield, size_t nth )
|
|||
{
|
||||
static const uint8_t ands[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
|
||||
bitfield->bits[nth>>3u] |= ands[nth&7u];
|
||||
assert( tr_bitfieldHas( bitfield, nth ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -808,6 +809,8 @@ tr_bitfieldRem( tr_bitfield * bitfield,
|
|||
|
||||
if( bitfield != NULL )
|
||||
bitfield->bits[nth>>3u] &= rems[nth&7u];
|
||||
|
||||
assert( !tr_bitfieldHas( bitfield, nth ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue