diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index d143dd831..f00147fac 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -360,16 +360,15 @@ peerDestructor( tr_peer * peer ) } static void -removePeer( Torrent * t, - tr_peer * peer ) +removePeer( Torrent * t, tr_peer * peer ) { - tr_peer * removed; - struct peer_atom * atom; + tr_peer * removed; + struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); assert( torrentIsLocked( t ) ); - - atom = getExistingAtom( t, &peer->addr ); assert( atom ); + atom->time = time( NULL ); removed = tr_ptrArrayRemoveSorted( &t->peers, peer, peerCompare ); @@ -911,8 +910,7 @@ broadcastGotBlock( Torrent * t, uint32_t index, uint32_t offset, uint32_t length } static void -addStrike( Torrent * t, - tr_peer * peer ) +addStrike( Torrent * t, tr_peer * peer ) { tordbg( t, "increasing peer %s strike count to %d", tr_peerIoAddrStr( &peer->addr, @@ -920,7 +918,8 @@ addStrike( Torrent * t, if( ++peer->strikes >= MAX_BAD_PIECES_PER_PEER ) { - struct peer_atom * atom = getExistingAtom( t, &peer->addr ); + struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); atom->myflags |= MYFLAG_BANNED; peer->doPurge = 1; tordbg( t, "banning peer %s", tr_peerIoAddrStr( &atom->addr, atom->port ) ); @@ -1009,8 +1008,8 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) case TR_PEER_UPLOAD_ONLY: /* update our atom */ if( peer ) { - struct peer_atom * a = getExistingAtom( t, &peer->addr ); - a->uploadOnly = e->uploadOnly ? UPLOAD_ONLY_YES : UPLOAD_ONLY_NO; +assert( peer->atom == getExistingAtom( t, &peer->addr ) ); + peer->atom->uploadOnly = e->uploadOnly ? UPLOAD_ONLY_YES : UPLOAD_ONLY_NO; } break; @@ -1037,10 +1036,9 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) tr_statsAddUploaded( tor->session, e->length ); /* update our atom */ - if( peer ) { - struct peer_atom * a = getExistingAtom( t, &peer->addr ); - if( e->wasPieceData ) - a->piece_data_time = now; + if( peer && e->wasPieceData ) { +assert( peer->atom == getExistingAtom( t, &peer->addr ) ); + peer->atom->piece_data_time = now; } tor->needsSeedRatioCheck = TRUE; @@ -1079,10 +1077,9 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) tr_statsAddDownloaded( tor->session, e->length ); /* update our atom */ - if( peer ) { - struct peer_atom * a = getExistingAtom( t, &peer->addr ); - if( e->wasPieceData ) - a->piece_data_time = now; + if( peer && e->wasPieceData ) { +assert( peer->atom == getExistingAtom( t, &peer->addr ) ); + peer->atom->piece_data_time = now; } break; @@ -1092,8 +1089,9 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) { if( peer ) { - struct peer_atom * atom = getExistingAtom( t, &peer->addr ); + struct peer_atom * atom = peer->atom; const int peerIsSeed = e->progress >= 1.0; +assert( peer->atom == getExistingAtom( t, &peer->addr ) ); if( peerIsSeed ) { tordbg( t, "marking peer %s as a seed", tr_peerIoAddrStr( &atom->addr, atom->port ) ); atom->flags |= ADDED_F_SEED_FLAG; @@ -1317,6 +1315,7 @@ myHandshakeDoneCB( tr_handshake * handshake, } peer->port = port; + peer->atom = atom; peer->io = tr_handshakeStealIO( handshake ); /* this steals its refcount too, which is balanced by our unref in peerDestructor() */ tr_peerIoSetParent( peer->io, t->tor->bandwidth ); @@ -1554,7 +1553,8 @@ tr_peerMgrGetPeers( tr_torrent * tor, const tr_peer * peer = peers[i]; if( peer->addr.type == af ) { - const struct peer_atom * atom = getExistingAtom( t, &peer->addr ); + const struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); assert( tr_isAddress( &peer->addr ) ); walk->addr = peer->addr; @@ -1745,7 +1745,8 @@ tr_peerMgrTorrentStats( tr_torrent * tor, for( i=0; iaddr ); + const struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); if( peer->io == NULL ) /* not connected */ continue; @@ -1825,12 +1826,13 @@ tr_peerMgrPeerStats( const tr_torrent * tor, ret = tr_new0( tr_peer_stat, size ); now = tr_date( ); - for( i = 0; i < size; ++i ) + for( i=0; iaddr ); + const struct peer_atom * atom = peer->atom; tr_peer_stat * stat = ret + i; +assert( atom == getExistingAtom( t, &peer->addr ) ); tr_ntop( &peer->addr, stat->addr, sizeof( stat->addr ) ); tr_strlcpy( stat->client, ( peer->client ? peer->client : "" ), @@ -1932,7 +1934,8 @@ rechokeTorrent( Torrent * t ) for( i = 0, size = 0; i < peerCount; ++i ) { tr_peer * peer = peers[i]; - struct peer_atom * atom = getExistingAtom( t, &peer->addr ); + struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); if( peer->progress >= 1.0 ) /* choke all seeds */ { @@ -2051,7 +2054,8 @@ shouldPeerBeClosed( const Torrent * t, { const tr_torrent * tor = t->tor; const time_t now = time( NULL ); - const struct peer_atom * atom = getExistingAtom( t, &peer->addr ); + const struct peer_atom * atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); /* if it's marked for purging, close it */ if( peer->doPurge ) @@ -2255,10 +2259,12 @@ closePeer( Torrent * t, tr_peer * peer ) assert( t != NULL ); assert( peer != NULL ); + atom = peer->atom; +assert( atom == getExistingAtom( t, &peer->addr ) ); + /* if we transferred piece data, then they might be good peers, so reset their `numFails' weight to zero. otherwise we connected to them fruitlessly, so mark it as another fail */ - atom = getExistingAtom( t, &peer->addr ); if( atom->piece_data_time ) atom->numFails = 0; else diff --git a/libtransmission/peer-mgr.h b/libtransmission/peer-mgr.h index fd4063bb8..cb0f61195 100644 --- a/libtransmission/peer-mgr.h +++ b/libtransmission/peer-mgr.h @@ -60,6 +60,9 @@ enum ENCRYPTION_PREFERENCE_NO }; +/* opaque forward declaration */ +struct peer_atom; + /** * State information about a connected peer. * @@ -81,6 +84,7 @@ typedef struct tr_peer tr_port port; tr_address addr; struct tr_peerIo * io; + struct peer_atom * atom; struct tr_bitfield * blame; struct tr_bitfield * have;