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.
This commit is contained in:
Josh Elsasser 2007-04-16 21:21:00 +00:00
parent 767b5629f7
commit 32f9de0ab9
3 changed files with 54 additions and 41 deletions

View File

@ -223,19 +223,15 @@ peertreeToBencAZ( tr_peertree_t * tree, benc_val_t * val )
return 0; return 0;
} }
static char * static int
makeAZPex( tr_torrent_t * tor, tr_peer_t * peer, int * len ) makeAZPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len )
{ {
benc_val_t val; benc_val_t val;
char * buf;
peer_dbg( "SEND azureus-pex" );
assert( !peer->private ); assert( !peer->private );
tr_bencInitStr( &val, tor->info.hash, sizeof( tor->info.hash ), 1 ); tr_bencInitStr( &val, tor->info.hash, sizeof( tor->info.hash ), 1 );
buf = makeCommonPex( tor, peer, len, peertreeToBencAZ, "infohash", &val ); return makeCommonPex( tor, peer, peertreeToBencAZ, "infohash", &val,
buf, len);
return buf;
} }
static int static int
@ -427,7 +423,7 @@ parseAZHandshake( tr_peer_t * peer, uint8_t * buf, int len )
} }
subsub = tr_bencDictFind( dict, "ver" ); subsub = tr_bencDictFind( dict, "ver" );
if( NULL == subsub || TYPE_STR != subsub->type || 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; continue;
} }

View File

@ -25,19 +25,20 @@
#define EXTENDED_HANDSHAKE_ID 0 #define EXTENDED_HANDSHAKE_ID 0
#define EXTENDED_PEX_ID 1 #define EXTENDED_PEX_ID 1
static char * static int
makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len, makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer,
int ( *peerfunc )( tr_peertree_t *, benc_val_t * ), 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; tr_peertree_t * sent, added, common;
int ii; int ii;
tr_peer_t * pp; tr_peer_t * pp;
tr_peertree_entry_t * found; tr_peertree_entry_t * found;
benc_val_t val, * addval, * delval, * extra; benc_val_t val, * addval, * delval, * extra;
char * buf;
*len = 0; *retbuf = NULL;
*retlen = 0;
sent = &peer->sentPeers; sent = &peer->sentPeers;
peertreeInit( &added ); peertreeInit( &added );
peertreeInit( &common ); peertreeInit( &common );
@ -60,20 +61,28 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len,
peertreeMerge( sent, &common ); peertreeMerge( sent, &common );
peertreeFree( &added ); peertreeFree( &added );
tr_bencFree( extraval ); 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 */ /* build the dictionaries */
tr_bencInit( &val, TYPE_DICT ); tr_bencInit( &val, TYPE_DICT );
if( ( peertreeEmpty( &added ) && peertreeEmpty( sent ) ) || if( tr_bencDictReserve( &val, 3 ) )
tr_bencDictReserve( &val, 3 ) )
{ {
tr_bencFree( &val ); tr_bencFree( &val );
peertreeMerge( sent, &common ); peertreeMerge( sent, &common );
peertreeFree( &added ); peertreeFree( &added );
tr_bencFree( extraval ); tr_bencFree( extraval );
return NULL; return 1;
} }
extra = tr_bencDictAdd( &val, extrakey ); extra = tr_bencDictAdd( &val, extrakey );
addval = tr_bencDictAdd( &val, "added" ); addval = tr_bencDictAdd( &val, "added" );
@ -85,26 +94,26 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len,
peertreeMerge( sent, &common ); peertreeMerge( sent, &common );
peertreeFree( &added ); peertreeFree( &added );
tr_bencFree( extraval ); tr_bencFree( extraval );
return NULL; return 1;
} }
*extra = *extraval; *extra = *extraval;
memset( extraval, 0, sizeof( extraval ) ); memset( extraval, 0, sizeof( extraval ) );
/* bencode it */ /* bencode it */
buf = tr_bencSaveMalloc( &val, len ); *retbuf = tr_bencSaveMalloc( &val, retlen );
tr_bencFree( &val ); tr_bencFree( &val );
if( NULL == buf ) if( NULL == *retbuf )
{ {
peertreeMerge( sent, &common ); peertreeMerge( sent, &common );
peertreeFree( &added ); peertreeFree( &added );
return NULL; return 1;
} }
peertreeSwap( sent, &common ); peertreeSwap( sent, &common );
peertreeMerge( sent, &added ); peertreeMerge( sent, &added );
peertreeFree( &common ); peertreeFree( &common );
return buf; return 0;
} }
static char * static char *
@ -162,9 +171,6 @@ makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
peer->advertisedPort = tor->publicPort; peer->advertisedPort = tor->publicPort;
peer_dbg( "SEND extended-handshake, %s pex",
( peer->private ? "without" : "with" ) );
return buf; return buf;
} }
@ -201,19 +207,15 @@ peertreeToBencUT( tr_peertree_t * tree, benc_val_t * val )
return 0; return 0;
} }
static char * static int
makeUTPex( tr_torrent_t * tor, tr_peer_t * peer, int * len ) makeUTPex( tr_torrent_t * tor, tr_peer_t * peer, char ** buf, int * len )
{ {
benc_val_t val; benc_val_t val;
char * ret;
peer_dbg( "SEND extended-pex" );
assert( !peer->private ); assert( !peer->private );
tr_bencInitStr( &val, NULL, 0, 1 ); tr_bencInitStr( &val, NULL, 0, 1 );
ret = makeCommonPex( tor, peer, len, peertreeToBencUT, "added.f", &val ); return makeCommonPex( tor, peer, peertreeToBencUT, "added.f", &val,
buf, len );
return ret;
} }
static inline int static inline int

View File

@ -405,18 +405,28 @@ static int sendExtended( tr_torrent_t * tor, tr_peer_t * peer, int id )
{ {
case EXTENDED_HANDSHAKE_ID: case EXTENDED_HANDSHAKE_ID:
buf = makeExtendedHandshake( tor, peer, &len ); buf = makeExtendedHandshake( tor, peer, &len );
if( NULL == buf )
{
return TR_ERROR;
}
peer_dbg( "SEND extended-handshake, %s pex",
( peer->private ? "without" : "with" ) );
break; break;
case EXTENDED_PEX_ID: 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; break;
default: default:
assert( 0 ); assert( 0 );
break; break;
} }
if( NULL == buf )
{
return TR_ERROR;
}
/* add header and queue it to be sent */ /* add header and queue it to be sent */
p = getMessagePointer( peer, 1 + len, PEER_MSG_EXTENDED ); 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; char * buf;
int len; int len;
buf = makeAZPex( tor, peer, &len ); if( makeAZPex( tor, peer, &buf, &len ) )
if( NULL == buf )
{ {
return TR_ERROR; return TR_ERROR;
} }
else if( NULL == buf )
{
return TR_OK;
}
/* add header and queue it to be sent */ /* add header and queue it to be sent */
p = getMessagePointer( peer, len, AZ_MSG_AZ_PEER_EXCHANGE ); p = getMessagePointer( peer, len, AZ_MSG_AZ_PEER_EXCHANGE );
memcpy( p, buf, len ); memcpy( p, buf, len );
free( buf ); free( buf );
peer_dbg( "SEND azureus-pex" );
return TR_OK; return TR_OK;
} }