Changeset 6700


Ignore:
Timestamp:
Sep 5, 2008, 5:14:49 AM (13 years ago)
Author:
charles
Message:

(libT) possible solution to the peer hammering problem reported by Switeck

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r6652 r6700  
    7474
    7575    /* unreachable for now... but not banned.  if they try to connect to us it's okay */
    76     MYFLAG_UNREACHABLE = 2
     76    MYFLAG_UNREACHABLE = 2,
     77
     78    /* the absolute minimum we'll wait before attempting to reconnect to a peer */
     79    MINIMUM_RECONNECT_INTERVAL_SECS = 5
    7780};
    7881
     
    9497    uint16_t numFails;
    9598    struct in_addr addr;
    96     time_t time;
     99    time_t time; /* the last time the peer's connection status changed */
    97100    time_t piece_data_time;
    98101};
     
    921924
    922925static int
    923 getMaxPeerCount( const tr_torrent * tor UNUSED )
     926getMaxPeerCount( const tr_torrent * tor )
    924927{
    925928    return tor->maxConnectedPeers;
     929}
     930
     931static int
     932getPeerCount( const Torrent * t )
     933{
     934    return tr_ptrArraySize( t->peers ) + tr_ptrArraySize( t->outgoingHandshakes );
    926935}
    927936
     
    980989        ensureAtomExists( t, addr, port, 0, TR_PEER_FROM_INCOMING );
    981990        atom = getExistingAtom( t, addr );
     991        atom->time = time( NULL );
    982992
    983993        if( atom->myflags & MYFLAG_BANNED )
     
    986996            tr_peerIoFree( io );
    987997        }
    988         else if( tr_ptrArraySize( t->peers ) >= getMaxPeerCount( t->tor ) )
     998        else if( tr_peerIoIsIncoming( io )
     999                 && ( getPeerCount( t ) >= getMaxPeerCount( t->tor ) ) )
     1000
    9891001        {
    9901002            tr_peerIoFree( io );
     
    10131025                peer->io = io;
    10141026                peer->msgs = tr_peerMsgsNew( t->tor, peer, peerCallbackFunc, t, &peer->msgsTag );
    1015                 atom->time = time( NULL );
    10161027            }
    10171028        }
     
    17781789{
    17791790    int sec;
    1780 
    1781     switch( atom->numFails )
    1782     {
     1791    const time_t now = time( NULL );
     1792
     1793    /* if we were recently connected to this peer and transferring piece
     1794     * data, try to reconnect to them sooner rather that later -- we don't
     1795     * want network troubles to get in the way of a good peer. */
     1796    if( ( now - atom->piece_data_time ) <= ( MINIMUM_RECONNECT_INTERVAL_SECS * 2 ) )
     1797        sec = MINIMUM_RECONNECT_INTERVAL_SECS;
     1798
     1799    /* don't allow reconnects more often than our minimum */
     1800    else if( ( now - atom->time ) < MINIMUM_RECONNECT_INTERVAL_SECS )
     1801        sec = MINIMUM_RECONNECT_INTERVAL_SECS;
     1802
     1803    /* otherwise, the interval depends on how many times we've tried
     1804     * and failed to connect to the peer */
     1805    else switch( atom->numFails ) {
    17831806        case 0: sec = 0; break;
    17841807        case 1: sec = 5; break;
     
    18081831    for( i=retCount=0; i<atomCount; ++i )
    18091832    {
     1833        int interval;
    18101834        struct peer_atom * atom = atoms[i];
    18111835
     
    18291853            continue;
    18301854
    1831         /* If we were connected to this peer recently and transferring
    1832          * piece data, try to reconnect -- network troubles may have
    1833          * disconnected us.  but if we weren't sharing piece data,
    1834          * hold off on this peer to give another one a try instead */
    1835         if( ( now - atom->piece_data_time ) > 10 )
    1836         {
    1837             const int wait = getReconnectIntervalSecs( atom );
    1838             if( ( now - atom->time ) < wait ) {
    1839                 tordbg( t, "RECONNECT peer %d (%s) is in its grace period of %d seconds..",
    1840                         i, tr_peerIoAddrStr(&atom->addr,atom->port), wait );
    1841                 continue;
    1842             }
     1855        /* don't reconnect too often */
     1856        interval = getReconnectIntervalSecs( atom );
     1857        if( ( now - atom->time ) < interval ) {
     1858            tordbg( t, "RECONNECT peer %d (%s) is in its grace period of %d seconds..",
     1859                    i, tr_peerIoAddrStr(&atom->addr,atom->port), interval );
     1860            continue;
    18431861        }
    18441862
     
    19051923
    19061924        /* add some new ones */
    1907         for( i=0;    i < nCandidates
    1908                   && i < MAX_RECONNECTIONS_PER_PULSE
    1909                   && newConnectionsThisSecond < MAX_CONNECTIONS_PER_SECOND; ++i )
     1925        for( i=0;    ( i < nCandidates )
     1926                  && ( i < MAX_RECONNECTIONS_PER_PULSE )
     1927                  && ( getPeerCount( t ) < getMaxPeerCount( t->tor ) )
     1928                  && ( newConnectionsThisSecond < MAX_CONNECTIONS_PER_SECOND ); ++i )
    19101929        {
    19111930            tr_peerMgr * mgr = t->manager;
Note: See TracChangeset for help on using the changeset viewer.