diff --git a/libtransmission/clients.c b/libtransmission/clients.c index af429ad76..4755bb39b 100644 --- a/libtransmission/clients.c +++ b/libtransmission/clients.c @@ -320,14 +320,17 @@ char * tr_clientForId( uint8_t * id ) /* No match */ if( !ret ) { - if( id[0] != 0 ) + if( isprint( id[0] ) && isprint( id[1] ) && isprint( id[2] ) && + isprint( id[3] ) && isprint( id[4] ) && isprint( id[5] ) && + isprint( id[6] ) && isprint( id[7] ) ) { asprintf( &ret, "unknown client (%c%c%c%c%c%c%c%c)", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] ); } else { - asprintf( &ret, "unknown client" ); + asprintf( &ret, "unknown client (0x%02x%02x%02x%02x%02x%02x%02x%02x", + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] ); } } diff --git a/libtransmission/internal.h b/libtransmission/internal.h index 927262b26..30ae7d8db 100644 --- a/libtransmission/internal.h +++ b/libtransmission/internal.h @@ -41,6 +41,7 @@ int vasprintf( char **, const char *, va_list ); #include #include #include +#include #include #include #include diff --git a/libtransmission/peer.c b/libtransmission/peer.c index 4014ef219..a28ee664d 100644 --- a/libtransmission/peer.c +++ b/libtransmission/peer.c @@ -135,6 +135,8 @@ struct tr_peer_s tr_ratecontrol_t * download; tr_ratecontrol_t * upload; + + char * client; }; #define peer_dbg( a... ) __peer_dbg( peer, ## a ) @@ -218,9 +220,21 @@ void tr_peerDestroy( tr_peer_t * peer ) } tr_rcClose( peer->download ); tr_rcClose( peer->upload ); + free( peer->client ); free( peer ); } +const char * +tr_peerClient( tr_peer_t * peer ) +{ + if( NULL == peer->client ) + { + peer->client = tr_clientForId( peer->id ); + } + + return peer->client; +} + void tr_peerSetPrivate( tr_peer_t * peer, int private ) { if( peer->private == private ) diff --git a/libtransmission/peer.h b/libtransmission/peer.h index 3d56b83ee..1dc8e1f26 100644 --- a/libtransmission/peer.h +++ b/libtransmission/peer.h @@ -31,6 +31,7 @@ typedef struct tr_peer_s tr_peer_t; tr_peer_t * tr_peerInit ( struct in_addr, in_port_t, int sock, int ); void tr_peerDestroy ( tr_peer_t * ); +const char *tr_peerClient ( tr_peer_t * ); void tr_peerSetPrivate ( tr_peer_t *, int ); void tr_peerSetTorrent ( tr_peer_t *, tr_torrent_t * ); int tr_peerRead ( tr_peer_t * ); diff --git a/libtransmission/peeraz.h b/libtransmission/peeraz.h index d97ad5d4c..46359f922 100644 --- a/libtransmission/peeraz.h +++ b/libtransmission/peeraz.h @@ -359,6 +359,29 @@ parseAZHandshake( tr_peer_t * peer, uint8_t * buf, int len ) return TR_ERROR; } +#if 0 /* ugh, we have to deal with encoding if we do this */ + /* get peer's client name */ + sub = tr_bencDictFind( &val, "client" ); + sub2 = tr_bencDictFind( &val, "version" ); + if( NULL != sub && TYPE_STR == sub->type && + NULL != sub2 && TYPE_STR == sub->type ) + { + if( NULL == peer->client || + ( 0 != strncmp( peer->client, sub->val.s.s, sub->val.s.i ) || + ' ' != peer->client[sub->val.s.i] || + 0 != strcmp( peer->client + sub->val.s.i + 1, sub2->val.s.s ) ) ) + { + client = NULL; + asprintf( &client, "%s %s", sub->val.s.s, sub2->val.s.s ); + if( NULL != client ) + { + free( peer->client ); + peer->client = client; + } + } + } +#endif + /* get the peer's listening port */ sub = tr_bencDictFind( &val, "tcp_port" ); if( NULL != sub ) diff --git a/libtransmission/peerext.h b/libtransmission/peerext.h index 2f32ff953..fa5630248 100644 --- a/libtransmission/peerext.h +++ b/libtransmission/peerext.h @@ -219,7 +219,7 @@ static inline int parseExtendedHandshake( tr_peer_t * peer, uint8_t * buf, int len ) { benc_val_t val, * sub; - int dbgport, dbgpex; + int dbgport, dbgpex; if( tr_bencLoad( buf, len, &val, NULL ) ) { @@ -250,6 +250,21 @@ parseExtendedHandshake( tr_peer_t * peer, uint8_t * buf, int len ) } } +#if 0 /* ugh, we have to deal with encoding if we do this */ + /* get peer's client name */ + sub = tr_bencDictFind( &val, "v" ); + if( NULL != sub && TYPE_STR == sub->type && + ( NULL == peer->client || 0 != strcmp( sub->val.s.s, peer->client ) ) ) + { + client = tr_bencStealStr( sub ); + if( NULL != client ) + { + free( peer->client ); + peer->client = client; + } + } +#endif + /* get peer's listening port */ sub = tr_bencDictFind( &val, "p" ); dbgport = -1; diff --git a/libtransmission/peerparse.h b/libtransmission/peerparse.h index b0d095e1a..8c39a25ef 100644 --- a/libtransmission/peerparse.h +++ b/libtransmission/peerparse.h @@ -584,7 +584,6 @@ static inline int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer ) { tr_info_t * inf = &tor->info; int ii; - char * client; if( memcmp( &peer->buf[28], inf->hash, SHA_DIGEST_LENGTH ) ) { @@ -614,13 +613,12 @@ static inline int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer ) } } - client = tr_clientForId( (uint8_t *) peer->id ); if( PEER_SUPPORTS_EXTENDED_MESSAGES( &peer->buf[20] ) ) { peer->status = PEER_STATUS_CONNECTED; peer->extStatus = EXTENDED_SUPPORTED; peer_dbg( "GET handshake, ok (%s) extended messaging supported", - client ); + tr_peerClient( peer ) ); } else if( PEER_SUPPORTS_AZUREUS_PROTOCOL( &peer->buf[20] ) ) { @@ -628,14 +626,13 @@ static inline int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer ) peer->azproto = 1; peer->date = tr_date(); peer_dbg( "GET handshake, ok (%s) will use azureus protocol", - client ); + tr_peerClient( peer ) ); } else { peer->status = PEER_STATUS_CONNECTED; - peer_dbg( "GET handshake, ok (%s)", client ); + peer_dbg( "GET handshake, ok (%s)", tr_peerClient( peer ) ); } - free( client ); return TR_OK; } diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index eab01c4eb..55bb06386 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -497,8 +497,7 @@ tr_peer_stat_t * tr_torrentPeers( tr_torrent_t * tor, int * peerCount ) sizeof( peers[i].addr ) ); } - peers[i].client = tr_clientForId(tr_peerId(peer)); - + peers[i].client = tr_peerClient( peer ); peers[i].isConnected = tr_peerIsConnected( peer ); peers[i].from = tr_peerIsFrom( peer ); peers[i].progress = tr_peerProgress( peer ); @@ -521,16 +520,11 @@ tr_peer_stat_t * tr_torrentPeers( tr_torrent_t * tor, int * peerCount ) return peers; } -void tr_torrentPeersFree( tr_peer_stat_t * peers, int peerCount ) +void tr_torrentPeersFree( tr_peer_stat_t * peers, int peerCount UNUSED ) { - int i; - if (peers == NULL) return; - for (i = 0; i < peerCount; i++) - free( peers[i].client ); - free( peers ); } diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 144b7b62e..6c7adc922 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -452,7 +452,7 @@ struct tr_stat_s struct tr_peer_stat_s { char addr[INET_ADDRSTRLEN]; - char * client; + const char * client; int isConnected; int from;