Changeset 2967


Ignore:
Timestamp:
Sep 1, 2007, 1:37:41 PM (15 years ago)
Author:
charles
Message:

promote some fields up out of peer-msgs s.t. the manager knows about them and can use them for stat messages and deciding which peers to choke/unchoke. add cleanup code for shutting down a group of peers.

Location:
branches/encryption/libtransmission
Files:
1 added
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • branches/encryption/libtransmission/Makefile.am

    r2966 r2967  
    6565    peer-io.h \
    6666    peer-mgr.h \
     67    peer-mgr-private.h \
    6768    peer-msgs.h \
    6869    platform.h \
  • branches/encryption/libtransmission/peer-mgr.c

    r2965 r2967  
    1414#include <string.h> /* memcpy, memcmp */
    1515
    16 #include <arpa/inet.h>
    17 
    1816#include "transmission.h"
    1917#include "handshake.h"
     
    2220#include "peer-io.h"
    2321#include "peer-mgr.h"
    24 #include "peer-work.h"
     22#include "peer-mgr-private.h"
     23#include "peer-msgs.h"
    2524#include "ptrarray.h"
    2625#include "utils.h"
     
    3029typedef struct
    3130{
    32     struct in_addr in_addr;
    33     uint16_t port;
    34     tr_peerIo * io;
    35     int from;
    36 }
    37 Peer;
    38 
    39 typedef struct
    40 {
    4131    uint8_t hash[SHA_DIGEST_LENGTH];
    42     tr_ptrArray * peers; /* Peer */
     32    tr_ptrArray * peers; /* tr_peer */
    4333}
    4434Torrent;
     
    9787peerCompare( const void * va, const void * vb )
    9888{
    99     const Peer * a = (const Peer *) va;
    100     const Peer * b = (const Peer *) vb;
     89    const tr_peer * a = (const tr_peer *) va;
     90    const tr_peer * b = (const tr_peer *) vb;
    10191    return memcmp( &a->in_addr, &b->in_addr, sizeof(struct in_addr) );
    10292}
     
    10595peerCompareToAddr( const void * va, const void * vb )
    10696{
    107     const Peer * a = (const Peer *) va;
     97    const tr_peer * a = (const tr_peer *) va;
    10898    const struct in_addr * b = (const struct in_addr *) vb;
    10999    return memcmp( &a->in_addr, b, sizeof(struct in_addr) );
    110100}
    111101
    112 static Peer*
     102static tr_peer*
    113103getExistingPeer( Torrent * torrent, const struct in_addr * in_addr )
    114104{
    115     return (Peer*) tr_ptrArrayFindSorted( torrent->peers,
    116                                           in_addr,
    117                                           peerCompareToAddr );
    118 }
    119 
    120 static Peer*
     105    return (tr_peer*) tr_ptrArrayFindSorted( torrent->peers,
     106                                             in_addr,
     107                                             peerCompareToAddr );
     108}
     109
     110static tr_peer*
    121111getPeer( Torrent * torrent, const struct in_addr * in_addr )
    122112{
    123     Peer * peer = getExistingPeer( torrent, in_addr );
     113    tr_peer * peer = getExistingPeer( torrent, in_addr );
    124114    if( peer == NULL )
    125115    {
    126         peer = tr_new0( Peer, 1 );
     116        peer = tr_new0( tr_peer, 1 );
    127117        memcpy( &peer->in_addr, in_addr, sizeof(struct in_addr) );
    128118        tr_ptrArrayInsertSorted( torrent->peers, peer, peerCompare );
     
    132122
    133123static void
    134 freePeer( Peer * peer )
    135 {
    136 #warning free the peer-work state here
     124freePeer( tr_peer * peer )
     125{
     126    tr_peerMsgsFree( peer->msgs );
     127    tr_bitfieldFree( peer->have );
     128    tr_bitfieldFree( peer->blame );
     129    tr_bitfieldFree( peer->banned );
    137130    tr_peerIoFree( peer->io );
     131    tr_free( peer->client );
    138132    tr_free( peer );
    139133}
     
    143137{
    144138    int i, size;
    145     Peer ** peers = (Peer **) tr_ptrArrayPeek( t->peers, &size );
     139    tr_peer ** peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &size );
    146140    for( i=0; i<size; ++i )
    147141        freePeer( peers[i] );
     
    201195    } else {
    202196        uint16_t port;
    203         Peer * peer = getPeer( t, tr_peerIoGetAddress(io,&port) );
     197        tr_peer * peer = getPeer( t, tr_peerIoGetAddress(io,&port) );
    204198        peer->port = port;
    205199        peer->io = io;
    206         tr_peerWorkAdd( tr_torrentFindFromHash(manager->handle,hash), io );
     200        peer->msgs = tr_peerMsgsNew( tr_torrentFindFromHash(manager->handle,hash), peer );
    207201    }
    208202}
     
    234228    for( i=0; i<peerCount; ++i )
    235229    {
    236         Peer * peer;
     230        tr_peer * peer;
    237231        struct in_addr addr;
    238232        uint16_t port;
     
    273267    const Torrent * t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    274268    int i, peerCount;
    275     const Peer ** peers = (const Peer **) tr_ptrArrayPeek( t->peers, &peerCount );
     269    const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
    276270    uint8_t * ret = tr_new( uint8_t, peerCount * 6 );
    277271    uint8_t * walk = ret;
     
    326320        else {
    327321            int j, peerCount;
    328             const Peer ** peers = (const Peer **) tr_ptrArrayPeek( t->peers, &peerCount );
     322            const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
    329323            for( j=0; j<peerCount; ++j )
    330                 if( peers[i].ccc )
     324                if( tr_bitfieldHas( peers[i]->have, j ) )
    331325                    ++tab[i];
    332326        }
     
    346340    int i, size;
    347341    const Torrent * t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    348     const Peer ** peers = (const Peer **) tr_ptrArrayPeek( t->peers, &size );
     342    const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &size );
    349343
    350344    *setmePeersTotal          = size;
     
    355349    for( i=0; i<size; ++i )
    356350    {
    357         const Peer * peer = peers[i];
     351        const tr_peer * peer = peers[i];
    358352
    359353        if( peer->io == NULL ) /* not connected */
     
    379373    int i, size;
    380374    const Torrent * t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    381     const Peer ** peers = (const Peer **) tr_ptrArrayPeek( t->peers, &size );
     375    const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &size );
    382376    tr_peer_stat * ret;
    383377
     
    386380    for( i=0; i<size; ++i )
    387381    {
    388         const Peer * peer = peers[i];
     382        const tr_peer * peer = peers[i];
    389383        const int live = peer->io != NULL;
    390384        tr_peer_stat * stat = ret + i;
    391385
    392386        tr_netNtop( &peer->in_addr, stat->addr, sizeof(stat->addr) );
    393         stat->port = peer->port;
    394         stat->from = peer->from;
    395         stat->isConnected = live;
     387        stat->port             = peer->port;
     388        stat->from             = peer->from;
     389        stat->client           = peer->client;
     390        stat->progress         = peer->progress;
     391        stat->isConnected      = live;
    396392        stat->uploadToRate     = tr_peerIoGetRateToPeer( peer->io );
    397393        stat->downloadFromRate = tr_peerIoGetRateToClient( peer->io );
    398         stat->isDownloading    =  stat->uploadToRate > 0.01;
    399         stat->isUploading      =  stat->downloadFromRate > 0.01;
    400 
    401 #warning FIXME
    402         //stat->progress = tr_peerProgress( peer );
    403         //stat->client = tr_peerClient( peer );
     394        stat->isDownloading    = stat->uploadToRate > 0.01;
     395        stat->isUploading      = stat->downloadFromRate > 0.01;
    404396    }
    405397
     
    409401
    410402void
    411 tr_peerMgrDisablePex( tr_peerMgr    * manager UNUSED,
    412                       const uint8_t * torrentHash UNUSED,
    413                       int             disable UNUSED)
    414 {
    415 #warning FIXME
    416 #if 0
    417     if( ( tor->pexDisabled != disable ) && ! ( TR_FLAG_PRIVATE & tor->info.flags ) ) {
    418         int i;
     403tr_peerMgrDisablePex( tr_peerMgr    * manager,
     404                      const uint8_t * torrentHash,
     405                      int             disable)
     406{
     407    tr_torrent * tor = tr_torrentFindFromHash( manager->handle, torrentHash );
     408
     409    if( ( tor->pexDisabled != disable ) && ! ( TR_FLAG_PRIVATE & tor->info.flags ) )
     410    {
     411        int i, size;
     412        Torrent * t = getExistingTorrent( manager, torrentHash );
     413        tr_peer ** peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &size );
     414        for( i=0; i<size; ++i ) {
     415            peers[i]->pexEnabled = disable ? 0 : 1;
     416            peers[i]->lastPexTime = 0;
     417        }
     418
    419419        tor->pexDisabled = disable;
    420         for( i=0; i<tor->peerCount; ++i )
    421             tr_peerSetPrivate( tor->peers[i], disable );
    422     }
    423 #endif
    424 }
     420    }
     421}
  • branches/encryption/libtransmission/peer-msgs.c

    r2966 r2967  
    2929#include "peer-io.h"
    3030#include "peer-mgr.h"
     31#include "peer-mgr-private.h"
     32#include "peer-msgs.h"
    3133#include "ratecontrol.h"
    3234#include "timer.h"
     
    99101}
    100102
    101 typedef struct
    102 {
     103struct tr_peermsgs
     104{
     105    tr_peer * peer;
     106
    103107    tr_handle * handle;
    104108    tr_torrent * torrent;
    105109    tr_peerIo * io;
    106     tr_bitfield * bitfield;   /* the peer's bitfield */
    107     tr_bitfield * banfield;   /* bad pieces from the peer */
    108     tr_bitfield * blamefield; /* lists pieces that this peer helped us with */
    109110
    110111    struct evbuffer * outMessages; /* buffer of all the non-piece messages */
     
    131132    uint64_t gotKeepAliveTime;
    132133
    133     float progress;
    134 
    135134    uint16_t ut_pex;
    136135    uint16_t listeningPort;
    137 
    138     /* the client name from the `v' string in LTEP's handshake dictionary */
    139     char * client;
    140 }
    141 tr_peer;
     136};
    142137
    143138/**
     
    146141
    147142static int
    148 isPieceInteresting( const tr_peer   * peer,
    149                     int               piece )
     143isPieceInteresting( const tr_peermsgs   * peer,
     144                    int                   piece )
    150145{
    151146    const tr_torrent * torrent = peer->torrent;
     
    154149    if( tr_cpPieceIsComplete( torrent->completion, piece ) ) /* we already have it */
    155150        return FALSE;
    156     if( !tr_bitfieldHas( peer->bitfield, piece ) ) /* peer doesn't have it */
     151    if( !tr_bitfieldHas( peer->peer->have, piece ) ) /* peer doesn't have it */
    157152        return FALSE;
    158     if( tr_bitfieldHas( peer->banfield, piece ) ) /* peer is banned for it */
     153    if( tr_bitfieldHas( peer->peer->banned, piece ) ) /* peer is banned for it */
    159154        return FALSE;
    160155    return TRUE;
     
    162157
    163158static int
    164 isInteresting( const tr_peer * peer )
     159isInteresting( const tr_peermsgs * peer )
    165160{
    166161    int i;
     
    168163    const tr_bitfield * bitfield = tr_cpPieceBitfield( torrent->completion );
    169164
    170     if( !peer->bitfield ) /* We don't know what this peer has */
     165    if( !peer->peer->have ) /* We don't know what this peer has */
    171166        return FALSE;
    172167
    173     assert( bitfield->len == peer->bitfield->len );
     168    assert( bitfield->len == peer->peer->have->len );
    174169
    175170    for( i=0; i<torrent->info.pieceCount; ++i )
     
    181176
    182177static void
    183 sendInterest( tr_peer * peer, int weAreInterested )
     178sendInterest( tr_peermsgs * peer, int weAreInterested )
    184179{
    185180    const uint32_t len = sizeof(uint8_t);
     
    192187
    193188static void
    194 updateInterest( tr_peer * peer )
     189updateInterest( tr_peermsgs * peer )
    195190{
    196191    const int i = isInteresting( peer );
     
    200195
    201196void
    202 setChoke( tr_peer * peer, int choke )
     197setChoke( tr_peermsgs * peer, int choke )
    203198{
    204199    if( peer->peerIsChoked != !!choke )
     
    225220
    226221static void
    227 parseLtepHandshake( tr_peer * peer, int len, struct evbuffer * inbuf )
     222parseLtepHandshake( tr_peermsgs * peer, int len, struct evbuffer * inbuf )
    228223{
    229224    benc_val_t val, * sub;
     
    253248    if( tr_bencIsStr( sub ) ) {
    254249int i;
    255         tr_free( peer->client );
     250        tr_free( peer->peer->client );
    256251        fprintf( stderr, "dictionary says client is [%s]\n", sub->val.s.s );
    257252for( i=0; i<sub->val.s.i; ++i ) fprintf( stderr, "[%c] (%d)\n", sub->val.s.s[i], (int)sub->val.s.s[i] );
    258         peer->client = tr_strndup( sub->val.s.s, sub->val.s.i );
    259         fprintf( stderr, "peer->client is now [%s]\n", peer->client );
     253        peer->peer->client = tr_strndup( sub->val.s.s, sub->val.s.i );
     254        fprintf( stderr, "peer->client is now [%s]\n", peer->peer->client );
    260255    }
    261256
     
    272267
    273268static void
    274 parseUtPex( tr_peer * peer, int msglen, struct evbuffer * inbuf )
     269parseUtPex( tr_peermsgs * peer, int msglen, struct evbuffer * inbuf )
    275270{
    276271    benc_val_t val, * sub;
     
    304299
    305300static void
    306 parseLtep( tr_peer * peer, int msglen, struct evbuffer * inbuf )
     301parseLtep( tr_peermsgs * peer, int msglen, struct evbuffer * inbuf )
    307302{
    308303    uint8_t ltep_msgid;
     
    329324
    330325static int
    331 readBtLength( tr_peer * peer, struct evbuffer * inbuf )
     326readBtLength( tr_peermsgs * peer, struct evbuffer * inbuf )
    332327{
    333328    uint32_t len;
     
    350345
    351346static int
    352 readBtMessage( tr_peer * peer, struct evbuffer * inbuf )
     347readBtMessage( tr_peermsgs * peer, struct evbuffer * inbuf )
    353348{
    354349    uint8_t id;
     
    402397            fprintf( stderr, "got a BT_HAVE\n" );
    403398            tr_peerIoReadUint32( peer->io, inbuf, &ui32 );
    404             tr_bitfieldAdd( peer->bitfield, ui32 );
    405             peer->progress = tr_bitfieldCountTrueBits( peer->bitfield ) / (float)peer->torrent->info.pieceCount;
     399            tr_bitfieldAdd( peer->peer->have, ui32 );
     400            peer->peer->progress = tr_bitfieldCountTrueBits( peer->peer->have ) / (float)peer->torrent->info.pieceCount;
    406401            updateInterest( peer );
    407402            break;
    408403
    409404        case BT_BITFIELD:
    410             assert( msglen == peer->bitfield->len );
     405            assert( msglen == peer->peer->have->len );
    411406            fprintf( stderr, "got a BT_BITFIELD\n" );
    412             tr_peerIoReadBytes( peer->io, inbuf, peer->bitfield->bits, msglen );
    413             peer->progress = tr_bitfieldCountTrueBits( peer->bitfield ) / (float)peer->torrent->info.pieceCount;
    414             fprintf( stderr, "peer progress is %f\n", peer->progress );
     407            tr_peerIoReadBytes( peer->io, inbuf, peer->peer->have->bits, msglen );
     408            peer->peer->progress = tr_bitfieldCountTrueBits( peer->peer->have ) / (float)peer->torrent->info.pieceCount;
     409            fprintf( stderr, "peer progress is %f\n", peer->peer->progress );
    415410            updateInterest( peer );
    416411            /* FIXME: maybe unchoke */
     
    482477
    483478static int
    484 canDownload( const tr_peer * peer )
     479canDownload( const tr_peermsgs * peer )
    485480{
    486481    tr_torrent * tor = peer->torrent;
    487482
    488483#if 0
    489     /* FIXME: was swift worth it?  did anyone notice a difference? :) */
     484    /* FIXME: was swift worth it?  did anyone notice a difference? */
    490485    if( SWIFT_ENABLED && !isSeeding && (peer->credit<0) )
    491486        return FALSE;
     
    502497
    503498static void
    504 gotBlock( tr_peer * peer, int pieceIndex, int offset, struct evbuffer * inbuf )
     499gotBlock( tr_peermsgs * peer, int pieceIndex, int offset, struct evbuffer * inbuf )
    505500{
    506501    tr_torrent * tor = peer->torrent;
     
    523518
    524519    /* make a note that this peer helped us with this piece */
    525     if( !peer->blamefield )
    526          peer->blamefield = tr_bitfieldNew( tor->info.pieceCount );
    527     tr_bitfieldAdd( peer->blamefield, pieceIndex );
     520    if( !peer->peer->blame )
     521         peer->peer->blame = tr_bitfieldNew( tor->info.pieceCount );
     522    tr_bitfieldAdd( peer->peer->blame, pieceIndex );
    528523
    529524    tr_cpBlockAdd( tor->completion, block );
     
    538533
    539534static ReadState
    540 readBtPiece( tr_peer * peer, struct evbuffer * inbuf )
     535readBtPiece( tr_peermsgs * peer, struct evbuffer * inbuf )
    541536{
    542537    assert( peer->blockToUs.length > 0 );
     
    575570{
    576571    ReadState ret;
    577     tr_peer * peer = (tr_peer *) vpeer;
     572    tr_peermsgs * peer = (tr_peermsgs *) vpeer;
    578573    struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
    579574    fprintf( stderr, "peer %p got a canRead; state is [%s]\n", peer, getStateName(peer->state) );
     
    594589
    595590static int
    596 canUpload( const tr_peer * peer )
     591canUpload( const tr_peermsgs * peer )
    597592{
    598593    const tr_torrent * tor = peer->torrent;
     
    610605pulse( void * vpeer )
    611606{
    612     tr_peer * peer = (tr_peer *) vpeer;
     607    tr_peermsgs * peer = (tr_peermsgs *) vpeer;
    613608    size_t len;
    614609
     
    658653didWrite( struct bufferevent * evin UNUSED, void * vpeer )
    659654{
    660     tr_peer * peer = (tr_peer *) vpeer;
     655    tr_peermsgs * peer = (tr_peermsgs *) vpeer;
    661656    fprintf( stderr, "peer %p got a didWrite...\n", peer );
    662657    pulse( vpeer );
     
    666661gotError( struct bufferevent * evbuf UNUSED, short what, void * vpeer )
    667662{
    668     tr_peer * peer = (tr_peer *) vpeer;
     663    tr_peermsgs * peer = (tr_peermsgs *) vpeer;
    669664    fprintf( stderr, "peer %p got an error in %d\n", peer, (int)what );
    670665}
    671666
    672667static void
    673 sendBitfield( tr_peer * peer )
     668sendBitfield( tr_peermsgs * peer )
    674669{
    675670    const tr_bitfield * bitfield = tr_cpPieceBitfield( peer->torrent->completion );
     
    683678}
    684679
    685 void
    686 tr_peerWorkAdd( struct tr_torrent * torrent,
    687                 struct tr_peerIo  * io )
    688 {
    689     tr_peer * peer;
    690 
    691     peer = tr_new0( tr_peer, 1 );
     680tr_peermsgs*
     681tr_peerMsgsNew( struct tr_torrent * torrent, struct tr_peer * peer_in )
     682{
     683    tr_peermsgs * peer;
     684
     685    assert( peer_in != NULL );
     686    assert( peer_in->io != NULL );
     687
     688    peer = tr_new0( tr_peermsgs, 1 );
     689    peer->peer = peer_in;
    692690    peer->handle = torrent->handle;
    693691    peer->torrent = torrent;
    694     peer->io = io;
     692    peer->io = peer_in->io;
    695693    peer->weAreChoked = 1;
    696694    peer->peerIsChoked = 1;
     
    698696    peer->peerIsInterested = 0;
    699697    peer->pulseTag = tr_timerNew( peer->handle, pulse, peer, NULL, 200 );
    700     peer->bitfield = tr_bitfieldNew( torrent->info.pieceCount );
     698    peer->peer->have = tr_bitfieldNew( torrent->info.pieceCount );
    701699    peer->outMessages = evbuffer_new( );
    702700    peer->outBlock = evbuffer_new( );
    703701    peer->inBlock = evbuffer_new( );
    704702
    705     tr_peerIoSetIOFuncs( io, canRead, didWrite, gotError, peer );
    706     tr_peerIoSetIOMode( io, EV_READ|EV_WRITE, 0 );
     703    tr_peerIoSetIOFuncs( peer->io, canRead, didWrite, gotError, peer );
     704    tr_peerIoSetIOMode( peer->io, EV_READ|EV_WRITE, 0 );
    707705
    708706    sendBitfield( peer );
    709 }
     707
     708    return peer;
     709}
     710
     711void
     712tr_peerMsgsFree( tr_peermsgs* p )
     713{
     714    tr_timerFree( &p->pulseTag );
     715    evbuffer_free( p->outMessages );
     716    evbuffer_free( p->outBlock );
     717    evbuffer_free( p->inBlock );
     718    tr_free( p );
     719}
  • branches/encryption/libtransmission/peer-msgs.h

    r2966 r2967  
    1515
    1616struct tr_torrent;
    17 struct tr_peerIo;
     17struct tr_peer;
    1818
    19 void tr_peerWorkAdd( struct tr_torrent  * torrent,
    20                      struct tr_peerIo   * io );
     19typedef struct tr_peermsgs tr_peermsgs;
     20
     21tr_peermsgs* tr_peerMsgsNew( struct tr_torrent  * torrent,
     22                             struct tr_peer     * peer );
     23
     24void         tr_peerMsgsFree( tr_peermsgs* );
    2125
    2226#endif
  • branches/encryption/libtransmission/torrent.c

    r2965 r2967  
    735735                            &s->peersSendingToUs,
    736736                            &s->peersGettingFromUs,
    737                             &s->peersFrom );
     737                             s->peersFrom );
    738738
    739739    s->percentComplete = tr_cpPercentComplete ( tor->completion );
Note: See TracChangeset for help on using the changeset viewer.