From 32f9de0ab9a9b9151ceeebc20fb8854f869b84af Mon Sep 17 00:00:00 2001 From: Josh Elsasser Date: Mon, 16 Apr 2007 21:21:00 +0000 Subject: [PATCH] Don't disconnect azureus peers with a newer peer protocol version, they seem to be able to speak version 1 to us just fine. Fix a bug with disconnecting peers when attempting to send empty PEX message. --- libtransmission/peeraz.h | 14 ++++----- libtransmission/peerext.h | 52 ++++++++++++++++++---------------- libtransmission/peermessages.h | 29 ++++++++++++++----- 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/libtransmission/peeraz.h b/libtransmission/peeraz.h index 9fdca83a6..2b8d9acc5 100644 --- a/libtransmission/peeraz.h +++ b/libtransmission/peeraz.h @@ -223,19 +223,15 @@ peertreeToBencAZ( tr_peertree_t * tree, benc_val_t * val ) return 0; } -static char * -makeAZPex( tr_torrent_t * tor, tr_peer_t * peer, int * len ) +static int +makeAZPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len ) { benc_val_t val; - char * buf; - - peer_dbg( "SEND azureus-pex" ); assert( !peer->private ); tr_bencInitStr( &val, tor->info.hash, sizeof( tor->info.hash ), 1 ); - buf = makeCommonPex( tor, peer, len, peertreeToBencAZ, "infohash", &val ); - - return buf; + return makeCommonPex( tor, peer, peertreeToBencAZ, "infohash", &val, + buf, len); } static int @@ -427,7 +423,7 @@ parseAZHandshake( tr_peer_t * peer, uint8_t * buf, int len ) } subsub = tr_bencDictFind( dict, "ver" ); if( NULL == subsub || TYPE_STR != subsub->type || - 1 != subsub->val.s.i || AZ_EXT_VERSION != subsub->val.s.s[0] ) + 1 != subsub->val.s.i || AZ_EXT_VERSION > subsub->val.s.s[0] ) { continue; } diff --git a/libtransmission/peerext.h b/libtransmission/peerext.h index ddf923ae2..6fdae9892 100644 --- a/libtransmission/peerext.h +++ b/libtransmission/peerext.h @@ -25,19 +25,20 @@ #define EXTENDED_HANDSHAKE_ID 0 #define EXTENDED_PEX_ID 1 -static char * -makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len, +static int +makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int ( *peerfunc )( tr_peertree_t *, benc_val_t * ), - const char * extrakey, benc_val_t * extraval ) + const char * extrakey, benc_val_t * extraval, + char ** retbuf, int * retlen ) { tr_peertree_t * sent, added, common; int ii; tr_peer_t * pp; tr_peertree_entry_t * found; benc_val_t val, * addval, * delval, * extra; - char * buf; - *len = 0; + *retbuf = NULL; + *retlen = 0; sent = &peer->sentPeers; peertreeInit( &added ); peertreeInit( &common ); @@ -60,20 +61,28 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len, peertreeMerge( sent, &common ); peertreeFree( &added ); tr_bencFree( extraval ); - return NULL; + return 1; } } + /* check if there were any added or deleted peers */ + if( peertreeEmpty( &added ) && peertreeEmpty( sent ) ) + { + peertreeMerge( sent, &common ); + peertreeFree( &added ); + tr_bencFree( extraval ); + return 0; + } + /* build the dictionaries */ tr_bencInit( &val, TYPE_DICT ); - if( ( peertreeEmpty( &added ) && peertreeEmpty( sent ) ) || - tr_bencDictReserve( &val, 3 ) ) + if( tr_bencDictReserve( &val, 3 ) ) { tr_bencFree( &val ); peertreeMerge( sent, &common ); peertreeFree( &added ); tr_bencFree( extraval ); - return NULL; + return 1; } extra = tr_bencDictAdd( &val, extrakey ); addval = tr_bencDictAdd( &val, "added" ); @@ -85,26 +94,26 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len, peertreeMerge( sent, &common ); peertreeFree( &added ); tr_bencFree( extraval ); - return NULL; + return 1; } *extra = *extraval; memset( extraval, 0, sizeof( extraval ) ); /* bencode it */ - buf = tr_bencSaveMalloc( &val, len ); + *retbuf = tr_bencSaveMalloc( &val, retlen ); tr_bencFree( &val ); - if( NULL == buf ) + if( NULL == *retbuf ) { peertreeMerge( sent, &common ); peertreeFree( &added ); - return NULL; + return 1; } peertreeSwap( sent, &common ); peertreeMerge( sent, &added ); peertreeFree( &common ); - return buf; + return 0; } static char * @@ -162,9 +171,6 @@ makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len ) peer->advertisedPort = tor->publicPort; - peer_dbg( "SEND extended-handshake, %s pex", - ( peer->private ? "without" : "with" ) ); - return buf; } @@ -201,19 +207,15 @@ peertreeToBencUT( tr_peertree_t * tree, benc_val_t * val ) return 0; } -static char * -makeUTPex( tr_torrent_t * tor, tr_peer_t * peer, int * len ) +static int +makeUTPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len ) { benc_val_t val; - char * ret; - - peer_dbg( "SEND extended-pex" ); assert( !peer->private ); tr_bencInitStr( &val, NULL, 0, 1 ); - ret = makeCommonPex( tor, peer, len, peertreeToBencUT, "added.f", &val ); - - return ret; + return makeCommonPex( tor, peer, peertreeToBencUT, "added.f", &val, + buf, len ); } static inline int diff --git a/libtransmission/peermessages.h b/libtransmission/peermessages.h index 083d3ce34..e815a4756 100644 --- a/libtransmission/peermessages.h +++ b/libtransmission/peermessages.h @@ -405,18 +405,28 @@ static int sendExtended( tr_torrent_t * tor, tr_peer_t * peer, int id ) { case EXTENDED_HANDSHAKE_ID: buf = makeExtendedHandshake( tor, peer, &len ); + if( NULL == buf ) + { + return TR_ERROR; + } + peer_dbg( "SEND extended-handshake, %s pex", + ( peer->private ? "without" : "with" ) ); break; case EXTENDED_PEX_ID: - buf = makeUTPex( tor, peer, &len ); + if( makeUTPex( tor, peer, &buf, &len ) ) + { + return TR_ERROR; + } + else if( NULL == buf ) + { + return TR_OK; + } + peer_dbg( "SEND extended-pex" ); break; default: assert( 0 ); break; } - if( NULL == buf ) - { - return TR_ERROR; - } /* add header and queue it to be sent */ p = getMessagePointer( peer, 1 + len, PEER_MSG_EXTENDED ); @@ -438,16 +448,21 @@ static int sendAZPex( tr_torrent_t * tor, tr_peer_t * peer ) char * buf; int len; - buf = makeAZPex( tor, peer, &len ); - if( NULL == buf ) + if( makeAZPex( tor, peer, &buf, &len ) ) { return TR_ERROR; } + else if( NULL == buf ) + { + return TR_OK; + } /* add header and queue it to be sent */ p = getMessagePointer( peer, len, AZ_MSG_AZ_PEER_EXCHANGE ); memcpy( p, buf, len ); free( buf ); + peer_dbg( "SEND azureus-pex" ); + return TR_OK; }