Changeset 1579


Ignore:
Timestamp:
Mar 23, 2007, 8:28:01 AM (15 years ago)
Author:
joshe
Message:

Merge PEX branch, I hope this works.

Location:
trunk
Files:
29 edited
6 copied

Legend:

Unmodified
Added
Removed
  • trunk/NEWS

    r620 r1579  
    11NEWS file for Transmission <http://transmission.m0k.org/>
     2
     30.7 ()
     4 - New icon
     5 - Automatic port configuration (NAT-PMP and UPnP)
     6 - Peer exchange (PEX) compatible with Azureus and uTorrent
     7 - Multitracker support
     8 - Listen to tracker's announce and min-announce intervals
     9 - Fix for sending invalid stats to trackers
     10 - Better scrape support
     11 - Bugfixes and improvements
     12 - OS X:
     13   + Download and seeding queue that can be user-arranged
     14   + Speed Limit: Second set of bandwidth limits that can be toggled or
     15     scheduled
     16   + Individual torrent bandwidth limits
     17   + Separate complete and incomplete download folders
     18   + Filter and search bar
     19   + Expanded Inspector with many additional views and stats
     20   + Fragment status view in Inspector shows downloaded or availability
     21   + Watch folder to auto add torrent files
     22   + Auto resizing of the main window
     23   + Minimal view to take up less space
     24   + Sounds when downloading and seeding complete
     25   + Warnings for directory unavailable or not enough space
     26   + Message log window
     27   + New toolbar icons
     28   + Built-in help files
    229
    3300.6.1 (2006/06/25)
  • trunk/libtransmission/bencode.c

    r1524 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    2727#define LIST_SIZE   20
    2828
     29static int makeroom( benc_val_t * val, int count )
     30{
     31    int len;
     32    void * new;
     33
     34    assert( TYPE_LIST == val->type || TYPE_DICT == val->type );
     35
     36    len = val->val.l.alloc;
     37    while( val->val.l.count + count >= len )
     38    {
     39        len += LIST_SIZE;
     40    }
     41
     42    if( len > val->val.l.alloc )
     43    {
     44        /* We need a bigger boat */
     45        new = realloc( val->val.l.vals, len * sizeof( benc_val_t ) );
     46        if( NULL == new )
     47        {
     48            return 1;
     49        }
     50        val->val.l.alloc = len;
     51        val->val.l.vals = new;
     52    }
     53
     54    return 0;
     55}
     56
    2957int _tr_bencLoad( char * buf, int len, benc_val_t * val, char ** end )
    3058{
    3159    char * p, * e, * foo;
    3260
    33     if( 1 >= len )
     61    if( NULL == buf || 1 >= len )
    3462    {
    3563        return 1;
     
    84112        while( cur - buf < len && cur[0] != 'e' )
    85113        {
    86             if( val->val.l.count == val->val.l.alloc )
    87             {
    88                 /* We need a bigger boat */
    89                 val->val.l.alloc += LIST_SIZE;
    90                 val->val.l.vals   =  realloc( val->val.l.vals,
    91                         val->val.l.alloc  * sizeof( benc_val_t ) );
    92             }
    93             if( tr_bencLoad( cur, len - (cur - buf),
     114            if( makeroom( val, 1 ) ||
     115                tr_bencLoad( cur, len - (cur - buf),
    94116                             &val->val.l.vals[val->val.l.count], &p ) )
    95117            {
     
    198220
    199221        case TYPE_STR:
    200             if( val->val.s.s )
     222            if( !val->val.s.nofree )
    201223            {
    202224                free( val->val.s.s );
     
    249271        }
    250272    }
     273    va_end( ap );
     274
     275    return ret;
     276}
     277
     278char * tr_bencStealStr( benc_val_t * val )
     279{
     280    assert( TYPE_STR == val->type );
     281    val->val.s.nofree = 1;
     282    return val->val.s.s;
     283}
     284
     285void _tr_bencInitStr( benc_val_t * val, char * str, int len, int nofree )
     286{
     287    tr_bencInit( val, TYPE_STR );
     288    val->val.s.s      = str;
     289    val->val.s.nofree = nofree;
     290    if( 0 >= len )
     291    {
     292        len = ( NULL == str ? 0 : strlen( str ) );
     293    }
     294    val->val.s.i = len;
     295}
     296
     297int tr_bencInitStrDup( benc_val_t * val, const char * str )
     298{
     299    char * new = NULL;
     300
     301    if( NULL != str )
     302    {
     303        new = strdup( str );
     304        if( NULL == new )
     305        {
     306            return 1;
     307        }
     308    }
     309
     310    _tr_bencInitStr( val, new, 0, 0 );
     311
     312    return 0;
     313}
     314
     315void tr_bencInitInt( benc_val_t * val, int64_t num )
     316{
     317    tr_bencInit( val, TYPE_INT );
     318    val->val.i = num;
     319}
     320
     321int tr_bencListAppend( benc_val_t * val, ... )
     322{
     323    va_list ap;
     324    int len;
     325    benc_val_t ** ptr;
     326
     327    assert( TYPE_LIST == val->type );
     328
     329    len = 0;
     330    va_start( ap, val );
     331    while( NULL != va_arg( ap, benc_val_t ** ) )
     332    {
     333        len++;
     334    }
     335    va_end( ap );
     336
     337    if( makeroom( val, len ) )
     338    {
     339        return 1;
     340    }
     341
     342    va_start( ap, val );
     343    while( NULL != ( ptr = va_arg( ap, benc_val_t ** ) ) )
     344    {
     345        *ptr = &val->val.l.vals[val->val.l.count];
     346        tr_bencInit( *ptr, TYPE_INT );
     347        val->val.l.count++;
     348    }
     349    va_end( ap );
     350
     351    return 0;
     352}
     353
     354int tr_bencListExtend( benc_val_t * val, int count )
     355{
     356    assert( TYPE_LIST == val->type );
     357
     358    if( makeroom( val, count ) )
     359    {
     360        return 1;
     361    }
     362
     363    return 0;
     364}
     365
     366static inline int _tr_bencDictAppend( benc_val_t * val, va_list ap,
     367                                      va_list ap2, int nofree )
     368{
     369    int len;
     370    char * key;
     371    benc_val_t ** ptr;
     372
     373    assert( TYPE_DICT == val->type );
     374
     375    len = 0;
     376    while( NULL != va_arg( ap, char * ) )
     377    {
     378        ptr = va_arg( ap, benc_val_t ** );
     379        assert( NULL != ptr );
     380        len += 2;
     381    }
     382
     383    if( makeroom( val, len ) )
     384    {
     385        return 1;
     386    }
     387
     388    while( NULL != ( key = va_arg( ap2, char * ) ) )
     389    {
     390        if( !nofree )
     391        {
     392            key = strdup( key );
     393            if( NULL == key )
     394            {
     395                return 1;
     396            }
     397        }
     398        ptr = va_arg( ap2, benc_val_t ** );
     399        tr_bencInitStr( &val->val.l.vals[val->val.l.count], key, 0, nofree );
     400        val->val.l.count++;
     401        *ptr = &val->val.l.vals[val->val.l.count];
     402        tr_bencInit( *ptr, TYPE_INT );
     403        val->val.l.count++;
     404    }
     405
     406    return 0;
     407}
     408
     409int tr_bencDictAppend( benc_val_t * val, ... )
     410{
     411    va_list ap, ap2;
     412    int     ret;
     413
     414    va_start( ap, val );
     415    va_start( ap2, val );
     416    ret = _tr_bencDictAppend( val, ap, ap2, 0 );
     417    va_end( ap2 );
     418    va_end( ap );
     419
     420    return ret;
     421}
     422
     423int tr_bencDictAppendNofree( benc_val_t * val, ... )
     424{
     425    va_list ap, ap2;
     426    int     ret;
     427
     428    va_start( ap, val );
     429    va_start( ap2, val );
     430    ret = _tr_bencDictAppend( val, ap, ap2, 1 );
     431    va_end( ap2 );
    251432    va_end( ap );
    252433
  • trunk/libtransmission/bencode.h

    r1524 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    4242            int    i;
    4343            char * s;
     44            int    nofree;
    4445        } s;
    4546        struct
     
    5960benc_val_t * tr_bencDictFind( benc_val_t * val, const char * key );
    6061benc_val_t * tr_bencDictFindFirst( benc_val_t * val, ... );
    61 char *       tr_bencSaveMalloc( benc_val_t * val, int * len );
    62 int          tr_bencSave( benc_val_t * val, char ** buf,
     62
     63/* marks a string as 'do not free' and returns it */
     64char *       tr_bencStealStr( benc_val_t * val );
     65
     66/* convenience functions for building benc_val_t structures */
     67
     68static inline void tr_bencInit( benc_val_t * val, int type )
     69{
     70    memset( val, 0, sizeof( *val ) );
     71    val->type = type;
     72}
     73
     74#define tr_bencInitStr( a, b, c, d ) \
     75    _tr_bencInitStr( (a), ( char * )(b), (c), (d) )
     76void   _tr_bencInitStr( benc_val_t * val, char * str, int len, int nofree );
     77int    tr_bencInitStrDup( benc_val_t * val, const char * str );
     78void   tr_bencInitInt( benc_val_t * val, int64_t num );
     79/* args are a NULL terminated list of benc_val_t** */
     80int    tr_bencListAppend( benc_val_t * val, ... );
     81/* args are a NULL terminated list of pairs of char * key, benc_val_t ** val */
     82int    tr_bencDictAppend( benc_val_t * val, ... );
     83/* like tr_bencDictAppend but char * key args are marked nofree */
     84int    tr_bencDictAppendNofree( benc_val_t * val, ... );
     85
     86/* insure val has room for at least count more items */
     87int tr_bencListExtend( benc_val_t * val, int count );
     88
     89char * tr_bencSaveMalloc( benc_val_t * val, int * len );
     90int    tr_bencSave( benc_val_t * val, char ** buf,
    6391                          int * used, int * max );
    6492
  • trunk/libtransmission/fastresume.h

    r1549 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    383383                    return 1;
    384384                }
    385                 tr_torrentAddCompact( tor, buf, len / 6 );
     385                tr_torrentAddCompact( tor, TR_PEER_FROM_CACHE, buf, len / 6 );
    386386                free( buf );
    387387                continue;
  • trunk/libtransmission/http.c

    r1436 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2006 Transmission authors and contributors
     4 * Copyright (c) 2006-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    450450    if( tr_sprintf( EXPANDBUF( http->header ), " HTTP/1.1" CR LF
    451451                    "Host: %s" CR LF
    452                     "User-Agent: Transmission/%d.%d" CR LF
     452                    "User-Agent: %s/%d.%d" CR LF
    453453                    "Connection: close" CR LF,
    454                     http->host, VERSION_MAJOR, VERSION_MINOR ) )
     454                    http->host, TR_NAME, VERSION_MAJOR, VERSION_MINOR ) )
    455455    {
    456456        goto err;
  • trunk/libtransmission/internal.h

    r1564 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    6565#  include <arpa/inet.h>
    6666#endif
     67
     68#define TR_NAME                 "Transmission"
    6769
    6870#ifndef INADDR_NONE
     
    98100   char pointers */
    99101#define TR_NTOHL(p,a) (a) = tr_ntohl((p))
    100 #define TR_HTONL(a,p) tr_htonl((a), (p))
     102#define TR_HTONL(a,p) tr_htonl((a), ( uint8_t * )(p))
    101103static inline uint32_t tr_ntohl( uint8_t * p )
    102104{
     
    145147#include "xml.h"
    146148
    147 void tr_torrentAddCompact( tr_torrent_t * tor, uint8_t * buf, int count );
     149void tr_torrentAddCompact( tr_torrent_t * tor, int from,
     150                           uint8_t * buf, int count );
    148151void tr_torrentAttachPeer( tr_torrent_t * tor, tr_peer_t * peer );
    149152
     
    166169    char            * id;
    167170    char            * key;
     171    uint8_t         * azId;
    168172    int               publicPort;
    169173
     
    224228    tr_handle_status_t stats[2];
    225229    int                statCur;
     230#define TR_AZ_ID_LEN            20
     231    uint8_t        azId[TR_AZ_ID_LEN];
    226232};
    227233
  • trunk/libtransmission/metainfo.c

    r1566 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    166166    }
    167167    inf->pieceCount = val->val.s.i / SHA_DIGEST_LENGTH;
    168     inf->pieces = (uint8_t *) val->val.s.s; /* Ugly, but avoids a memcpy */
    169     val->val.s.s = NULL;
     168    inf->pieces = (uint8_t *) tr_bencStealStr( val );
    170169
    171170    /* TODO add more tests so we don't crash on weird files */
  • trunk/libtransmission/net.h

    r1425 r1579  
    6060
    6161void tr_netNtop( const struct in_addr * addr, char * buf, int len );
     62
     63
     64#define tr_addrcmp( aa, bb )    memcmp( ( void * )(aa), ( void * )(bb), 4)
  • trunk/libtransmission/peer.c

    r1562 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    2424
    2525#include "transmission.h"
    26 
    27 #define MAX_REQUEST_COUNT 32
    28 #define OUR_REQUEST_COUNT 8  /* TODO: we should detect if we are on a
    29                                 high-speed network and adapt */
     26#include "peertree.h"
     27
     28#define MAX_REQUEST_COUNT       32
     29#define OUR_REQUEST_COUNT       8  /* TODO: we should detect if we are on a
     30                                      high-speed network and adapt */
     31#define PEX_PEER_CUTOFF         50 /* only try to add new peers from pex if
     32                                      we have fewer existing peers than this */
     33#define PEX_INTERVAL            60 /* don't send pex messages more frequently
     34                                      than PEX_INTERVAL +
     35                                      rand( PEX_INTERVAL / 10 ) seconds */
     36#define PEER_SUPPORTS_EXTENDED_MESSAGES( bits ) ( (bits)[5] & 0x10 )
     37#define PEER_SUPPORTS_AZUREUS_PROTOCOL( bits )  ( (bits)[0] & 0x80 )
     38
     39#define PEER_MSG_CHOKE          0
     40#define PEER_MSG_UNCHOKE        1
     41#define PEER_MSG_INTERESTED     2
     42#define PEER_MSG_UNINTERESTED   3
     43#define PEER_MSG_HAVE           4
     44#define PEER_MSG_BITFIELD       5
     45#define PEER_MSG_REQUEST        6
     46#define PEER_MSG_PIECE          7
     47#define PEER_MSG_CANCEL         8
     48#define PEER_MSG_PORT           9
     49#define PEER_MSG_EXTENDED       20
    3050
    3151typedef struct tr_request_s
     
    4666#define PEER_STATUS_IDLE        1 /* Need to connect */
    4767#define PEER_STATUS_CONNECTING  2 /* Trying to send handshake */
    48 #define PEER_STATUS_HANDSHAKE   4 /* Waiting for peer's handshake */
    49 #define PEER_STATUS_CONNECTED   8 /* Got peer's handshake */
     68#define PEER_STATUS_HANDSHAKE   3 /* Waiting for peer's handshake */
     69#define PEER_STATUS_AZ_GIVER    4 /* Sending Azureus handshake */
     70#define PEER_STATUS_AZ_RECEIVER 5 /* Receiving Azureus handshake */
     71#define PEER_STATUS_CONNECTED   6 /* Got peer's handshake */
    5072    int                 status;
    5173    int                 socket;
    52     char                incoming;
     74    char                from;
     75    char                private;
     76    char                azproto;  /* azureus peer protocol is being used */
    5377    uint64_t            date;
    5478    uint64_t            keepAlive;
     79
     80#define EXTENDED_NOT_SUPPORTED   0 /* extended messages not supported */
     81#define EXTENDED_SUPPORTED       1 /* waiting to send extended handshake */
     82#define EXTENDED_HANDSHAKE       2 /* sent extended handshake */
     83    uint8_t             extStatus;
     84    uint8_t             pexStatus;   /* peer's ut_pex id, 0 if not supported */
     85    uint64_t            lastPex;     /* time when last pex packet was sent */
     86    int                 advertisedPort; /* listening port we last told peer */
     87    tr_peertree_t       sentPeers;
    5588
    5689    char                amChoking;
     
    122155}
    123156
     157#include "peerext.h"
     158#include "peeraz.h"
    124159#include "peermessages.h"
    125160#include "peerutils.h"
     
    131166 * Initializes a new peer.
    132167 **********************************************************************/
    133 tr_peer_t * tr_peerInit( struct in_addr addr, in_port_t port, int s )
     168tr_peer_t * tr_peerInit( struct in_addr addr, in_port_t port, int s, int from )
    134169{
    135170    tr_peer_t * peer = peerInit();
     171
     172    assert( 0 <= from && TR_PEER_FROM__MAX > from );
    136173
    137174    peer->socket = s;
    138175    peer->addr = addr;
    139176    peer->port = port;
     177    peer->from = from;
    140178    if( s >= 0 )
    141179    {
     180        assert( TR_PEER_FROM_INCOMING == from );
    142181        peer->status = PEER_STATUS_CONNECTING;
    143         peer->incoming = 1;
    144182    }
    145183    else
     
    157195    int i, block;
    158196
     197    peertreeFree( &peer->sentPeers );
    159198    for( i = 0; i < peer->inRequestCount; i++ )
    160199    {
     
    181220    tr_rcClose( peer->upload );
    182221    free( peer );
     222}
     223
     224void tr_peerSetPrivate( tr_peer_t * peer, int private )
     225{
     226    peer->private = private;
    183227}
    184228
     
    320364
    321365    /* Connect */
    322     if( peer->status & PEER_STATUS_IDLE )
     366    if( PEER_STATUS_IDLE == peer->status )
    323367    {
    324368        peer->socket = tr_netOpenTCP( peer->addr, peer->port, 0 );
     
    331375
    332376    /* Try to send handshake */
    333     if( peer->status & PEER_STATUS_CONNECTING )
     377    if( PEER_STATUS_CONNECTING == peer->status )
    334378    {
    335379        uint8_t buf[68];
     
    339383        memcpy( &buf[1], "BitTorrent protocol", 19 );
    340384        memset( &buf[20], 0, 8 );
     385        buf[20] = 0x80;         /* azureus protocol */
     386        buf[25] = 0x10;         /* extended messages */
    341387        memcpy( &buf[28], inf->hash, 20 );
    342388        memcpy( &buf[48], tor->id, 20 );
     
    366412        return ret;
    367413    }
     414
     415    /* Try to send Azureus handshake */
     416    if( PEER_STATUS_AZ_GIVER == peer->status )
     417    {
     418        switch( sendAZHandshake( tor, peer ) )
     419        {
     420            case TR_NET_BLOCK:
     421                break;
     422            case TR_NET_CLOSE:
     423                peer_dbg( "connection closed" );
     424                return TR_ERROR;
     425            default:
     426                peer->status = PEER_STATUS_AZ_RECEIVER;
     427                break;
     428        }
     429    }
     430
    368431    if( peer->status < PEER_STATUS_CONNECTED )
    369432    {
     
    469532int tr_peerIsConnected( tr_peer_t * peer )
    470533{
    471     return peer->status & PEER_STATUS_CONNECTED;
     534    return PEER_STATUS_CONNECTED == peer->status;
    472535}
    473536
     
    477540 *
    478541 **********************************************************************/
    479 int tr_peerIsIncoming( tr_peer_t * peer )
    480 {
    481     return peer->incoming;
     542int tr_peerIsFrom( tr_peer_t * peer )
     543{
     544    return peer->from;
    482545}
    483546
  • trunk/libtransmission/peer.h

    r1534 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    3030typedef struct tr_peer_s tr_peer_t;
    3131
    32 tr_peer_t * tr_peerInit          ( struct in_addr, in_port_t, int socket );
     32tr_peer_t * tr_peerInit          ( struct in_addr, in_port_t, int sock, int );
    3333void        tr_peerDestroy       ( tr_peer_t * );
     34void        tr_peerSetPrivate    ( tr_peer_t *, int );
    3435void        tr_peerSetTorrent    ( tr_peer_t *, tr_torrent_t * );
    3536int         tr_peerRead          ( tr_peer_t * );
     
    3940int         tr_peerPulse         ( tr_peer_t * );
    4041int         tr_peerIsConnected   ( tr_peer_t * );
    41 int         tr_peerIsIncoming    ( tr_peer_t * );
     42int         tr_peerIsFrom        ( tr_peer_t * );
    4243int         tr_peerAmChoking     ( tr_peer_t * );
    4344int         tr_peerAmInterested  ( tr_peer_t * );
  • trunk/libtransmission/peermessages.h

    r1555 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    139139{
    140140    uint8_t * p;
     141    int       index = 0;
    141142
    142143    size += 4;
    143     if( 0 <= id )
     144    if( peer->azproto )
     145    {
     146        index = azmsgIdIndex( id );
     147        assert( 0 <= index );
     148        size += 4 + azmsgLen( index ) + 1;
     149    }
     150    else if( 0 <= id )
    144151    {
    145152        size++;
     
    158165    TR_HTONL( size - 4, p );
    159166    p += 4;
    160     if( 0 <= id )
     167    if( peer->azproto )
     168    {
     169        TR_HTONL( azmsgLen( index ), p );
     170        memcpy( p + 4, azmsgStr( index ), azmsgLen( index ) );
     171        p[ 4 + azmsgLen( index ) ] = AZ_EXT_VERSION;
     172        p += 4 + azmsgLen( index ) + 1;
     173    }
     174    else if( 0 <= id )
    161175    {
    162176        *p = id;
     
    174188static void sendKeepAlive( tr_peer_t * peer )
    175189{
    176     uint8_t * p;
    177 
    178     p = getMessagePointer( peer, 0, -1 );
     190    getMessagePointer( peer, 0, AZ_MSG_BT_KEEP_ALIVE );
    179191
    180192    peer_dbg( "SEND keep-alive" );
     
    189201static void sendChoke( tr_peer_t * peer, int yes )
    190202{
    191     uint8_t * p;
    192     int       id;
     203    int id;
    193204
    194205    id = ( yes ? PEER_MSG_CHOKE : PEER_MSG_UNCHOKE );
    195     p = getMessagePointer( peer, 0, id );
     206    getMessagePointer( peer, 0, id );
    196207
    197208    peer->amChoking = yes;
     
    214225static void sendInterest( tr_peer_t * peer, int yes )
    215226{
    216     uint8_t * p;
    217     int       id;
     227    int id;
    218228
    219229    id = ( yes ? PEER_MSG_INTERESTED : PEER_MSG_UNINTERESTED );
    220     p = getMessagePointer( peer, 0, id );
     230    getMessagePointer( peer, 0, id );
    221231
    222232    peer->amInterested = yes;
     
    337347    }
    338348}
     349
     350/***********************************************************************
     351 * sendExtended
     352 ***********************************************************************
     353 * Builds an extended message:
     354 *  - size = 6 + X (4 bytes)
     355 *  - id   = 20    (1 byte)
     356 *  - eid  = Y     (1 byte)
     357 *  - data         (X bytes)
     358 **********************************************************************/
     359static int sendExtended( tr_torrent_t * tor, tr_peer_t * peer, int id )
     360{
     361    uint8_t * p;
     362    char    * buf;
     363    int       len;
     364
     365    buf = NULL;
     366    switch( id )
     367    {
     368        case EXTENDED_HANDSHAKE_ID:
     369            buf = makeExtendedHandshake( tor, peer, &len );
     370            break;
     371        case EXTENDED_PEX_ID:
     372            buf = makeUTPex( tor, peer, &len );
     373            break;
     374        default:
     375            assert( 0 );
     376            break;
     377    }
     378    if( NULL == buf )
     379    {
     380        return 1;
     381    }
     382
     383    /* add header and queue it to be sent */
     384    p = getMessagePointer( peer, 1 + len, PEER_MSG_EXTENDED );
     385    p[0] = id;
     386    memcpy( p + 1, buf, len );
     387    free( buf );
     388
     389    return 0;
     390}
     391
     392/***********************************************************************
     393 * sendAZPex
     394 ***********************************************************************
     395 *
     396 **********************************************************************/
     397static int sendAZPex( tr_torrent_t * tor, tr_peer_t * peer )
     398{
     399    uint8_t * p;
     400    char    * buf;
     401    int       len;
     402
     403    buf = makeAZPex( tor, peer, &len );
     404    if( NULL == buf )
     405    {
     406        return 1;
     407    }
     408
     409    /* add header and queue it to be sent */
     410    p = getMessagePointer( peer, len, AZ_MSG_AZ_PEER_EXCHANGE );
     411    memcpy( p, buf, len );
     412    free( buf );
     413
     414    return 0;
     415}
  • trunk/libtransmission/peerparse.h

    r1535 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    441441}
    442442
     443static inline int
     444parseMessageHeader( tr_peer_t * peer, uint8_t * buf, int buflen,
     445                    int * msgid, int * msglen )
     446{
     447    if( 4 > buflen )
     448    {
     449        return TR_NET_BLOCK;
     450    }
     451
     452    /* Get payload size */
     453    TR_NTOHL( buf, *msglen );
     454
     455    if( 4 + *msglen > buflen )
     456    {
     457        /* We do not have the entire message */
     458        return TR_NET_BLOCK;
     459    }
     460
     461    if( 0 == *msglen )
     462    {
     463        /* keep-alive */
     464        peer_dbg( "GET  keep-alive" );
     465        *msgid = AZ_MSG_BT_KEEP_ALIVE;
     466        return 4;
     467    }
     468    else
     469    {
     470        /* Type of the message */
     471        *msgid = buf[4];
     472        (*msglen)--;
     473        return 5;
     474    }
     475}
     476
    443477static inline int parseMessage( tr_torrent_t * tor, tr_peer_t * peer,
    444                                 uint8_t * p, int len )
    445 {
    446     char id;
    447 
    448     /* Type of the message */
    449     id = *(p++);
    450     len--;
     478                                int id, uint8_t * p, int len )
     479{
     480    int extid;
    451481
    452482    switch( id )
     
    472502        case PEER_MSG_PORT:
    473503            return parsePort( peer, p, len );
     504        case PEER_MSG_EXTENDED:
     505            if( EXTENDED_NOT_SUPPORTED == peer->extStatus )
     506            {
     507                break;
     508            }
     509            if( 0 < len )
     510            {
     511                extid = p[0];
     512                p++;
     513                len--;
     514                if( EXTENDED_HANDSHAKE_ID == extid )
     515                {
     516                    return parseExtendedHandshake( peer, p, len );
     517                }
     518                else if( 0 < peer->pexStatus && extid == peer->pexStatus )
     519                {
     520                    return parseUTPex( tor, peer, p, len );
     521                }
     522                peer_dbg( "Unknown extended message '%hhu'", extid );
     523            }
     524            return 1;
     525        case AZ_MSG_BT_KEEP_ALIVE:
     526            return TR_OK;
     527        case AZ_MSG_AZ_PEER_EXCHANGE:
     528            if( peer->azproto && peer->pexStatus )
     529            {
     530                return parseAZPex( tor, peer, p, len );
     531            }
     532            break;
     533        case AZ_MSG_INVALID:
     534            return 0;
    474535    }
    475536
     
    527588    int       len;
    528589    uint8_t * p   = peer->buf;
    529     uint8_t * end = &p[peer->pos];
    530590    int       ret;
     591    int       msgid;
    531592
    532593    if( peer->banned )
     
    539600    while( peer->pos >= 4 )
    540601    {
    541         if( peer->status & PEER_STATUS_HANDSHAKE )
     602        if( PEER_STATUS_HANDSHAKE == peer->status )
    542603        {
    543604            char * client;
     
    566627            }
    567628
    568             peer->status  = PEER_STATUS_CONNECTED;
     629            peer->status = PEER_STATUS_CONNECTED;
     630            if( PEER_SUPPORTS_EXTENDED_MESSAGES( &p[20] ) )
     631            {
     632                peer_dbg( "extended messages supported" );
     633                peer->extStatus = EXTENDED_SUPPORTED;
     634            }
     635            else if( PEER_SUPPORTS_AZUREUS_PROTOCOL( &p[20] ) )
     636            {
     637                peer->azproto = 1;
     638                peer->status  = PEER_STATUS_AZ_GIVER;
     639                peer->date    = tr_date();
     640            }
    569641            memcpy( peer->id, &p[48], 20 );
    570642            p            += 68;
     
    588660            free( client );
    589661
    590             sendBitfield( tor, peer );
     662          justconnected:
     663            if( PEER_STATUS_CONNECTED == peer->status )
     664            {
     665                if( EXTENDED_SUPPORTED == peer->extStatus )
     666                {
     667                    if( sendExtended( tor, peer, EXTENDED_HANDSHAKE_ID ) )
     668                    {
     669                        return TR_ERROR;
     670                    }
     671                    peer->extStatus = EXTENDED_HANDSHAKE;
     672                }
     673                sendBitfield( tor, peer );
     674            }
    591675
    592676            continue;
    593677        }
    594        
    595         /* Get payload size */
    596         TR_NTOHL( p, len );
    597         p += 4;
    598 
    599         if( len > 9 + tor->blockSize )
     678        else if( peer->status < PEER_STATUS_CONNECTED )
     679        {
     680            ret = parseAZMessageHeader( peer, p, peer->pos, &msgid, &len );
     681            if( TR_NET_BLOCK & ret )
     682            {
     683                break;
     684            }
     685            else if( TR_NET_CLOSE & ret )
     686            {
     687                return TR_ERROR;
     688            }
     689            else
     690            {
     691                p         += ret;
     692                peer->pos -= ret;
     693                assert( len <= peer->pos );
     694                if( AZ_MSG_AZ_HANDSHAKE != msgid ||
     695                    parseAZHandshake( peer, p, len ) )
     696                {
     697                    return TR_ERROR;
     698                }
     699                p           += len;
     700                peer->pos   -= len;
     701                assert( 0 <= peer->pos );
     702                peer->status = PEER_STATUS_CONNECTED;
     703                goto justconnected;
     704            }
     705        }
     706
     707        if( peer->azproto )
     708        {
     709            ret = parseAZMessageHeader( peer, p, peer->pos, &msgid, &len );
     710        }
     711        else
     712        {
     713            ret = parseMessageHeader( peer, p, peer->pos, &msgid, &len );
     714        }
     715        if( TR_NET_BLOCK & ret )
     716        {
     717            break;
     718        }
     719        else if( TR_NET_CLOSE & ret )
     720        {
     721            return TR_ERROR;
     722        }
     723
     724        if( len > 8 + tor->blockSize )
    600725        {
    601726            /* This should never happen. Drop that peer */
     727            /* XXX could an extended message be longer than this? */
    602728            peer_dbg( "message too large (%d bytes)", len );
    603729            return TR_ERROR;
    604730        }
    605731
    606         if( !len )
    607         {
    608             /* keep-alive */
    609             peer_dbg( "GET  keep-alive" );
    610             peer->pos -= 4;
    611             continue;
    612         }
    613 
    614         if( &p[len] > end )
    615         {
    616             /* We do not have the entire message */
    617             p -= 4;
    618             break;
    619         }
    620 
    621         /* Remaining data after this message */
    622         peer->pos -= 4 + len;
    623 
    624         if( ( ret = parseMessage( tor, peer, p, len ) ) )
     732        p         += ret;
     733        peer->pos -= ret;
     734        assert( 0 <= peer->pos );
     735
     736        if( ( ret = parseMessage( tor, peer, msgid, p, len ) ) )
    625737        {
    626738            return ret;
    627739        }
    628740
    629         p += len;
     741        p         += len;
     742        peer->pos -= len;
     743        assert( 0 <= peer->pos );
    630744    }
    631745
  • trunk/libtransmission/peerutils.h

    r1534 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    3535
    3636    peer              = calloc( sizeof( tr_peer_t ), 1 );
     37    peertreeInit( &peer->sentPeers );
    3738    peer->amChoking   = 1;
    3839    peer->peerChoking = 1;
     
    4849{
    4950    /* Wait until we got the peers' ids */
    50     if( peer1->status < PEER_STATUS_CONNECTED ||
    51         peer2->status < PEER_STATUS_CONNECTED )
     51    if( peer1->status <= PEER_STATUS_HANDSHAKE ||
     52        peer2->status <= PEER_STATUS_HANDSHAKE )
    5253    {
    5354        return 1;
     
    5960static int checkPeer( tr_peer_t * peer )
    6061{
     62    tr_torrent_t * tor = peer->tor;
     63    uint64_t       now;
     64
     65    now = tr_date();
     66
    6167    if( peer->status < PEER_STATUS_CONNECTED &&
    62         tr_date() > peer->date + 8000 )
     68        now > peer->date + 8000 )
    6369    {
    6470        /* If it has been too long, don't wait for the socket
     
    7076    /* Drop peers who haven't even sent a keep-alive within the
    7177       last 3 minutes */
    72     if( tr_date() > peer->date + 180000 )
     78    if( now > peer->date + 180000 )
    7379    {
    7480        peer_dbg( "read timeout" );
     
    7884    /* Drop peers which are supposed to upload but actually
    7985       haven't sent anything within the last minute */
    80     if( peer->inRequestCount && tr_date() > peer->date + 60000 )
     86    if( peer->inRequestCount && now > peer->date + 60000 )
    8187    {
    8288        peer_dbg( "bad uploader" );
     
    8490    }
    8591
    86     if( peer->status & PEER_STATUS_CONNECTED )
     92    if( PEER_STATUS_CONNECTED == peer->status )
    8793    {
    8894        /* Send keep-alive every 2 minutes */
    89         if( tr_date() > peer->keepAlive + 120000 )
     95        if( now > peer->keepAlive + 120000 )
    9096        {
    9197            sendKeepAlive( peer );
    92             peer->keepAlive = tr_date();
     98            peer->keepAlive = now;
     99        }
     100
     101        /* Resend extended handshake if our public port changed */
     102        if( EXTENDED_HANDSHAKE == peer->extStatus &&
     103            tor->publicPort != peer->advertisedPort )
     104        {
     105            sendExtended( tor, peer, EXTENDED_HANDSHAKE_ID );
     106        }
     107
     108        /* Send peer list */
     109        if( !peer->private && 0 < peer->pexStatus )
     110        {
     111            if( 0 == peer->lastPex )
     112            {
     113                /* randomize time when first pex message is sent */
     114                peer->lastPex = now - 1000 * tr_rand( PEX_INTERVAL );
     115            }
     116            if( now > peer->lastPex + 1000 * PEX_INTERVAL )
     117            {
     118                if( ( EXTENDED_HANDSHAKE == peer->extStatus &&
     119                      !sendExtended( tor, peer, EXTENDED_PEX_ID ) ) ||
     120                    ( peer->azproto && !sendAZPex( tor, peer ) ) )
     121                {
     122                    peer->lastPex = now + 1000 * tr_rand( PEX_INTERVAL / 10 );
     123                }
     124            }
    93125        }
    94126    }
  • trunk/libtransmission/shared.c

    r1462 r1579  
    341341            break;
    342342        }
    343         s->peers[s->peerCount++] = tr_peerInit( addr, 0, socket );
     343        s->peers[s->peerCount++] = tr_peerInit( addr, 0, socket,
     344                                                TR_PEER_FROM_INCOMING );
    344345    }
    345346}
  • trunk/libtransmission/torrent.c

    r1576 r1579  
    127127    tor->id       = h->id;
    128128    tor->key      = h->key;
     129    tor->azId     = h->azId;
    129130    tor->finished = 0;
    130131
     
    292293    if( peerCount > 0 )
    293294    {
    294         tr_torrentAddCompact( tor, peerCompact, peerCount );
     295        tr_torrentAddCompact( tor, TR_PEER_FROM_TRACKER,
     296                              peerCompact, peerCount );
    295297        free( peerCompact );
    296298    }
     
    329331
    330332    s->peersTotal       = 0;
    331     s->peersIncoming    = 0;
     333    memset( s->peersFrom, 0, sizeof( s->peersFrom ) );
    332334    s->peersUploading   = 0;
    333335    s->peersDownloading = 0;
     
    340342        {
    341343            (s->peersTotal)++;
    342            
    343             if( tr_peerIsIncoming( peer ) )
    344             {
    345                 (s->peersIncoming)++;
    346             }
     344            (s->peersFrom[ tr_peerIsFrom( peer ) ])++;
    347345            if( tr_peerAmInterested( peer ) && !tr_peerIsChoking( peer ) )
    348346            {
     
    432430           
    433431            peers[i].isConnected   = tr_peerIsConnected( peer );
    434             peers[i].isIncoming    = tr_peerIsIncoming( peer );
     432            peers[i].from          = tr_peerIsFrom( peer );
    435433            peers[i].progress      = tr_peerProgress( peer );
    436434            peers[i].port          = tr_peerPort( peer );
     
    638636    }
    639637
     638    tr_peerSetPrivate( peer, tor->info.flags & TR_FLAG_PRIVATE );
    640639    tr_peerSetTorrent( peer, tor );
    641640    tor->peers[tor->peerCount++] = peer;
    642641}
    643642
    644 void tr_torrentAddCompact( tr_torrent_t * tor, uint8_t * buf, int count )
     643void tr_torrentAddCompact( tr_torrent_t * tor, int from,
     644                           uint8_t * buf, int count )
    645645{
    646646    struct in_addr addr;
     
    654654        memcpy( &port, buf, 2 ); buf += 2;
    655655
    656         peer = tr_peerInit( addr, port, -1 );
     656        peer = tr_peerInit( addr, port, -1, from );
    657657        tr_torrentAttachPeer( tor, peer );
    658658    }
     
    698698        if( peerCount > 0 )
    699699        {
    700             tr_torrentAddCompact( tor, peerCompact, peerCount );
     700            tr_torrentAddCompact( tor, TR_PEER_FROM_TRACKER,
     701                                  peerCompact, peerCount );
    701702            free( peerCompact );
    702703        }
  • trunk/libtransmission/tracker.c

    r1517 r1579  
    722722    tc->interval = beFoo->val.i;
    723723    tr_inf( "Tracker: interval = %d seconds", tc->interval );
    724 
    725     tc->interval = MIN( tc->interval, 300 );
    726724    tc->interval = MAX( 10, tc->interval );
    727725
     
    733731        tc->minInterval = beFoo->val.i;
    734732        tr_inf( "Tracker: min interval = %d seconds", tc->minInterval );
    735 
    736         tc->minInterval = MIN( tc->minInterval, 300 );
    737733        tc->minInterval = MAX( 10, tc->minInterval );
    738734
  • trunk/libtransmission/transmission.c

    r1564 r1579  
    6868        r         = tr_rand( 36 );
    6969        h->key[i] = ( r < 26 ) ? ( 'a' + r ) : ( '0' + r - 26 ) ;
     70    }
     71
     72    /* Azureus identity */
     73    for( i = 0; i < TR_AZ_ID_LEN; i++ )
     74    {
     75        h->azId[i] = tr_rand( 0xff );
    7076    }
    7177
  • trunk/libtransmission/transmission.h

    r1576 r1579  
    5252#define TR_DEFAULT_PORT   9090
    5353
     54#define TR_PEER_FROM__MAX       4
     55#define TR_PEER_FROM_INCOMING   0 /* connections made to the listening port */
     56#define TR_PEER_FROM_TRACKER    1 /* peers received from a tracker */
     57#define TR_PEER_FROM_CACHE      2 /* peers read from the peer cache */
     58#define TR_PEER_FROM_PEX        3 /* peers discovered via PEX */
     59
    5460/***********************************************************************
    5561 * Error codes
     
    404410    int                 eta;
    405411    int                 peersTotal;
    406     int                 peersIncoming;
     412    int                 peersFrom[TR_PEER_FROM__MAX];
    407413    int                 peersUploading;
    408414    int                 peersDownloading;
     
    426432   
    427433    int     isConnected;
    428     int     isIncoming;
     434    int     from;
    429435    float   progress;
    430436    int     port;
  • trunk/libtransmission/upnp.c

    r1463 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2006 Transmission authors and contributors
     4 * Copyright (c) 2006-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
     
    847847                               "PortMappingProtocol", "TCP",
    848848                               "InternalClient", dev->myaddr,
    849                                "PortMappingDescription",
    850                                    "Added by Transmission",
     849                               "PortMappingDescription", "Added by " TR_NAME,
    851850                               NULL );
    852851            break;
  • trunk/libtransmission/utils.c

    r1444 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
  • trunk/libtransmission/utils.h

    r1534 r1579  
    22 * $Id$
    33 *
    4  * Copyright (c) 2005-2006 Transmission authors and contributors
     4 * Copyright (c) 2005-2007 Transmission authors and contributors
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a
  • trunk/macosx/Controller.m

    r1577 r1579  
    483483        return;
    484484
    485     //wait for running transfers to stop (5 second timeout) and for NAT to be disabled
     485    //wait for running transfers to stop (5 second timeout)
    486486    NSDate * start = [NSDate date];
    487487    BOOL timeUp = NO;
     
    489489    enumerator = [fTorrents objectEnumerator];
    490490    Torrent * torrent;
    491     while (!timeUp && ((torrent = [enumerator nextObject])
    492             || tr_handleStatus(fLib)->natTraversalStatus != TR_NAT_TRAVERSAL_DISABLED))
     491    while (!timeUp && (torrent = [enumerator nextObject]))
    493492        while (![torrent isPaused] && !(timeUp = [start timeIntervalSinceNow] < -5.0))
    494493        {
     
    496495            [torrent update];
    497496        }
     497   
     498    //wait for NAT to be disabled (same 5 second timeout)
     499    while (!([start timeIntervalSinceNow] < -5.0)
     500                && tr_handleStatus(fLib)->natTraversalStatus != TR_NAT_TRAVERSAL_DISABLED)
     501        usleep(100000);
    498502}
    499503
  • trunk/macosx/English.lproj/InfoWindow.nib/info.nib

    r1295 r1579  
    44<dict>
    55        <key>IBDocumentLocation</key>
    6         <string>34 67 356 240 0 0 1152 842 </string>
     6        <string>29 56 356 240 0 0 1024 746 </string>
    77        <key>IBEditorPositions</key>
    88        <dict>
  • trunk/macosx/English.lproj/MainMenu.nib/info.nib

    r1307 r1579  
    3535        </array>
    3636        <key>IBSystem Version</key>
    37         <string>8L127</string>
     37        <string>8P135</string>
    3838</dict>
    3939</plist>
  • trunk/macosx/InfoWindowController.m

    r1577 r1579  
    4040#define TAB_INFO_HEIGHT 284.0
    4141#define TAB_ACTIVITY_HEIGHT 170.0
    42 #define TAB_PEERS_HEIGHT 268.0
    43 #define TAB_FILES_HEIGHT 268.0
     42#define TAB_PEERS_HEIGHT 279.0
     43#define TAB_FILES_HEIGHT 279.0
    4444#define TAB_OPTIONS_HEIGHT 117.0
    4545
     
    196196        [fLeechersField setStringValue: @""];
    197197        [fCompletedFromTrackerField setStringValue: @""];
    198         [fConnectedPeersField setStringValue: @""];
     198        [fConnectedPeersField setStringValue: NSLocalizedString(@"info not available", "Inspector -> Peers tab -> peers")];
    199199        [fDownloadingFromField setStringValue: @""];
    200200        [fUploadingToField setStringValue: @""];
     
    237237        [fHashField setToolTip: hashString];
    238238        [fSecureField setStringValue: [torrent privateTorrent]
    239                         ? NSLocalizedString(@"Private Torrent", "Inspector -> is private torrent")
     239                        ? NSLocalizedString(@"Private Torrent, PEX disabled", "Inspector -> is private torrent")
    240240                        : NSLocalizedString(@"Public Torrent", "Inspector -> is not private torrent")];
    241241        [fCommentView setString: commentString];
     
    382382   
    383383    BOOL active = [torrent isActive];
    384     [fConnectedPeersField setStringValue: active ? [NSString stringWithFormat: NSLocalizedString(@"%d (%d incoming)",
    385                                                                                 "Inspector -> Peers tab -> connected"),
    386                                                     [torrent totalPeers], [torrent totalPeersIncoming]]: @""];
     384   
     385    if (active)
     386    {
     387        int total = [torrent totalPeers];
     388        NSString * connected = [NSString stringWithFormat:
     389                                NSLocalizedString(@"%d Connected", "Inspector -> Peers tab -> peers"), total];
     390       
     391        if (total > 0)
     392        {
     393            NSMutableArray * components = [NSMutableArray arrayWithCapacity: 4];
     394            int count;
     395            if ((count = [torrent totalPeersTracker]) > 0)
     396                [components addObject: [NSString stringWithFormat:
     397                                        NSLocalizedString(@"%d tracker", "Inspector -> Peers tab -> peers"), count]];
     398            if ((count = [torrent totalPeersIncoming]) > 0)
     399                [components addObject: [NSString stringWithFormat:
     400                                        NSLocalizedString(@"%d incoming", "Inspector -> Peers tab -> peers"), count]];
     401            if ((count = [torrent totalPeersPex]) > 0)
     402                [components addObject: [NSString stringWithFormat:
     403                                        NSLocalizedString(@"%d PEX", "Inspector -> Peers tab -> peers"), count]];
     404            if ((count = [torrent totalPeersCache]) > 0)
     405                [components addObject: [NSString stringWithFormat:
     406                                        NSLocalizedString(@"%d cache", "Inspector -> Peers tab -> peers"), count]];
     407           
     408            connected = [NSString stringWithFormat: @"%@: %@", connected, [components componentsJoinedByString: @", "]];
     409        }
     410       
     411        [fConnectedPeersField setStringValue: connected];
     412    }
     413    else
     414        [fConnectedPeersField setStringValue: NSLocalizedString(@"info not available", "Inspector -> Peers tab -> peers")];
     415   
    387416    [fDownloadingFromField setStringValue: active ? [NSString stringWithInt: [torrent peersUploading]] : @""];
    388417    [fUploadingToField setStringValue: active ? [NSString stringWithInt: [torrent peersDownloading]] : @""];
     
    666695    {
    667696        NSDictionary * peerDic = [fPeers objectAtIndex: row];
     697       
     698        NSString * fromString;
     699        int from = [[peerDic objectForKey: @"From"] intValue];
     700        if (from == TR_PEER_FROM_INCOMING)
     701            fromString = NSLocalizedString(@"incoming connection", "Inspector -> Peers tab -> table row tooltip");
     702        else if (from == TR_PEER_FROM_CACHE)
     703            fromString = NSLocalizedString(@"cache", "Inspector -> Peers tab -> table row tooltip");
     704        else if (from == TR_PEER_FROM_PEX)
     705            fromString = NSLocalizedString(@"peer exchange", "Inspector -> Peers tab -> table row tooltip");
     706        else
     707            fromString = NSLocalizedString(@"tracker", "Inspector -> Peers tab -> table row tooltip");
     708       
    668709        return [NSString stringWithFormat: NSLocalizedString(@"Progress: %.1f%%"
    669710                    "\nPort: %@"
    670                     "\nFrom %@ connection", "Inspector -> Peers tab -> table row tooltip"),
     711                    "\nFrom: %@", "Inspector -> Peers tab -> table row tooltip"),
    671712                    [[peerDic objectForKey: @"Progress"] floatValue] * 100.0,
    672                     [peerDic objectForKey: @"Port"],
    673                     [[peerDic objectForKey: @"Incoming"] boolValue]
    674                         ? NSLocalizedString(@"incoming", "Inspector -> Peers tab -> table row tooltip")
    675                         : NSLocalizedString(@"outgoing", "Inspector -> Peers tab -> table row tooltip")];
     713                    [peerDic objectForKey: @"Port"], fromString];
    676714    }
    677715    return nil;
  • trunk/macosx/Torrent.h

    r1575 r1579  
    163163- (int) leechers;
    164164- (int) completedFromTracker;
     165
    165166- (int) totalPeers;
     167- (int) totalPeersTracker;
    166168- (int) totalPeersIncoming;
    167 - (int) totalPeersOutgoing;
     169- (int) totalPeersCache;
     170- (int) totalPeersPex;
     171
    168172- (int) peersUploading;
    169173- (int) peersDownloading;
  • trunk/macosx/Torrent.m

    r1576 r1579  
    946946        dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:
    947947            [NSNumber numberWithBool: peer->isConnected], @"Connected",
    948             [NSNumber numberWithBool: peer->isIncoming], @"Incoming",
     948            [NSNumber numberWithInt: peer->from], @"From",
    949949            [NSString stringWithCString: (char *) peer->addr encoding: NSUTF8StringEncoding], @"IP",
    950950            [NSString stringWithCString: (char *) peer->client encoding: NSUTF8StringEncoding], @"Client",
     
    10071007}
    10081008
     1009- (int) totalPeersTracker
     1010{
     1011    return fStat->peersFrom[TR_PEER_FROM_TRACKER];
     1012}
     1013
    10091014- (int) totalPeersIncoming
    10101015{
    1011     return fStat->peersIncoming;
    1012 }
    1013 
    1014 - (int) totalPeersOutgoing
    1015 {
    1016     return [self totalPeers] - [self totalPeersIncoming];
     1016    return fStat->peersFrom[TR_PEER_FROM_INCOMING];
     1017}
     1018
     1019- (int) totalPeersCache
     1020{
     1021    return fStat->peersFrom[TR_PEER_FROM_CACHE];
     1022}
     1023
     1024- (int) totalPeersPex
     1025{
     1026    return fStat->peersFrom[TR_PEER_FROM_PEX];
    10171027}
    10181028
Note: See TracChangeset for help on using the changeset viewer.