"corruption" fix part 2: lots of assertions, and try to complete pieces & ban bad peers sooner

This commit is contained in:
Charles Kerr 2007-10-31 04:23:51 +00:00
parent 4584417bf0
commit a6206b036c
5 changed files with 33 additions and 11 deletions

View File

@ -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 )

View File

@ -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 )

View File

@ -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;

View File

@ -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 );

View File

@ -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