Ignore:
Timestamp:
Dec 22, 2008, 12:51:14 AM (12 years ago)
Author:
charles
Message:

(1.4x libT) backport handshake, peer, bandwidth, peer-io to 1.4x.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/1.4x/libtransmission/peer-mgr.c

    r7354 r7455  
    5858   
    5959    /* how frequently to reallocate bandwidth */
    60     BANDWIDTH_PERIOD_MSEC = 250,
     60    BANDWIDTH_PERIOD_MSEC = 500,
    6161
    6262    /* max # of peers to ask fer per torrent per reconnect pulse */
     
    9090**/
    9191
    92 /* We keep one of these for every peer we know about, whether
    93  * it's connected or not, so the struct must be small.
    94  * When our current connections underperform, we dip back
    95  * into this list for new ones. */
     92enum
     93{
     94    UPLOAD_ONLY_UKNOWN,
     95    UPLOAD_ONLY_YES,
     96    UPLOAD_ONLY_NO
     97};
     98
     99/**
     100 * Peer information that should be kept even before we've connected and
     101 * after we've disconnected.  These are kept in a pool of peer_atoms to decide
     102 * which ones would make good candidates for connecting to, and to watch out
     103 * for banned peers.
     104 *
     105 * @see tr_peer
     106 * @see tr_peermsgs
     107 */
    96108struct peer_atom
    97109{
    98     uint8_t           from;
    99     uint8_t           flags; /* these match the added_f flags */
    100     uint8_t           myflags; /* flags that aren't defined in added_f */
    101     uint16_t          port;
    102     uint16_t          numFails;
    103     struct in_addr    addr;
    104     time_t            time; /* when the peer's connection status last changed */
    105     time_t            piece_data_time;
     110    uint8_t     from;
     111    uint8_t     flags;       /* these match the added_f flags */
     112    uint8_t     myflags;     /* flags that aren't defined in added_f */
     113    uint8_t     uploadOnly;  /* UPLOAD_ONLY_ */
     114    tr_port     port;
     115    uint16_t    numFails;
     116    tr_address  addr;
     117    time_t      time;        /* when the peer's connection status last changed */
     118    time_t      piece_data_time;
    106119};
    107120
     
    131144    tr_ptrArray     * torrents; /* Torrent */
    132145    tr_ptrArray     * incomingHandshakes; /* tr_handshake */
     146    tr_ptrArray     * finishedHandshakes; /* tr_handshake */
    133147    tr_timer        * bandwidthTimer;
    134148};
     
    185199
    186200static int
    187 compareAddresses( const struct in_addr * a,
    188                   const struct in_addr * b )
    189 {
    190     if( a->s_addr != b->s_addr )
    191         return a->s_addr < b->s_addr ? -1 : 1;
    192 
    193     return 0;
    194 }
    195 
    196 static int
    197 handshakeCompareToAddr( const void * va,
    198                         const void * vb )
     201handshakeCompareToAddr( const void * va, const void * vb )
    199202{
    200203    const tr_handshake * a = va;
    201204
    202     return compareAddresses( tr_handshakeGetAddr( a, NULL ), vb );
    203 }
    204 
    205 static int
    206 handshakeCompare( const void * a,
    207                   const void * b )
     205    return tr_compareAddresses( tr_handshakeGetAddr( a, NULL ), vb );
     206}
     207
     208static int
     209handshakeCompare( const void * a, const void * b )
    208210{
    209211    return handshakeCompareToAddr( a, tr_handshakeGetAddr( b, NULL ) );
     
    211213
    212214static tr_handshake*
    213 getExistingHandshake( tr_ptrArray *          handshakes,
    214                       const struct in_addr * in_addr )
    215 {
    216     return tr_ptrArrayFindSorted( handshakes,
    217                                   in_addr,
    218                                   handshakeCompareToAddr );
    219 }
    220 
    221 static int
    222 comparePeerAtomToAddress( const void * va,
    223                           const void * vb )
     215getExistingHandshake( tr_ptrArray      * handshakes,
     216                      const tr_address * addr )
     217{
     218    return tr_ptrArrayFindSorted( handshakes, addr, handshakeCompareToAddr );
     219}
     220
     221static int
     222comparePeerAtomToAddress( const void * va, const void * vb )
    224223{
    225224    const struct peer_atom * a = va;
    226225
    227     return compareAddresses( &a->addr, vb );
    228 }
    229 
    230 static int
    231 comparePeerAtoms( const void * va,
    232                   const void * vb )
     226    return tr_compareAddresses( &a->addr, vb );
     227}
     228
     229static int
     230comparePeerAtoms( const void * va, const void * vb )
    233231{
    234232    const struct peer_atom * b = vb;
     
    271269
    272270static int
    273 peerCompare( const void * va,
    274              const void * vb )
     271peerCompare( const void * va, const void * vb )
    275272{
    276273    const tr_peer * a = va;
    277274    const tr_peer * b = vb;
    278275
    279     return compareAddresses( &a->in_addr, &b->in_addr );
    280 }
    281 
    282 static int
    283 peerCompareToAddr( const void * va,
    284                    const void * vb )
     276    return tr_compareAddresses( &a->addr, &b->addr );
     277}
     278
     279static int
     280peerCompareToAddr( const void * va, const void * vb )
    285281{
    286282    const tr_peer * a = va;
    287283
    288     return compareAddresses( &a->in_addr, vb );
     284    return tr_compareAddresses( &a->addr, vb );
    289285}
    290286
    291287static tr_peer*
    292 getExistingPeer( Torrent *              torrent,
    293                  const struct in_addr * in_addr )
     288getExistingPeer( Torrent          * torrent,
     289                 const tr_address * addr )
    294290{
    295291    assert( torrentIsLocked( torrent ) );
    296     assert( in_addr );
    297 
    298     return tr_ptrArrayFindSorted( torrent->peers,
    299                                   in_addr,
    300                                   peerCompareToAddr );
     292    assert( addr );
     293
     294    return tr_ptrArrayFindSorted( torrent->peers, addr, peerCompareToAddr );
    301295}
    302296
    303297static struct peer_atom*
    304 getExistingAtom( const                  Torrent * t,
    305                  const struct in_addr * addr )
     298getExistingAtom( const Torrent    * t,
     299                 const tr_address * addr )
    306300{
    307301    assert( torrentIsLocked( t ) );
     
    309303}
    310304
    311 static int
    312 peerIsInUse( const Torrent *        ct,
    313              const struct in_addr * addr )
     305static tr_bool
     306peerIsInUse( const Torrent    * ct,
     307             const tr_address * addr )
    314308{
    315309    Torrent * t = (Torrent*) ct;
     
    318312
    319313    return getExistingPeer( t, addr )
    320            || getExistingHandshake( t->outgoingHandshakes, addr )
    321            || getExistingHandshake( t->manager->incomingHandshakes, addr );
     314        || getExistingHandshake( t->outgoingHandshakes, addr )
     315        || getExistingHandshake( t->manager->incomingHandshakes, addr );
    322316}
    323317
    324318static tr_peer*
    325 peerConstructor( tr_torrent * tor, const struct in_addr * in_addr )
     319peerConstructor( tr_torrent * tor, const tr_address * addr )
    326320{
    327321    tr_peer * p;
    328 
    329322    p = tr_new0( tr_peer, 1 );
    330     memcpy( &p->in_addr, in_addr, sizeof( struct in_addr ) );
     323    p->addr = *addr;
    331324    p->bandwidth = tr_bandwidthNew( tor->session, tor->bandwidth );
    332325    return p;
     
    334327
    335328static tr_peer*
    336 getPeer( Torrent *              torrent,
    337          const struct in_addr * in_addr )
     329getPeer( Torrent          * torrent,
     330         const tr_address * addr )
    338331{
    339332    tr_peer * peer;
     
    341334    assert( torrentIsLocked( torrent ) );
    342335
    343     peer = getExistingPeer( torrent, in_addr );
     336    peer = getExistingPeer( torrent, addr );
    344337
    345338    if( peer == NULL )
    346339    {
    347         peer = peerConstructor( torrent->tor, in_addr );
     340        peer = peerConstructor( torrent->tor, addr );
    348341        tr_ptrArrayInsertSorted( torrent->peers, peer, peerCompare );
    349342    }
     
    356349{
    357350    assert( peer );
    358     assert( peer->msgs );
    359 
    360     tr_peerMsgsUnsubscribe( peer->msgs, peer->msgsTag );
    361     tr_peerMsgsFree( peer->msgs );
     351
     352    if( peer->msgs != NULL )
     353    {
     354        tr_peerMsgsUnsubscribe( peer->msgs, peer->msgsTag );
     355        tr_peerMsgsFree( peer->msgs );
     356    }
    362357
    363358    tr_peerIoFree( peer->io );
     
    381376    assert( torrentIsLocked( t ) );
    382377
    383     atom = getExistingAtom( t, &peer->in_addr );
     378    atom = getExistingAtom( t, &peer->addr );
    384379    assert( atom );
    385380    atom->time = time( NULL );
     
    456451}
    457452
    458 /**
    459  * For explanation, see http://www.bittorrent.org/fast_extensions.html
    460  * Also see the "test-allowed-set" unit test
    461  *
    462  * @param k number of pieces in set
    463  * @param sz number of pieces in the torrent
    464  * @param infohash torrent's SHA1 hash
    465  * @param ip peer's address
    466  */
    467 struct tr_bitfield *
    468 tr_peerMgrGenerateAllowedSet(
    469     const uint32_t         k,
    470     const uint32_t         sz,
    471     const                  uint8_t        *
    472                            infohash,
    473     const struct in_addr * ip )
    474 {
    475     uint8_t       w[SHA_DIGEST_LENGTH + 4];
    476     uint8_t       x[SHA_DIGEST_LENGTH];
    477     tr_bitfield * a;
    478     uint32_t      a_size;
    479 
    480     *(uint32_t*)w = ntohl( htonl( ip->s_addr ) & 0xffffff00 );   /* (1) */
    481     memcpy( w + 4, infohash, SHA_DIGEST_LENGTH );              /* (2) */
    482     tr_sha1( x, w, sizeof( w ), NULL );                        /* (3) */
    483 
    484     a = tr_bitfieldNew( sz );
    485     a_size = 0;
    486 
    487     while( a_size < k )
    488     {
    489         int i;
    490         for( i = 0; i < 5 && a_size < k; ++i )                      /* (4) */
    491         {
    492             uint32_t j = i * 4;                                /* (5) */
    493             uint32_t y = ntohl( *( uint32_t* )( x + j ) );             /* (6) */
    494             uint32_t index = y % sz;                           /* (7) */
    495             if( !tr_bitfieldHas( a, index ) )                  /* (8) */
    496             {
    497                 tr_bitfieldAdd( a, index );                    /* (9) */
    498                 ++a_size;
    499             }
    500         }
    501         tr_sha1( x, x, sizeof( x ), NULL );                    /* (3) */
    502     }
    503 
    504     return a;
    505 }
    506453
    507454static int bandwidthPulse( void * vmgr );
     
    516463    m->torrents = tr_ptrArrayNew( );
    517464    m->incomingHandshakes = tr_ptrArrayNew( );
     465    m->finishedHandshakes = tr_ptrArrayNew( );
    518466    m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
    519467    return m;
     
    523471tr_peerMgrFree( tr_peerMgr * manager )
    524472{
     473    tr_handshake * handshake;
     474
    525475    managerLock( manager );
    526476
     
    534484    tr_ptrArrayFree( manager->incomingHandshakes, NULL );
    535485
     486    while(( handshake = tr_ptrArrayPop( manager->finishedHandshakes )))
     487        tr_handshakeFree( handshake );
     488
     489    tr_ptrArrayFree( manager->finishedHandshakes, NULL );
     490
    536491    /* free the torrents. */
    537492    tr_ptrArrayFree( manager->torrents, torrentDestructor );
     
    542497
    543498static tr_peer**
    544 getConnectedPeers( Torrent * t,
    545                    int *     setmeCount )
    546 {
    547     int       i, peerCount, connectionCount;
     499getConnectedPeers( Torrent * t, int * setmeCount )
     500{
     501    int i, peerCount, connectionCount;
    548502    tr_peer **peers;
    549503    tr_peer **ret;
     
    578532***/
    579533
    580 int
    581 tr_peerMgrPeerIsSeed( const tr_peerMgr *    mgr,
    582                       const uint8_t *        torrentHash,
    583                       const struct in_addr * addr )
    584 {
    585     int                      isSeed = FALSE;
    586     const Torrent *          t = NULL;
     534tr_bool
     535tr_peerMgrPeerIsSeed( const tr_peerMgr  * mgr,
     536                      const uint8_t     * torrentHash,
     537                      const tr_address * addr )
     538{
     539    tr_bool isSeed = FALSE;
     540    const Torrent * t = NULL;
    587541    const struct peer_atom * atom = NULL;
    588542
     
    648602
    649603static int
    650 compareRefillPiece( const void * aIn,
    651                     const void * bIn )
     604compareRefillPiece( const void * aIn, const void * bIn )
    652605{
    653606    const struct tr_refill_piece * a = aIn;
     
    678631
    679632static tr_piece_index_t *
    680 getPreferredPieces( Torrent           * t,
    681                     tr_piece_index_t  * pieceCount )
     633getPreferredPieces( Torrent * t, tr_piece_index_t * pieceCount )
    682634{
    683635    const tr_torrent  * tor = t->tor;
     
    877829        for( j=0; !handled && j<peerCount; )
    878830        {
    879             const int val = tr_peerMsgsAddRequest( peers[j]->msgs,
    880                                                    index, offset, length );
     831            const tr_addreq_t val = tr_peerMsgsAddRequest( peers[j]->msgs, index, offset, length );
    881832            switch( val )
    882833            {
     
    905856        for( j=0; !handled && j<webseedCount; )
    906857        {
    907             const tr_addreq_t val = tr_webseedAddRequest( webseeds[j],
    908                                                           index, offset, length );
     858            const tr_addreq_t val = tr_webseedAddRequest( webseeds[j], index, offset, length );
    909859            switch( val )
    910860            {
     
    943893    assert( torrentIsLocked( t ) );
    944894
     895    tordbg( t, "got a block; cancelling any duplicate requests from peers %"PRIu32":%"PRIu32"->%"PRIu32, index, offset, length );
    945896    peers = getConnectedPeers( t, &size );
    946897    for( i=0; i<size; ++i )
     
    954905{
    955906    tordbg( t, "increasing peer %s strike count to %d",
    956             tr_peerIoAddrStr( &peer->in_addr,
     907            tr_peerIoAddrStr( &peer->addr,
    957908                              peer->port ), peer->strikes + 1 );
    958909
    959910    if( ++peer->strikes >= MAX_BAD_PIECES_PER_PEER )
    960911    {
    961         struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     912        struct peer_atom * atom = getExistingAtom( t, &peer->addr );
    962913        atom->myflags |= MYFLAG_BANNED;
    963914        peer->doPurge = 1;
     
    988939
    989940static void
    990 peerCallbackFunc( void * vpeer,
    991                   void * vevent,
    992                   void * vt )
    993 {
    994     tr_peer *             peer = vpeer; /* may be NULL if peer is a webseed */
    995     Torrent *             t = (Torrent *) vt;
     941peerSuggestedPiece( Torrent            * t UNUSED,
     942                    tr_peer            * peer UNUSED,
     943                    tr_piece_index_t     pieceIndex UNUSED,
     944                    int                  isFastAllowed UNUSED )
     945{
     946#if 0
     947    assert( t );
     948    assert( peer );
     949    assert( peer->msgs );
     950
     951    /* is this a valid piece? */
     952    if(  pieceIndex >= t->tor->info.pieceCount )
     953        return;
     954
     955    /* don't ask for it if we've already got it */
     956    if( tr_cpPieceIsComplete( t->tor->completion, pieceIndex ) )
     957        return;
     958
     959    /* don't ask for it if they don't have it */
     960    if( !tr_bitfieldHas( peer->have, pieceIndex ) )
     961        return;
     962
     963    /* don't ask for it if we're choked and it's not fast */
     964    if( !isFastAllowed && peer->clientIsChoked )
     965        return;
     966
     967    /* request the blocks that we don't have in this piece */
     968    {
     969        tr_block_index_t block;
     970        const tr_torrent * tor = t->tor;
     971        const tr_block_index_t start = tr_torPieceFirstBlock( tor, pieceIndex );
     972        const tr_block_index_t end = start + tr_torPieceCountBlocks( tor, pieceIndex );
     973
     974        for( block=start; block<end; ++block )
     975        {
     976            if( !tr_cpBlockIsComplete( tor->completion, block ) )
     977            {
     978                const uint32_t offset = getBlockOffsetInPiece( tor, block );
     979                const uint32_t length = tr_torBlockCountBytes( tor, block );
     980                tr_peerMsgsAddRequest( peer->msgs, pieceIndex, offset, length );
     981                incrementPieceRequests( t, pieceIndex );
     982            }
     983        }
     984    }
     985#endif
     986}
     987
     988static void
     989peerCallbackFunc( void * vpeer, void * vevent, void * vt )
     990{
     991    tr_peer * peer = vpeer; /* may be NULL if peer is a webseed */
     992    Torrent * t = vt;
    996993    const tr_peer_event * e = vevent;
    997994
     
    1000997    switch( e->eventType )
    1001998    {
     999        case TR_PEER_UPLOAD_ONLY:
     1000            /* update our atom */
     1001            if( peer ) {
     1002                struct peer_atom * a = getExistingAtom( t, &peer->addr );
     1003                a->uploadOnly = e->uploadOnly ? UPLOAD_ONLY_YES : UPLOAD_ONLY_NO;
     1004            }
     1005            break;
     1006
    10021007        case TR_PEER_NEED_REQ:
    10031008            refillSoon( t );
     
    10241029            /* update our atom */
    10251030            if( peer ) {
    1026                 struct peer_atom * a = getExistingAtom( t, &peer->in_addr );
     1031                struct peer_atom * a = getExistingAtom( t, &peer->addr );
    10271032                if( e->wasPieceData )
    10281033                    a->piece_data_time = now;
     
    10311036            break;
    10321037        }
     1038
     1039        case TR_PEER_CLIENT_GOT_SUGGEST:
     1040            if( peer )
     1041                peerSuggestedPiece( t, peer, e->pieceIndex, FALSE );
     1042            break;
     1043
     1044        case TR_PEER_CLIENT_GOT_ALLOWED_FAST:
     1045            if( peer )
     1046                peerSuggestedPiece( t, peer, e->pieceIndex, TRUE );
     1047            break;
    10331048
    10341049        case TR_PEER_CLIENT_GOT_DATA:
     
    10361051            const time_t now = time( NULL );
    10371052            tr_torrent * tor = t->tor;
    1038 
    10391053            tor->activityDate = now;
    10401054
     
    10541068            /* update our atom */
    10551069            if( peer ) {
    1056                 struct peer_atom * a = getExistingAtom( t, &peer->in_addr );
     1070                struct peer_atom * a = getExistingAtom( t, &peer->addr );
    10571071                if( e->wasPieceData )
    10581072                    a->piece_data_time = now;
     
    10661080            if( peer )
    10671081            {
    1068                 struct peer_atom * atom = getExistingAtom( t,
    1069                                                            &peer->in_addr );
    1070                 const int          peerIsSeed = e->progress >= 1.0;
    1071                 if( peerIsSeed )
    1072                 {
    1073                     tordbg( t, "marking peer %s as a seed",
    1074                            tr_peerIoAddrStr( &atom->addr,
    1075                                              atom->port ) );
     1082                struct peer_atom * atom = getExistingAtom( t, &peer->addr );
     1083                const int peerIsSeed = e->progress >= 1.0;
     1084                if( peerIsSeed ) {
     1085                    tordbg( t, "marking peer %s as a seed", tr_peerIoAddrStr( &atom->addr, atom->port ) );
    10761086                    atom->flags |= ADDED_F_SEED_FLAG;
    1077                 }
    1078                 else
    1079                 {
    1080                     tordbg( t, "marking peer %s as a non-seed",
    1081                            tr_peerIoAddrStr( &atom->addr,
    1082                                              atom->port ) );
     1087                } else {
     1088                    tordbg( t, "marking peer %s as a non-seed", tr_peerIoAddrStr( &atom->addr, atom->port ) );
    10831089                    atom->flags &= ~ADDED_F_SEED_FLAG;
    10841090                }
     
    10911097            tr_torrent *     tor = t->tor;
    10921098
    1093             tr_block_index_t block = _tr_block( tor, e->pieceIndex,
    1094                                                 e->offset );
     1099            tr_block_index_t block = _tr_block( tor, e->pieceIndex, e->offset );
    10951100
    10961101            tr_cpBlockAdd( tor->completion, block );
     
    11021107            {
    11031108                const tr_piece_index_t p = e->pieceIndex;
    1104                 const int              ok = tr_ioTestPiece( tor, p );
     1109                const tr_bool ok = tr_ioTestPiece( tor, p );
    11051110
    11061111                if( !ok )
    11071112                {
    1108                     tr_torerr( tor,
    1109                               _( "Piece %lu, which was just downloaded, failed its checksum test" ),
    1110                               (unsigned long)p );
     1113                    tr_torerr( tor, _( "Piece %lu, which was just downloaded, failed its checksum test" ),
     1114                               (unsigned long)p );
    11111115                }
    11121116
     
    11191123                else
    11201124                {
    1121                     int        i, peerCount;
     1125                    int i, peerCount;
    11221126                    tr_peer ** peers = getConnectedPeers( t, &peerCount );
    11231127                    for( i = 0; i < peerCount; ++i )
     
    11361140                addStrike( t, peer );
    11371141                peer->doPurge = 1;
     1142                tordbg( t, "setting doPurge because we got an EINVAL error" );
    11381143            }
    11391144            else if( ( e->err == ERANGE )
     
    11431148                /* some protocol error from the peer */
    11441149                peer->doPurge = 1;
     1150                tordbg( t, "setting doPurge because we got an ERANGE, EMSGSIZE, or ENOTCONN error" );
    11451151            }
    11461152            else /* a local error, such as an IO error */
     
    11621168
    11631169static void
    1164 ensureAtomExists( Torrent *              t,
    1165                   const struct in_addr * addr,
    1166                   uint16_t               port,
    1167                   uint8_t                flags,
    1168                   uint8_t                from )
     1170ensureAtomExists( Torrent          * t,
     1171                  const tr_address * addr,
     1172                  tr_port            port,
     1173                  uint8_t            flags,
     1174                  uint8_t            from )
    11691175{
    11701176    if( getExistingAtom( t, addr ) == NULL )
     
    11761182        a->flags = flags;
    11771183        a->from = from;
    1178         tordbg( t, "got a new atom: %s",
    1179                tr_peerIoAddrStr( &a->addr, a->port ) );
     1184        tordbg( t, "got a new atom: %s", tr_peerIoAddrStr( &a->addr, a->port ) );
    11801185        tr_ptrArrayInsertSorted( t->pool, a, comparePeerAtoms );
    11811186    }
     
    11911196getPeerCount( const Torrent * t )
    11921197{
    1193     return tr_ptrArraySize( t->peers ) + tr_ptrArraySize(
    1194                t->outgoingHandshakes );
     1198    return tr_ptrArraySize( t->peers ) + tr_ptrArraySize( t->outgoingHandshakes );
    11951199}
    11961200
    11971201/* FIXME: this is kind of a mess. */
    1198 static int
    1199 myHandshakeDoneCB( tr_handshake * handshake,
    1200                    tr_peerIo *    io,
     1202static tr_bool
     1203myHandshakeDoneCB( tr_handshake  * handshake,
     1204                   tr_peerIo     * io,
    12011205                   int             isConnected,
    12021206                   const uint8_t * peer_id,
    1203                    void *          vmanager )
    1204 {
    1205     int                    ok = isConnected;
    1206     int                    success = FALSE;
    1207     uint16_t               port;
    1208     const struct in_addr * addr;
    1209     tr_peerMgr *           manager = (tr_peerMgr*) vmanager;
    1210     Torrent *              t;
    1211     tr_handshake *        ours;
     1207                   void          * vmanager )
     1208{
     1209    tr_bool            ok = isConnected;
     1210    tr_bool            success = FALSE;
     1211    tr_port            port;
     1212    const tr_address * addr;
     1213    tr_peerMgr       * manager = vmanager;
     1214    Torrent          * t;
     1215    tr_handshake     * ours;
    12121216
    12131217    assert( io );
     
    12431247                ++atom->numFails;
    12441248        }
    1245 
    1246         tr_peerIoFree( io );
    12471249    }
    12481250    else /* looking good */
     
    12571259        {
    12581260            tordbg( t, "banned peer %s tried to reconnect",
    1259                    tr_peerIoAddrStr( &atom->addr,
    1260                                      atom->port ) );
    1261             tr_peerIoFree( io );
     1261                    tr_peerIoAddrStr( &atom->addr, atom->port ) );
    12621262        }
    12631263        else if( tr_peerIoIsIncoming( io )
     
    12651265
    12661266        {
    1267             tr_peerIoFree( io );
    12681267        }
    12691268        else
     
    12731272            if( peer ) /* we already have this peer */
    12741273            {
    1275                 tr_peerIoFree( io );
    12761274            }
    12771275            else
     
    12891287
    12901288                peer->port = port;
    1291                 peer->io = io;
    1292                 peer->msgs = tr_peerMsgsNew( t->tor, peer, peerCallbackFunc, t, &peer->msgsTag );
     1289                peer->io = tr_handshakeStealIO( handshake );
     1290                tr_peerMsgsNew( t->tor, peer, peerCallbackFunc, t, &peer->msgsTag );
    12931291                tr_peerIoSetBandwidth( io, peer->bandwidth );
    12941292
     
    12981296    }
    12991297
     1298    if( !success )
     1299        tr_ptrArrayAppend( manager->finishedHandshakes, handshake );
     1300
    13001301    if( t )
    13011302        torrentUnlock( t );
     
    13051306
    13061307void
    1307 tr_peerMgrAddIncoming( tr_peerMgr *     manager,
    1308                        struct in_addr * addr,
    1309                        uint16_t         port,
    1310                        int              socket )
     1308tr_peerMgrAddIncoming( tr_peerMgr * manager,
     1309                       tr_address * addr,
     1310                       tr_port      port,
     1311                       int          socket )
    13111312{
    13121313    managerLock( manager );
     
    13141315    if( tr_sessionIsAddressBlocked( manager->session, addr ) )
    13151316    {
    1316         tr_dbg( "Banned IP address \"%s\" tried to connect to us",
    1317                inet_ntoa( *addr ) );
     1317        tr_dbg( "Banned IP address \"%s\" tried to connect to us", inet_ntoa( *addr ) );
    13181318        tr_netClose( socket );
    13191319    }
     
    13391339
    13401340    managerUnlock( manager );
     1341}
     1342
     1343static tr_bool
     1344tr_isPex( const tr_pex * pex )
     1345{
     1346    return pex && tr_isAddress( &pex->addr );
    13411347}
    13421348
     
    13471353                  const tr_pex *  pex )
    13481354{
    1349     Torrent * t;
    1350 
    1351     managerLock( manager );
    1352 
    1353     t = getExistingTorrent( manager, torrentHash );
    1354     if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->in_addr ) )
    1355         ensureAtomExists( t, &pex->in_addr, pex->port, pex->flags, from );
    1356 
    1357     managerUnlock( manager );
     1355    if( tr_isPex( pex ) ) /* safeguard against corrupt data */
     1356    {
     1357        Torrent * t;
     1358        managerLock( manager );
     1359
     1360        t = getExistingTorrent( manager, torrentHash );
     1361        if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->addr ) )
     1362            ensureAtomExists( t, &pex->addr, pex->port, pex->flags, from );
     1363
     1364        managerUnlock( manager );
     1365    }
    13581366}
    13591367
     
    13721380    for( i = 0; i < n; ++i )
    13731381    {
    1374         memcpy( &pex[i].in_addr, walk, 4 ); walk += 4;
     1382        memcpy( &pex[i].addr, walk, 4 ); walk += 4;
    13751383        memcpy( &pex[i].port, walk, 2 ); walk += 2;
    13761384        if( added_f && ( n == added_f_len ) )
     
    14061414            if( tr_bitfieldHas( peer->blame, pieceIndex ) )
    14071415            {
    1408                 tordbg(
    1409                     t,
    1410                     "peer %s contributed to corrupt piece (%d); now has %d strikes",
    1411                     tr_peerIoAddrStr( &peer->in_addr, peer->port ),
    1412                     pieceIndex, (int)peer->strikes + 1 );
     1416                tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
     1417                        tr_peerIoAddrStr( &peer->addr, peer->port ),
     1418                        pieceIndex, (int)peer->strikes + 1 );
    14131419                addStrike( t, peer );
    14141420            }
     
    14181424
    14191425int
    1420 tr_pexCompare( const void * va,
    1421                const void * vb )
     1426tr_pexCompare( const void * va, const void * vb )
    14221427{
    14231428    const tr_pex * a = va;
    14241429    const tr_pex * b = vb;
    1425     int            i =
    1426         memcmp( &a->in_addr, &b->in_addr, sizeof( struct in_addr ) );
    1427 
    1428     if( i ) return i;
    1429     if( a->port < b->port ) return -1;
    1430     if( a->port > b->port ) return 1;
     1430    int i;
     1431
     1432    assert( tr_isPex( a ) );
     1433    assert( tr_isPex( b ) );
     1434
     1435    if(( i = tr_compareAddresses( &a->addr, &b->addr )))
     1436        return i;
     1437
     1438    if( a->port != b->port )
     1439        return a->port < b->port ? -1 : 1;
     1440
    14311441    return 0;
    14321442}
    1433 
    1434 int tr_pexCompare( const void * a,
    1435                    const void * b );
    14361443
    14371444static int
     
    14481455
    14491456int
    1450 tr_peerMgrGetPeers( tr_peerMgr *    manager,
    1451                     const uint8_t * torrentHash,
    1452                     tr_pex **      setme_pex )
     1457tr_peerMgrGetPeers( tr_peerMgr      * manager,
     1458                    const uint8_t   * torrentHash,
     1459                    tr_pex         ** setme_pex )
    14531460{
    14541461    int peerCount = 0;
     
    14581465
    14591466    t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    1460     if( !t )
     1467    if( t == NULL )
    14611468    {
    14621469        *setme_pex = NULL;
     
    14691476        tr_pex * walk = pex;
    14701477
    1471         for( i = 0; i < peerCount; ++i, ++walk )
     1478        for( i=0; i<peerCount; ++i, ++walk )
    14721479        {
    14731480            const tr_peer * peer = peers[i];
    1474             walk->in_addr = peer->in_addr;
     1481            const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
     1482
     1483            assert( tr_isAddress( &peer->addr ) );
     1484            walk->addr = peer->addr;
    14751485            walk->port = peer->port;
    14761486            walk->flags = 0;
    1477             if( peerPrefersCrypto( peer ) ) walk->flags |= ADDED_F_ENCRYPTION_FLAG;
    1478             if( peer->progress >= 1.0 ) walk->flags |= ADDED_F_SEED_FLAG;
     1487            if( peerPrefersCrypto( peer ) )
     1488                walk->flags |= ADDED_F_ENCRYPTION_FLAG;
     1489            if( ( atom->uploadOnly == UPLOAD_ONLY_YES ) || ( peer->progress >= 1.0 ) )
     1490                walk->flags |= ADDED_F_SEED_FLAG;
    14791491        }
    14801492
     
    16031615    const tr_torrent * tor;
    16041616    float              interval;
    1605     int                isComplete;
     1617    tr_bool            isSeed;
    16061618    int                peerCount;
    16071619    const tr_peer **   peers;
     
    16121624    tor = t->tor;
    16131625    interval = tor->info.pieceCount / (float)tabCount;
    1614     isComplete = tor
    1615                  && ( tr_cpGetStatus ( tor->completion ) == TR_CP_COMPLETE );
     1626    isSeed = tor && ( tr_cpGetStatus ( tor->completion ) == TR_CP_COMPLETE );
    16161627    peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
    16171628
     
    16221633        const int piece = i * interval;
    16231634
    1624         if( isComplete || tr_cpPieceIsComplete( tor->completion, piece ) )
     1635        if( isSeed || tr_cpPieceIsComplete( tor->completion, piece ) )
    16251636            tab[i] = -1;
    1626         else if( peerCount )
    1627         {
     1637        else if( peerCount ) {
    16281638            int j;
    16291639            for( j = 0; j < peerCount; ++j )
     
    16451655    tr_peer **    peers;
    16461656    tr_bitfield * pieces;
    1647 
    16481657    managerLock( manager );
    16491658
     
    16631672                          const uint8_t *    torrentHash )
    16641673{
    1665     int             ret;
     1674    int ret;
    16661675    const Torrent * t;
    1667 
    16681676    managerLock( manager );
    16691677
    16701678    t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    1671     ret = t && ( !tr_ptrArrayEmpty( t->peers )
    1672                || !tr_ptrArrayEmpty( t->webseeds ) );
     1679    ret = t && ( !tr_ptrArrayEmpty( t->peers ) || !tr_ptrArrayEmpty( t->webseeds ) );
    16731680
    16741681    managerUnlock( manager );
     
    16781685void
    16791686tr_peerMgrTorrentStats( const tr_peerMgr * manager,
    1680                         const uint8_t *    torrentHash,
    1681                         int *              setmePeersKnown,
    1682                         int *              setmePeersConnected,
    1683                         int *              setmeSeedsConnected,
    1684                         int *              setmeWebseedsSendingToUs,
    1685                         int *              setmePeersSendingToUs,
    1686                         int *              setmePeersGettingFromUs,
    1687                         int *              setmePeersFrom )
    1688 {
    1689     int                 i, size;
    1690     const Torrent *     t;
    1691     const tr_peer **    peers;
     1687                        const uint8_t    * torrentHash,
     1688                        int              * setmePeersKnown,
     1689                        int              * setmePeersConnected,
     1690                        int              * setmeSeedsConnected,
     1691                        int              * setmeWebseedsSendingToUs,
     1692                        int              * setmePeersSendingToUs,
     1693                        int              * setmePeersGettingFromUs,
     1694                        int              * setmePeersFrom )
     1695{
     1696    int i, size;
     1697    const Torrent * t;
     1698    const tr_peer ** peers;
    16921699    const tr_webseed ** webseeds;
    16931700
     
    17041711    *setmeWebseedsSendingToUs  = 0;
    17051712
    1706     for( i = 0; i < TR_PEER_FROM__MAX; ++i )
     1713    for( i=0; i<TR_PEER_FROM__MAX; ++i )
    17071714        setmePeersFrom[i] = 0;
    17081715
    1709     for( i = 0; i < size; ++i )
    1710     {
    1711         const tr_peer *          peer = peers[i];
    1712         const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     1716    for( i=0; i<size; ++i )
     1717    {
     1718        const tr_peer * peer = peers[i];
     1719        const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
    17131720
    17141721        if( peer->io == NULL ) /* not connected */
    17151722            continue;
    17161723
    1717         ++ * setmePeersConnected;
     1724        ++*setmePeersConnected;
    17181725
    17191726        ++setmePeersFrom[atom->from];
    17201727
    17211728        if( clientIsDownloadingFrom( peer ) )
    1722             ++ * setmePeersSendingToUs;
     1729            ++*setmePeersSendingToUs;
    17231730
    17241731        if( clientIsUploadingTo( peer ) )
    1725             ++ * setmePeersGettingFromUs;
     1732            ++*setmePeersGettingFromUs;
    17261733
    17271734        if( atom->flags & ADDED_F_SEED_FLAG )
    1728             ++ * setmeSeedsConnected;
     1735            ++*setmeSeedsConnected;
    17291736    }
    17301737
    17311738    webseeds = (const tr_webseed **) tr_ptrArrayPeek( t->webseeds, &size );
    1732     for( i = 0; i < size; ++i )
    1733     {
     1739    for( i=0; i<size; ++i )
    17341740        if( tr_webseedIsActive( webseeds[i] ) )
    1735             ++ * setmeWebseedsSendingToUs;
    1736     }
     1741            ++*setmeWebseedsSendingToUs;
    17371742
    17381743    managerUnlock( manager );
     
    17431748                     const uint8_t *    torrentHash )
    17441749{
    1745     const Torrent *     t;
     1750    const Torrent * t;
    17461751    const tr_webseed ** webseeds;
    1747     int                 i;
    1748     int                 webseedCount;
    1749     float *             ret;
     1752    int i;
     1753    int webseedCount;
     1754    float * ret;
    17501755
    17511756    assert( manager );
     
    17581763    ret = tr_new0( float, webseedCount );
    17591764
    1760     for( i = 0; i < webseedCount; ++i )
     1765    for( i=0; i<webseedCount; ++i )
    17611766        if( !tr_webseedGetSpeed( webseeds[i], &ret[i] ) )
    17621767            ret[i] = -1.0;
     
    17671772
    17681773double
    1769 tr_peerGetPieceSpeed( const tr_peer    * peer,
    1770                       tr_direction       direction )
     1774tr_peerGetPieceSpeed( const tr_peer * peer, tr_direction direction )
    17711775{
    17721776    assert( peer );
     
    17981802        char *                   pch;
    17991803        const tr_peer *          peer = peers[i];
    1800         const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     1804        const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
    18011805        tr_peer_stat *           stat = ret + i;
    18021806
    1803         tr_netNtop( &peer->in_addr, stat->addr, sizeof( stat->addr ) );
     1807        tr_netNtop( &peer->addr, stat->addr, sizeof( stat->addr ) );
    18041808        tr_strlcpy( stat->client, ( peer->client ? peer->client : "" ),
    18051809                   sizeof( stat->client ) );
     
    18171821        stat->isDownloadingFrom  = clientIsDownloadingFrom( peer );
    18181822        stat->isUploadingTo      = clientIsUploadingTo( peer );
     1823        stat->isSeed             = ( atom->uploadOnly == UPLOAD_ONLY_YES ) || ( peer->progress >= 1.0 );
    18191824
    18201825        pch = stat->flagStr;
     
    18241829        if( stat->isUploadingTo ) *pch++ = 'U';
    18251830        else if( stat->peerIsInterested ) *pch++ = 'u';
    1826         if( !stat->clientIsChoked && !stat->clientIsInterested ) *pch++ =
    1827                 'K';
     1831        if( !stat->clientIsChoked && !stat->clientIsInterested ) *pch++ = 'K';
    18281832        if( !stat->peerIsChoked && !stat->peerIsInterested ) *pch++ = '?';
    18291833        if( stat->isEncrypted ) *pch++ = 'E';
     
    18991903    {
    19001904        tr_peer * peer = peers[i];
     1905        struct peer_atom * atom = getExistingAtom( t, &peer->addr );
     1906
    19011907        if( peer->progress >= 1.0 ) /* choke all seeds */
     1908        {
    19021909            tr_peerMsgsSetChoke( peer->msgs, TRUE );
    1903         else if( chokeAll )
     1910        }
     1911        else if( atom->uploadOnly == UPLOAD_ONLY_YES ) /* choke partial seeds */
     1912        {
    19041913            tr_peerMsgsSetChoke( peer->msgs, TRUE );
    1905         else {
     1914        }
     1915        else if( chokeAll ) /* choke everyone if we're not uploading */
     1916        {
     1917            tr_peerMsgsSetChoke( peer->msgs, TRUE );
     1918        }
     1919        else
     1920        {
    19061921            struct ChokeData * n = &choke[size++];
    19071922            n->peer         = peer;
     
    19281943     */
    19291944    unchokedInterested = 0;
    1930     for( i = 0; i < size && unchokedInterested < MAX_UNCHOKED_PEERS; ++i )
    1931     {
     1945    for( i=0; i<size && unchokedInterested<MAX_UNCHOKED_PEERS; ++i ) {
    19321946        choke[i].doUnchoke = 1;
    19331947        if( choke[i].isInterested )
     
    19381952    if( i < size )
    19391953    {
    1940         int                n;
     1954        int n;
    19411955        struct ChokeData * c;
    1942         tr_ptrArray *      randPool = tr_ptrArrayNew( );
    1943 
    1944         for( ; i < size; ++i )
     1956        tr_ptrArray * randPool = tr_ptrArrayNew( );
     1957
     1958        for( ; i<size; ++i )
    19451959        {
    19461960            if( choke[i].isInterested )
    19471961            {
    19481962                const tr_peer * peer = choke[i].peer;
    1949                 int             x = 1, y;
     1963                int x = 1, y;
    19501964                if( isNew( peer ) ) x *= 3;
    19511965                if( isSame( peer ) ) x *= 3;
    1952                 for( y = 0; y < x; ++y )
     1966                for( y=0; y<x; ++y )
    19531967                    tr_ptrArrayAppend( randPool, &choke[i] );
    19541968            }
    19551969        }
    19561970
    1957         if( ( n = tr_ptrArraySize( randPool ) ) )
     1971        if(( n = tr_ptrArraySize( randPool )))
    19581972        {
    1959             c = tr_ptrArrayNth( randPool, tr_cryptoWeakRandInt( n ) );
     1973            c = tr_ptrArrayNth( randPool, tr_cryptoWeakRandInt( n ));
    19601974            c->doUnchoke = 1;
    19611975            t->optimistic = c->peer;
     
    19651979    }
    19661980
    1967     for( i = 0; i < size; ++i )
     1981    for( i=0; i<size; ++i )
    19681982        tr_peerMsgsSetChoke( choke[i].peer->msgs, !choke[i].doUnchoke );
    19691983
     
    19972011    const tr_torrent *       tor = t->tor;
    19982012    const time_t             now = time( NULL );
    1999     const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     2013    const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
    20002014
    20012015    /* if it's marked for purging, close it */
     
    20032017    {
    20042018        tordbg( t, "purging peer %s because its doPurge flag is set",
    2005                tr_peerIoAddrStr( &atom->addr,
    2006                                  atom->port ) );
     2019                tr_peerIoAddrStr( &atom->addr, atom->port ) );
    20072020        return TRUE;
    20082021    }
     
    20172030        else if( peer->progress < tr_cpPercentDone( tor->completion ) )
    20182031            peerHasEverything = FALSE;
    2019         else
    2020         {
    2021             tr_bitfield * tmp =
    2022                 tr_bitfieldDup( tr_cpPieceBitfield( tor->completion ) );
     2032        else {
     2033            tr_bitfield * tmp = tr_bitfieldDup( tr_cpPieceBitfield( tor->completion ) );
    20232034            tr_bitfieldDifference( tmp, peer->have );
    20242035            peerHasEverything = tr_bitfieldCountTrueBits( tmp ) == 0;
    20252036            tr_bitfieldFree( tmp );
    20262037        }
    2027         if( peerHasEverything
    2028           && ( !tr_torrentAllowsPex( tor ) || ( now - atom->time >= 30 ) ) )
     2038
     2039        if( peerHasEverything && ( !tr_torrentAllowsPex(tor) || (now-atom->time>=30 )))
    20292040        {
    20302041            tordbg( t, "purging peer %s because we're both seeds",
    2031                    tr_peerIoAddrStr( &atom->addr,
    2032                                      atom->port ) );
     2042                    tr_peerIoAddrStr( &atom->addr, atom->port ) );
    20332043            return TRUE;
    20342044        }
     
    20602070
    20612071static tr_peer **
    2062 getPeersToClose( Torrent * t,
    2063                  int *     setmeSize )
    2064 {
    2065     int               i, peerCount, outsize;
    2066     tr_peer **        peers = (tr_peer**) tr_ptrArrayPeek( t->peers,
    2067                                                            &peerCount );
     2072getPeersToClose( Torrent * t, int * setmeSize )
     2073{
     2074    int i, peerCount, outsize;
     2075    tr_peer ** peers = (tr_peer**) tr_ptrArrayPeek( t->peers, &peerCount );
    20682076    struct tr_peer ** ret = tr_new( tr_peer *, peerCount );
    20692077
     
    21012109        return a->time < b->time ? -1 : 1;
    21022110
     2111    /* all other things being equal, prefer peers whose
     2112     * information comes from a more reliable source */
     2113    if( a->from != b->from )
     2114        return a->from < b->from ? -1 : 1;
     2115
    21032116    return 0;
    21042117}
     
    21132126     * data, try to reconnect to them sooner rather that later -- we don't
    21142127     * want network troubles to get in the way of a good peer. */
    2115     if( ( now - atom->piece_data_time ) <=
    2116        ( MINIMUM_RECONNECT_INTERVAL_SECS * 2 ) )
     2128    if( ( now - atom->piece_data_time ) <= ( MINIMUM_RECONNECT_INTERVAL_SECS * 2 ) )
    21172129        sec = MINIMUM_RECONNECT_INTERVAL_SECS;
    21182130
     
    21232135    /* otherwise, the interval depends on how many times we've tried
    21242136     * and failed to connect to the peer */
    2125     else switch( atom->numFails )
    2126         {
    2127             case 0:
    2128                 sec = 0; break;
    2129 
    2130             case 1:
    2131                 sec = 5; break;
    2132 
    2133             case 2:
    2134                 sec = 2 * 60; break;
    2135 
    2136             case 3:
    2137                 sec = 15 * 60; break;
    2138 
    2139             case 4:
    2140                 sec = 30 * 60; break;
    2141 
    2142             case 5:
    2143                 sec = 60 * 60; break;
    2144 
    2145             default:
    2146                 sec = 120 * 60; break;
    2147         }
     2137    else switch( atom->numFails ) {
     2138        case 0: sec = 0; break;
     2139        case 1: sec = 5; break;
     2140        case 2: sec = 2 * 60; break;
     2141        case 3: sec = 15 * 60; break;
     2142        case 4: sec = 30 * 60; break;
     2143        case 5: sec = 60 * 60; break;
     2144        default: sec = 120 * 60; break;
     2145    }
    21482146
    21492147    return sec;
     
    21512149
    21522150static struct peer_atom **
    2153 getPeerCandidates(                               Torrent * t,
    2154                                            int * setmeSize )
     2151getPeerCandidates( Torrent * t, int * setmeSize )
    21552152{
    21562153    int                 i, atomCount, retCount;
     
    21852182
    21862183        /* no need to connect if we're both seeds... */
    2187         if( seed && ( atom->flags & ADDED_F_SEED_FLAG ) )
     2184        if( seed && ( ( atom->flags & ADDED_F_SEED_FLAG ) ||
     2185                      ( atom->uploadOnly == UPLOAD_ONLY_YES ) ) )
    21882186            continue;
    21892187
     
    21922190        if( ( now - atom->time ) < interval )
    21932191        {
    2194             tordbg(
    2195                 t,
    2196                 "RECONNECT peer %d (%s) is in its grace period of %d seconds..",
    2197                 i, tr_peerIoAddrStr( &atom->addr,
    2198                                      atom->port ), interval );
     2192            tordbg( t, "RECONNECT peer %d (%s) is in its grace period of %d seconds..",
     2193                    i, tr_peerIoAddrStr( &atom->addr, atom->port ), interval );
    21992194            continue;
    22002195        }
     
    22352230    else
    22362231    {
    2237         int                 i, nCandidates, nBad;
     2232        int i, nCandidates, nBad;
    22382233        struct peer_atom ** candidates = getPeerCandidates( t, &nCandidates );
    2239         struct tr_peer **   connections = getPeersToClose( t, &nBad );
     2234        struct tr_peer ** connections = getPeersToClose( t, &nBad );
    22402235
    22412236        if( nBad || nCandidates )
    2242             tordbg(
    2243                 t, "reconnect pulse for [%s]: %d bad connections, "
    2244                    "%d connection candidates, %d atoms, max per pulse is %d",
    2245                 t->tor->info.name, nBad, nCandidates,
    2246                 tr_ptrArraySize( t->pool ),
    2247                 (int)MAX_RECONNECTIONS_PER_PULSE );
     2237            tordbg( t, "reconnect pulse for [%s]: %d bad connections, "
     2238                    "%d connection candidates, %d atoms, max per pulse is %d",
     2239                    t->tor->info.name, nBad, nCandidates,
     2240                    tr_ptrArraySize( t->pool ),
     2241                    (int)MAX_RECONNECTIONS_PER_PULSE );
    22482242
    22492243        /* disconnect some peers.
     
    22512245           so reset their `numFails' weight to zero.  otherwise we connected
    22522246           to them fruitlessly, so mark it as another fail */
    2253         for( i = 0; i < nBad; ++i )
    2254         {
    2255             tr_peer *          peer = connections[i];
    2256             struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     2247        for( i = 0; i < nBad; ++i ) {
     2248            tr_peer * peer = connections[i];
     2249            struct peer_atom * atom = getExistingAtom( t, &peer->addr );
    22572250            if( atom->piece_data_time )
    22582251                atom->numFails = 0;
    22592252            else
    22602253                ++atom->numFails;
    2261             tordbg( t, "removing bad peer %s",
    2262                    tr_peerIoGetAddrStr( peer->io ) );
     2254            tordbg( t, "removing bad peer %s", tr_peerIoGetAddrStr( peer->io ) );
    22632255            removePeer( t, peer );
    22642256        }
     
    22682260           && ( i < MAX_RECONNECTIONS_PER_PULSE )
    22692261           && ( getPeerCount( t ) < getMaxPeerCount( t->tor ) )
    2270            && ( newConnectionsThisSecond < MAX_CONNECTIONS_PER_SECOND );
    2271              ++i )
     2262           && ( newConnectionsThisSecond < MAX_CONNECTIONS_PER_SECOND ); ++i )
    22722263        {
    22732264            tr_peerMgr *       mgr = t->manager;
     
    22782269                   tr_peerIoAddrStr( &atom->addr, atom->port ) );
    22792270
    2280             io =
    2281                 tr_peerIoNewOutgoing( mgr->session, &atom->addr, atom->port,
    2282                                       t->hash );
     2271            io = tr_peerIoNewOutgoing( mgr->session, &atom->addr, atom->port, t->hash );
    22832272            if( io == NULL )
    22842273            {
     
    22872276            else
    22882277            {
    2289                 tr_handshake * handshake = tr_handshakeNew(
    2290                     io,
    2291                     mgr->session->
    2292                     encryptionMode,
    2293                     myHandshakeDoneCB,
    2294                     mgr );
     2278                tr_handshake * handshake = tr_handshakeNew( io,
     2279                                                            mgr->session->encryptionMode,
     2280                                                            myHandshakeDoneCB,
     2281                                                            mgr );
    22952282
    22962283                assert( tr_peerIoGetTorrentHash( io ) );
     
    23402327bandwidthPulse( void * vmgr )
    23412328{
     2329    tr_handshake * handshake;
    23422330    tr_peerMgr * mgr = vmgr;
    23432331    managerLock( mgr );
    23442332
     2333    /* FIXME: this next line probably isn't necessary... */
    23452334    pumpAllPeers( mgr );
     2335
     2336    /* allocate bandwidth to the peers */
    23462337    tr_bandwidthAllocate( mgr->session->bandwidth, TR_UP, BANDWIDTH_PERIOD_MSEC );
    23472338    tr_bandwidthAllocate( mgr->session->bandwidth, TR_DOWN, BANDWIDTH_PERIOD_MSEC );
    2348     pumpAllPeers( mgr );
     2339
     2340    /* free all the finished handshakes */
     2341    while(( handshake = tr_ptrArrayPop( mgr->finishedHandshakes )))
     2342        tr_handshakeFree( handshake );
    23492343
    23502344    managerUnlock( mgr );
Note: See TracChangeset for help on using the changeset viewer.