diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 922656c1d..501bab4d6 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -130,6 +130,7 @@ struct peer_atom uint16_t numFails; struct in_addr addr; time_t time; + time_t piece_data_time; }; typedef struct @@ -917,6 +918,12 @@ msgsCallbackFunc( void * vpeer, void * vevent, void * vt ) tr_bitfieldRem( t->requested, _tr_block( t->tor, e->pieceIndex, e->offset ) ); break; + case TR_PEERMSG_PIECE_DATA: { + struct peer_atom * atom = getExistingAtom( t, &peer->in_addr ); + atom->piece_data_time = time( NULL ); + break; + } + case TR_PEERMSG_CLIENT_HAVE: broadcastClientHave( t, e->pieceIndex ); tr_torrentRecheckCompleteness( t->tor ); @@ -1766,7 +1773,6 @@ getPeerCandidates( Torrent * t, int * setmeSize ) ret = tr_new( struct peer_atom*, atomCount ); for( i=retCount=0; inumFails > 10 ) continue; - /* if we used this peer recently, give someone else a turn */ - minWait = 60; - maxWait = (60 * 20); /* twenty minutes */ - wait = atom->numFails * 30; /* add 30 secs to the wait interval for each consecutive failure*/ - if( wait < minWait ) wait = minWait; - if( wait > maxWait ) wait = maxWait; - if( ( now - atom->time ) < wait ) { - tordbg( t, "RECONNECT peer %d (%s) is in its grace period of %d seconds..", - i, tr_peerIoAddrStr(&atom->addr,atom->port), wait ); - continue; + /* If we were connected to this peer recently and transferring + * piece data, try to reconnect -- network troubles may have + * disconnected us. but if we weren't sharing piece data, + * hold off on this peer to give another one a try instead */ + if( ( now - atom->piece_data_time ) > 15 ) + { + int minWait = 60; + int maxWait = (60 * 20); /* twenty minutes */ + int wait = atom->numFails * 30; /* add 30 secs to the wait interval for each consecutive failure*/ + if( wait < minWait ) wait = minWait; + if( wait > maxWait ) wait = maxWait; + if( ( now - atom->time ) < wait ) { + tordbg( t, "RECONNECT peer %d (%s) is in its grace period of %d seconds..", + i, tr_peerIoAddrStr(&atom->addr,atom->port), wait ); + continue; + } } ret[retCount++] = atom; diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index b3ed30127..44778e5d8 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -331,6 +331,14 @@ fireGotBlock( tr_peermsgs * msgs, const struct peer_request * req ) publish( msgs, &e ); } +static void +firePieceData( tr_peermsgs * msgs ) +{ + tr_peermsgs_event e = blankEvent; + e.eventType = TR_PEERMSG_PIECE_DATA; + publish( msgs, &e ); +} + static void fireCancelledReq( tr_peermsgs * msgs, const struct peer_request * req ) { @@ -1079,6 +1087,7 @@ clientGotBytes( tr_peermsgs * msgs, uint32_t byteCount ) tr_rcTransferred( tor->download, byteCount ); tr_rcTransferred( tor->handle->download, byteCount ); tr_statsAddDownloaded( msgs->handle, byteCount ); + firePieceData( msgs ); } static int @@ -1304,6 +1313,7 @@ peerGotBytes( tr_peermsgs * msgs, uint32_t byteCount ) tr_rcTransferred( tor->upload, byteCount ); tr_rcTransferred( tor->handle->upload, byteCount ); tr_statsAddUploaded( msgs->handle, byteCount ); + firePieceData( msgs ); } static size_t diff --git a/libtransmission/peer-msgs.h b/libtransmission/peer-msgs.h index 495e9844f..941189c9a 100644 --- a/libtransmission/peer-msgs.h +++ b/libtransmission/peer-msgs.h @@ -63,6 +63,7 @@ typedef enum { TR_PEERMSG_CLIENT_HAVE, TR_PEERMSG_CLIENT_BLOCK, + TR_PEERMSG_PIECE_DATA, TR_PEERMSG_PEER_PROGRESS, TR_PEERMSG_GOT_ERROR, TR_PEERMSG_GOT_ASSERT_ERROR,