improved uTorrent handshaking, after talking to #utorrent-dev about minutae...

This commit is contained in:
Charles Kerr
2007-09-29 00:46:41 +00:00
parent 79973a8a93
commit 3f1d888354
5 changed files with 60 additions and 19 deletions
-3
View File
@@ -104,7 +104,6 @@ extern const char* getPeerId( void ) ;
struct tr_handshake
{
unsigned int peerSupportsEncryption : 1;
unsigned int havePeerID : 1;
unsigned int haveSentBitTorrentHandshake : 1;
unsigned int allowUnencryptedPeers : 1;
@@ -406,7 +405,6 @@ readYb( tr_handshake * handshake, struct evbuffer * inbuf )
dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") );
handshake->peerSupportsEncryption = isEncrypted;
tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
: PEER_ENCRYPTION_NONE );
if( !isEncrypted ) {
@@ -1001,7 +999,6 @@ fireDoneFunc( tr_handshake * handshake, int isConnected )
handshake->io,
isConnected,
peer_id,
handshake->peerSupportsEncryption,
handshake->doneUserData );
}
-1
View File
@@ -23,7 +23,6 @@ typedef void (*handshakeDoneCB)(struct tr_handshake * handshake,
struct tr_peerIo * io,
int isConnected,
const uint8_t * peerId,
int peerSupportsEncryption,
void * userData );
tr_handshake * tr_handshakeNew( struct tr_peerIo * io,
+8 -1
View File
@@ -21,15 +21,22 @@ struct tr_bitfield;
struct tr_peerIo;
struct tr_peermsgs;
enum
{
ENCRYPTION_PREFERENCE_UNKNOWN,
ENCRYPTION_PREFERENCE_YES,
ENCRYPTION_PREFERENCE_NO
};
typedef struct tr_peer
{
unsigned int peerIsChoked : 1;
unsigned int peerIsInterested : 1;
unsigned int clientIsChoked : 1;
unsigned int clientIsInterested : 1;
unsigned int peerSupportsEncryption : 1;
unsigned int doPurge : 1;
uint8_t encryption_preference;
uint8_t from;
uint16_t port;
struct in_addr in_addr;
+13 -5
View File
@@ -746,7 +746,6 @@ myHandshakeDoneCB( tr_handshake * handshake,
tr_peerIo * io,
int isConnected,
const uint8_t * peer_id,
int peerSupportsEncryption,
void * vmanager )
{
int ok = isConnected;
@@ -759,7 +758,6 @@ myHandshakeDoneCB( tr_handshake * handshake,
assert( io != NULL );
assert( isConnected==0 || isConnected==1 );
assert( peerSupportsEncryption==0 || peerSupportsEncryption==1 );
ours = tr_ptrArrayRemoveSorted( manager->handshakes,
handshake,
@@ -807,7 +805,6 @@ myHandshakeDoneCB( tr_handshake * handshake,
peer->msgs = tr_peerMsgsNew( t->tor, peer );
tr_free( peer->client );
peer->client = peer_id ? tr_clientForId( peer_id ) : NULL;
peer->peerSupportsEncryption = peerSupportsEncryption ? 1 : 0;
peer->msgsTag = tr_peerMsgsSubscribe( peer->msgs, msgsCallbackFunc, t );
peer->connectionChangedAt = time( NULL );
rechokeSoon( t );
@@ -922,6 +919,17 @@ tr_pexCompare( const void * va, const void * vb )
int tr_pexCompare( const void * a, const void * b );
static int
peerPrefersCrypto( const tr_peer * peer )
{
if( peer->encryption_preference == ENCRYPTION_PREFERENCE_YES )
return TRUE;
if( peer->encryption_preference == ENCRYPTION_PREFERENCE_NO )
return FALSE;
return tr_peerIoIsEncrypted( peer->io );
};
int
tr_peerMgrGetPeers( tr_peerMgr * manager,
@@ -943,8 +951,8 @@ tr_peerMgrGetPeers( tr_peerMgr * manager,
walk->port = peer->port;
walk->flags = 0;
if( peer->peerSupportsEncryption ) walk->flags |= 1;
if( peer->progress >= 1.0 ) walk->flags |= 2;
if( peerPrefersCrypto(peer) ) walk->flags |= 1;
if( peer->progress >= 1.0 ) walk->flags |= 2;
}
assert( ( walk - pex ) == peerCount );
+39 -9
View File
@@ -122,9 +122,10 @@ struct tr_peermsgs
time_t clientSentPexAt;
time_t clientSentAnythingAt;
unsigned int notListening : 1;
unsigned int peerSupportsPex : 1;
unsigned int hasSentLtepHandshake : 1;
unsigned int notListening : 1;
unsigned int peerSupportsPex : 1;
unsigned int clientSentLtepHandshake : 1;
unsigned int peerSentLtepHandshake : 1;
tr_bitfield * clientAllowedPieces;
tr_bitfield * peerAllowedPieces;
@@ -529,17 +530,34 @@ sendLtepHandshake( tr_peermsgs * msgs )
benc_val_t val, *m;
char * buf;
int len;
int pex;
const char * v = TR_NAME " " USERAGENT_PREFIX;
const int port = tr_getPublicPort( msgs->handle );
struct evbuffer * outbuf = evbuffer_new( );
if( msgs->clientSentLtepHandshake )
return;
dbgmsg( msgs, "sending an ltep handshake" );
msgs->clientSentLtepHandshake = 1;
/* decide if we want to advertise pex support */
if( msgs->torrent->pexDisabled )
pex = 0;
else if( msgs->peerSentLtepHandshake )
pex = msgs->peerSupportsPex ? 1 : 0;
else
pex = 1;
tr_bencInit( &val, TYPE_DICT );
tr_bencDictReserve( &val, 3 );
tr_bencDictReserve( &val, 4 );
tr_bencInitInt( tr_bencDictAdd( &val, "e" ), 1 );
m = tr_bencDictAdd( &val, "m" );
tr_bencInit( m, TYPE_DICT );
tr_bencDictReserve( m, 1 );
tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), OUR_LTEP_PEX );
if( pex ) {
tr_bencDictReserve( m, 1 );
tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), OUR_LTEP_PEX );
}
if( port > 0 )
tr_bencInitInt( tr_bencDictAdd( &val, "p" ), port );
tr_bencInitStr( tr_bencDictAdd( &val, "v" ), v, 0, 1 );
@@ -551,7 +569,9 @@ sendLtepHandshake( tr_peermsgs * msgs )
tr_peerIoWriteBytes ( msgs->io, outbuf, buf, len );
tr_peerIoWriteBuf( msgs->io, outbuf );
msgs->hasSentLtepHandshake = 1;
dbgmsg( msgs, "here is the ltep handshake we sent:" );
tr_bencPrint( &val );
/* cleanup */
tr_bencFree( &val );
@@ -567,6 +587,7 @@ parseLtepHandshake( tr_peermsgs * msgs, int len, struct evbuffer * inbuf )
uint8_t * tmp = tr_new( uint8_t, len );
tr_peerIoReadBytes( msgs->io, inbuf, tmp, len );
msgs->peerSentLtepHandshake = 1;
if( tr_bencLoad( tmp, len, &val, NULL ) || val.type!=TYPE_DICT ) {
dbgmsg( msgs, "GET extended-handshake, couldn't get dictionary" );
@@ -574,6 +595,16 @@ parseLtepHandshake( tr_peermsgs * msgs, int len, struct evbuffer * inbuf )
return;
}
dbgmsg( msgs, "here is the ltep handshake we read:" );
tr_bencPrint( &val );
/* does the peer prefer encrypted connections? */
sub = tr_bencDictFind( &val, "e" );
if( tr_bencIsInt( sub ) )
msgs->info->encryption_preference = sub->val.i
? ENCRYPTION_PREFERENCE_YES
: ENCRYPTION_PREFERENCE_NO;
/* check supported messages for utorrent pex */
sub = tr_bencDictFind( &val, "m" );
if( tr_bencIsDict( sub ) ) {
@@ -657,8 +688,7 @@ parseLtep( tr_peermsgs * msgs, int msglen, struct evbuffer * inbuf )
{
dbgmsg( msgs, "got ltep handshake" );
parseLtepHandshake( msgs, msglen, inbuf );
if( !msgs->hasSentLtepHandshake )
sendLtepHandshake( msgs );
sendLtepHandshake( msgs );
}
else if( ltep_msgid == msgs->ut_pex_id )
{