diff --git a/libtransmission/peer.c b/libtransmission/peer.c index 3641ee993..1ec7c6b7a 100644 --- a/libtransmission/peer.c +++ b/libtransmission/peer.c @@ -111,6 +111,10 @@ static const int SWIFT_REFRESH_INTERVAL_SEC = 5; /* uncomment this to disable support for the azureus protocol bit */ /* #define DISABLE_AZPROTO */ +/* uncomment this to use the new reserved bits proposed here: + http://www.azureuswiki.com/index.php/Extension_negotiation_protocol */ +/* #define NEW_AZ_BITS */ + #define HANDSHAKE_NAME "\023BitTorrent protocol" #define HANDSHAKE_NAME_LEN 20 #define HANDSHAKE_FLAGS_OFF HANDSHAKE_NAME_LEN @@ -119,6 +123,7 @@ static const int SWIFT_REFRESH_INTERVAL_SEC = 5; #define HANDSHAKE_PEERID_OFF ( HANDSHAKE_HASH_OFF + SHA_DIGEST_LENGTH ) #define HANDSHAKE_SIZE ( HANDSHAKE_PEERID_OFF + TR_ID_LEN ) +/* these macros test and set the bit indicating extended messaging support */ #ifdef DISABLE_EXTMSGS #define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 ) #define HANDSHAKE_SET_EXTMSGS( bits ) ( (void)0 ) @@ -127,6 +132,7 @@ static const int SWIFT_REFRESH_INTERVAL_SEC = 5; #define HANDSHAKE_SET_EXTMSGS( bits ) ( (bits)[5] |= 0x10 ) #endif +/* these macros test and set the bit indicating azureus protocol support */ #ifdef DISABLE_AZPROTO #define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 ) #define HANDSHAKE_SET_AZPROTO( bits ) ( (void)0 ) @@ -135,6 +141,20 @@ static const int SWIFT_REFRESH_INTERVAL_SEC = 5; #define HANDSHAKE_SET_AZPROTO( bits ) ( (bits)[0] |= 0x80 ) #endif +/* these macros are to be used if both extended messaging and the + azureus protocol is supported, they indicate which protocol is preferred */ +#ifdef NEW_AZ_BITS +#define HANDSHAKE_GET_EXTPREF( bits ) ( (bits)[5] & 0x03 ) +#define HANDSHAKE_SET_EXTPREF( bits, val ) ( (bits)[5] |= 0x03 & (val) ) +#else +#define HANDSHAKE_GET_EXTPREF( bits ) ( 0 ) +#define HANDSHAKE_SET_EXTPREF( bits, val ) ( (void)0 ) +#endif +#define HANDSHAKE_EXTPREF_FORCE_EXT ( 0x00 ) +#define HANDSHAKE_EXTPREF_WANT_EXT ( 0x01 ) +#define HANDSHAKE_EXTPREF_WANT_AZ ( 0x10 ) +#define HANDSHAKE_EXTPREF_FORCE_AZ ( 0x11 ) + #define PEER_MSG_CHOKE 0 #define PEER_MSG_UNCHOKE 1 #define PEER_MSG_INTERESTED 2 @@ -558,6 +578,8 @@ int tr_peerPulse( tr_peer_t * peer ) memset( buf + HANDSHAKE_FLAGS_OFF, 0, HANDSHAKE_FLAGS_LEN ); HANDSHAKE_SET_EXTMSGS( buf + HANDSHAKE_FLAGS_OFF ); HANDSHAKE_SET_AZPROTO( buf + HANDSHAKE_FLAGS_OFF ); + HANDSHAKE_SET_EXTPREF( buf + HANDSHAKE_FLAGS_OFF, + HANDSHAKE_EXTPREF_WANT_EXT ); memcpy( buf + HANDSHAKE_HASH_OFF, inf->hash, SHA_DIGEST_LENGTH ); memcpy( buf + HANDSHAKE_PEERID_OFF, tor->peer_id, TR_ID_LEN ); diff --git a/libtransmission/peerparse.h b/libtransmission/peerparse.h index 60bdeddd2..f5669b411 100644 --- a/libtransmission/peerparse.h +++ b/libtransmission/peerparse.h @@ -603,7 +603,8 @@ static const uint8_t * parseBufHash( const tr_peer_t * peer ) static int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer ) { tr_info_t * inf = &tor->info; - int ii; + int ii, extmsgs, azproto; + char * dbgsup, * dbgwant; if( 0 != memcmp( peer->buf + HANDSHAKE_HASH_OFF, inf->hash, SHA_DIGEST_LENGTH ) ) @@ -635,26 +636,63 @@ static int parseHandshake( tr_torrent_t * tor, tr_peer_t * peer ) } } + extmsgs = 0; + azproto = 0; + dbgsup = ""; + dbgwant = ""; + if( HANDSHAKE_HAS_EXTMSGS( peer->buf + HANDSHAKE_FLAGS_OFF ) ) + { + dbgsup = " extended messaging supported"; + extmsgs = 1; + } + if( HANDSHAKE_HAS_AZPROTO( peer->buf + HANDSHAKE_FLAGS_OFF ) ) + { + dbgsup = " will use azureus protocol"; + azproto = 1; + } + if( extmsgs && azproto ) + { + dbgsup = " both extended and azureus messaging supported"; + switch( HANDSHAKE_GET_EXTPREF( peer->buf + HANDSHAKE_FLAGS_OFF ) ) + { + case HANDSHAKE_EXTPREF_FORCE_EXT: + dbgwant = ", peer forces extended"; + azproto = 0; + break; + case HANDSHAKE_EXTPREF_WANT_EXT: + dbgwant = ", peer prefers extended"; + azproto = 0; + break; + case HANDSHAKE_EXTPREF_WANT_AZ: + dbgwant = ", peer prefers azureus"; + extmsgs = 0; + break; + case HANDSHAKE_EXTPREF_FORCE_AZ: + dbgwant = ", peer forces azureus"; + extmsgs = 0; + break; + } + } + assert( !extmsgs || !azproto ); + + if( extmsgs ) { peer->status = PEER_STATUS_CONNECTED; peer->extStatus = EXTENDED_SUPPORTED; - peer_dbg( "GET handshake, ok (%s) extended messaging supported", - tr_peerClient( peer ) ); } - else if( HANDSHAKE_HAS_AZPROTO( peer->buf + HANDSHAKE_FLAGS_OFF ) ) + else if( azproto ) { peer->status = PEER_STATUS_AZ_GIVER; peer->azproto = 1; peer->date = tr_date(); - peer_dbg( "GET handshake, ok (%s) will use azureus protocol", - tr_peerClient( peer ) ); } else { peer->status = PEER_STATUS_CONNECTED; - peer_dbg( "GET handshake, ok (%s)", tr_peerClient( peer ) ); } + peer_dbg( "GET handshake, ok (%s)%s%s", + tr_peerClient( peer ), dbgsup, dbgwant ); return TR_OK; }