Changeset 3101


Ignore:
Timestamp:
Sep 20, 2007, 4:11:09 AM (15 years ago)
Author:
charles
Message:
  • add a public API call for setting encryption preferences
  • fix upload bug that caused us to send the same block out more than once
  • fix handshake bug that caused us to shun uTorrent and vice versa
  • fix minor memory leaks (valgrind).
  • move extension handshakes into peer-msgs
Location:
branches/encryption/libtransmission
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/encryption/libtransmission/handshake.c

    r3079 r3101  
    4444#define HANDSHAKE_SIZE          68
    4545
     46/***
     47****
     48***/
     49
     50enum
     51{
     52    HANDSHAKE_EXTPREF_LTEP_FORCE   = 0x0,
     53    HANDSHAKE_EXTPREF_LTEP_PREFER  = 0x1,
     54    HANDSHAKE_EXTPREF_AZMP_PREFER  = 0x2,
     55    HANDSHAKE_EXTPREF_AZMP_FORCE   = 0x3
     56};
     57
     58
    4659#ifdef ENABLE_LTEP
    47 #define HANDSHAKE_HAS_EXTMSGS( bits ) ( (bits)[5] & 0x10 )
    48 #define HANDSHAKE_SET_EXTMSGS( bits ) ( (bits)[5] |= 0x10 )
     60#define HANDSHAKE_HAS_EXTMSGS( bits ) ( ( (bits)[5] & 0x10 ) ? 1 : 0 )
     61#define HANDSHAKE_SET_EXTMSGS( bits ) ( ( (bits)[5] |= 0x10 ) ? 1 : 0 )
    4962#else
    5063#define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 )
     
    5366
    5467#ifdef ENABLE_AZMP
    55 #define HANDSHAKE_HAS_AZPROTO( bits ) ( (bits)[0] & 0x80 )
    56 #define HANDSHAKE_SET_AZPROTO( bits ) ( (bits)[0] |= 0x80 )
     68#define HANDSHAKE_HAS_AZPROTO( bits ) ( ( (bits)[0] & 0x80 ) ? 1 : 0 )
     69#define HANDSHAKE_SET_AZPROTO( bits ) ( ( (bits)[0] |= 0x80 ) ? 1 : 0 )
    5770#else
    5871#define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 )
     
    7083#define HANDSHAKE_EXTPREF_AZMP_FORCE   ( 0x3 )
    7184
     85enum
     86{
     87    PadA_MAXLEN = 512,
     88    PadB_MAXLEN = 512,
     89    PadC_MAXLEN = 512,
     90    PadD_MAXLEN = 512
     91};
     92
    7293extern const char* getPeerId( void ) ;
    7394
     
    7798struct tr_handshake
    7899{
    79     unsigned int peerSupportsEncryption : 1;
    80     unsigned int havePeerID             : 1;
     100    unsigned int peerSupportsEncryption       : 1;
     101    unsigned int havePeerID                   : 1;
     102    unsigned int haveSentBitTorrentHandshake  : 1;
     103    unsigned int shunUnencryptedPeers         : 1;
    81104    tr_peerIo * io;
    82105    tr_crypto * crypto;
     
    85108    uint8_t mySecret[96];
    86109    uint8_t state;
    87     uint8_t encryptionPreference;
    88110    uint16_t pad_c_len;
    89111    uint16_t pad_d_len;
     
    96118};
    97119
    98 static void
    99 fireDoneCB( tr_handshake * handshake, int isConnected );
    100 
    101120/**
    102121***
    103122**/
    104123
    105 enum /*ccc*/
     124enum
    106125{
    107126    /* incoming */
     
    123142***
    124143**/
     144
     145static void
     146myDebug( const char * file, int line, const tr_handshake * handshake, const char * fmt, ... )
     147{
     148    va_list args;
     149    const char * addr = tr_peerIoGetAddrStr( handshake->io );
     150    struct evbuffer * buf = evbuffer_new( );
     151    evbuffer_add_printf( buf, "[%s:%d] %s (%p) ", file, line, addr, handshake );
     152    va_start( args, fmt );
     153    evbuffer_add_vprintf( buf, fmt, args );
     154    va_end( args );
     155
     156    fprintf( stderr, "%s\n", EVBUFFER_DATA(buf) );
     157
     158    evbuffer_free( buf );
     159}
     160
     161#define dbgmsg(handshake, fmt...) myDebug(__FILE__, __LINE__, handshake, ##fmt )
    125162
    126163static const char* getStateName( short state )
     
    141178        case AWAITING_CRYPTO_SELECT:  str = "awaiting crypto select"; break;
    142179        case AWAITING_PAD_D:          str = "awaiting pad d"; break;
    143         //case SENDING_PLAINTEXT_HANDSHAKE: str = "sending plaintext handshake"; break;
     180        //case SENDING_NONE: str = "sending plaintext handshake"; break;
    144181    }
    145182    return str;
     
    149186setState( tr_handshake * handshake, short state )
    150187{
    151     fprintf( stderr, "handshake %p: setting to state [%s]\n", handshake, getStateName(state) );
     188    dbgmsg( handshake, "setting to state [%s]", getStateName(state) );
    152189    handshake->state = state;
    153190}
     
    160197}
    161198
     199static uint8_t *
     200buildHandshakeMessage( tr_handshake * handshake,
     201                       int            extensionPreference,
     202                       int          * setme_len )
     203{
     204    uint8_t * buf = tr_new0( uint8_t, HANDSHAKE_SIZE );
     205    uint8_t * walk = buf;
     206    const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );
     207
     208    memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
     209    walk += HANDSHAKE_NAME_LEN;
     210    memset( walk, 0, HANDSHAKE_FLAGS_LEN );
     211    switch( extensionPreference )
     212    {
     213        case HANDSHAKE_EXTPREF_LTEP_FORCE:
     214            HANDSHAKE_SET_EXTMSGS( walk );
     215            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
     216            break;
     217
     218        case HANDSHAKE_EXTPREF_LTEP_PREFER:
     219            HANDSHAKE_SET_EXTMSGS( walk );
     220            HANDSHAKE_SET_AZPROTO( walk );
     221            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
     222            break;
     223
     224        case HANDSHAKE_EXTPREF_AZMP_PREFER:
     225            HANDSHAKE_SET_EXTMSGS( walk );
     226            HANDSHAKE_SET_AZPROTO( walk );
     227            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
     228            break;
     229
     230        case HANDSHAKE_EXTPREF_AZMP_FORCE:
     231            HANDSHAKE_SET_AZPROTO( walk );
     232            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
     233            break;
     234    }
     235
     236    walk += HANDSHAKE_FLAGS_LEN;
     237    memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
     238    walk += SHA_DIGEST_LENGTH;
     239    memcpy( walk, getPeerId(), TR_ID_LEN );
     240    walk += TR_ID_LEN;
     241
     242    assert( walk-buf == HANDSHAKE_SIZE );
     243    *setme_len = walk - buf;
     244    return buf;
     245}
     246
     247/***
     248****
     249****  OUTGOING CONNECTIONS
     250****
     251***/
     252
     253/* 1 A->B: Diffie Hellman Ya, PadA */
    162254static void
    163 sendPublicKey( tr_handshake * handshake )
     255sendYa( tr_handshake * handshake )
    164256{
    165257    int i;
     
    167259    const uint8_t * public_key;
    168260    struct evbuffer * outbuf = evbuffer_new( );
    169     uint8_t pad[512];
     261    uint8_t pad_a[PadA_MAXLEN];
    170262
    171263    /* add our public key (Ya) */
     
    176268
    177269    /* add some bullshit padding */
    178     len = tr_rand( 512 );
     270    len = tr_rand( PadA_MAXLEN );
    179271    for( i=0; i<len; ++i )
    180         pad[i] = tr_rand( UCHAR_MAX );
    181     evbuffer_add( outbuf, pad, len );
     272        pad_a[i] = tr_rand( UCHAR_MAX );
     273    evbuffer_add( outbuf, pad_a, len );
    182274
    183275    /* send it */
    184276    setReadState( handshake, AWAITING_YB );
    185     //setState( handshake, SENDING_YA );
    186277    tr_peerIoWriteBuf( handshake->io, outbuf );
    187278
     
    189280    evbuffer_free( outbuf );
    190281}
    191 
    192 static void
    193 buildHandshakeMessage( tr_handshake * handshake, uint8_t * buf )
    194 {
    195     uint8_t *walk = buf;
    196     const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );
    197 
    198     memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
    199     walk += HANDSHAKE_NAME_LEN;
    200     memset( walk, 0, HANDSHAKE_FLAGS_LEN );
    201     HANDSHAKE_SET_EXTMSGS( walk );
    202     HANDSHAKE_SET_AZPROTO( walk );
    203     HANDSHAKE_SET_EXTPREF( walk, HANDSHAKE_EXTPREF_LTEP_PREFER );
    204     walk += HANDSHAKE_FLAGS_LEN;
    205     memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
    206     walk += SHA_DIGEST_LENGTH;
    207     memcpy( walk, getPeerId(), TR_ID_LEN );
    208     walk += TR_ID_LEN;
    209     assert( walk-buf == HANDSHAKE_SIZE );
    210 }
    211 
    212 static void
    213 sendPlaintextHandshake( tr_handshake * handshake )
    214 {
    215     uint8_t buf[HANDSHAKE_SIZE];
    216     buildHandshakeMessage( handshake, buf );
    217 
    218     setReadState( handshake, AWAITING_HANDSHAKE );
    219     tr_peerIoWrite( handshake->io, buf, HANDSHAKE_SIZE );
    220 }
    221 
    222 static void
    223 sendHandshake( tr_handshake * handshake )
    224 {
    225     if( ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_PREFERRED ) ||
    226         ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_REQUIRED ) )
    227     {
    228         sendPublicKey( handshake );
    229     }
    230     else
    231     {
    232         sendPlaintextHandshake( handshake );
    233     }
    234 }
    235 
    236 static void
    237 sendLtepHandshake( tr_handshake * handshake )
    238 {
    239     benc_val_t val, *m;
    240     char * buf;
    241     int len;
    242     const char * v = TR_NAME " " USERAGENT_PREFIX;
    243     const int port = tr_getPublicPort( handshake->handle );
    244     struct evbuffer * outbuf = evbuffer_new( );
    245     uint32_t msglen;
    246     const uint8_t tr_msgid = 20; /* ltep extension id */
    247     const uint8_t ltep_msgid = 0; /* handshake id */
    248 
    249     tr_bencInit( &val, TYPE_DICT );
    250     tr_bencDictReserve( &val, 3 );
    251     m  = tr_bencDictAdd( &val, "m" );
    252     tr_bencInit( m, TYPE_DICT );
    253     tr_bencDictReserve( m, 1 );
    254     tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), 1 );
    255     if( port > 0 )
    256         tr_bencInitInt( tr_bencDictAdd( &val, "p" ), port );
    257     tr_bencInitStr( tr_bencDictAdd( &val, "v" ), v, 0, 1 );
    258 
    259     fprintf( stderr, "handshake %p: sending ltep handshake...\n", handshake );
    260     buf = tr_bencSaveMalloc( &val,  &len );
    261     tr_bencPrint( &val );
    262 
    263     msglen = sizeof(tr_msgid) + sizeof(ltep_msgid) + len;
    264     tr_peerIoWriteUint32( handshake->io, outbuf, msglen );
    265     tr_peerIoWriteBytes ( handshake->io, outbuf, &tr_msgid, 1 );
    266     tr_peerIoWriteBytes ( handshake->io, outbuf, &ltep_msgid, 1 );
    267     tr_peerIoWriteBytes ( handshake->io, outbuf, buf, len );
    268    
    269     tr_peerIoWriteBuf( handshake->io, outbuf );
    270     fireDoneCB( handshake, TRUE );
    271  
    272     /* cleanup */
    273     tr_bencFree( &val );
    274     tr_free( buf );
    275     evbuffer_free( outbuf );
    276 }
    277 
    278 
    279 /**
    280 ***
    281 **/
    282 
    283 static int
    284 readYa( tr_handshake * handshake, struct evbuffer  * inbuf )
    285 {
    286     uint8_t ya[KEY_LEN];
    287     uint8_t *walk, outbuf[KEY_LEN + 512];
    288     const uint8_t *myKey, *secret;
    289     int len;
    290 
    291     if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )
    292         return READ_MORE;
    293 
    294     /* read the incoming peer's public key */
    295     evbuffer_remove( inbuf, ya, KEY_LEN );
    296     secret = tr_cryptoComputeSecret( handshake->crypto, ya );
    297     memcpy( handshake->mySecret, secret, KEY_LEN );
    298     tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
    299 
    300     /* send our public key to the peer */
    301     walk = outbuf;
    302     myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
    303     memcpy( walk, myKey, len );
    304     len = tr_rand( 512 );
    305     while( len-- )
    306         *walk++ = tr_rand( UCHAR_MAX );
    307 
    308     setReadState( handshake, AWAITING_PAD_A );
    309     tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );
    310 
    311     return READ_DONE;
    312 }
    313 
    314 static int
    315 readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
    316 {
    317     uint8_t * pch;
    318 
    319     /**
    320     *** Resynchronizing on HASH('req1',S)
    321     **/
    322 
    323     pch = memchr( EVBUFFER_DATA(inbuf),
    324                   handshake->myReq1[0],
    325                   EVBUFFER_LENGTH(inbuf) );
    326     if( pch == NULL ) {
    327         evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );
    328         return READ_MORE;
    329     }
    330     evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );
    331     if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )
    332         return READ_MORE;
    333     if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {
    334         evbuffer_drain( inbuf, 1 );
    335         return READ_AGAIN;
    336     }
    337 
    338     setState( handshake, AWAITING_CRYPTO_PROVIDE );
    339     return READ_AGAIN;
    340 }
    341 
    342 static int
    343 readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf )
    344 {
    345     /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */
    346 
    347     int i;
    348     uint8_t vc_in[VC_LENGTH];
    349     uint8_t req2[SHA_DIGEST_LENGTH];
    350     uint8_t req3[SHA_DIGEST_LENGTH];
    351     uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
    352     uint16_t padc_len = 0;
    353     uint32_t crypto_provide = 0;
    354     const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len);
    355     tr_torrent * tor = NULL;
    356 
    357     if( EVBUFFER_LENGTH(inbuf) < needlen )
    358         return READ_MORE;
    359 
    360     /* TODO: confirm they sent HASH('req1',S) here? */
    361     evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
    362 
    363     /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
    364      * we can get the first half of that (the obufscatedTorrentHash)
    365      * by building the latter and xor'ing it with what the peer sent us */
    366     fprintf( stderr, "reading obfuscated torrent hash...\n" );
    367     evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
    368     tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
    369     for( i=0; i<SHA_DIGEST_LENGTH; ++i )
    370         obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
    371     tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash );
    372     assert( tor != NULL );
    373     fprintf( stderr, "found the torrent; it's [%s]\n", tor->info.name );
    374     tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
    375 
    376     /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
    377 
    378     tr_cryptoDecryptInit( handshake->crypto );
    379 
    380     tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
    381 
    382     tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
    383     fprintf( stderr, "crypto_provide is %d\n", (int)crypto_provide );
    384 
    385     tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
    386     fprintf( stderr, "padc is %d\n", (int)padc_len );
    387     handshake->pad_c_len = padc_len;
    388     setState( handshake, AWAITING_PAD_C );
    389     return READ_AGAIN;
    390 }
    391 
    392 static int
    393 readPadC( tr_handshake * handshake, struct evbuffer * inbuf )
    394 {
    395     uint16_t ia_len;
    396     const size_t needlen = handshake->pad_c_len + sizeof(uint16_t);
    397 
    398     if( EVBUFFER_LENGTH(inbuf) < needlen )
    399         return READ_MORE;
    400 
    401     evbuffer_drain( inbuf, needlen );
    402 
    403     tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
    404     fprintf( stderr, "ia_len is %d\n", (int)ia_len );
    405     handshake->ia_len = ia_len;
    406     setState( handshake, AWAITING_IA );
    407     return READ_AGAIN;
    408 }
    409 
    410 static int
    411 readIA( tr_handshake * handshake, struct evbuffer * inbuf )
    412 {
    413     const size_t needlen = handshake->ia_len;
    414     uint8_t * ia;
    415 
    416     if( EVBUFFER_LENGTH(inbuf) < needlen )
    417         return READ_MORE;
    418 
    419     ia = tr_new( uint8_t, handshake->ia_len );
    420     tr_peerIoReadBytes( handshake->io, inbuf, ia, handshake->ia_len );
    421     fprintf( stderr, "got their payload ia: [%*.*s]\n", (int)needlen, (int)needlen, ia );
    422 
    423     handshake->state = -1;
    424     assert( 0 && "asdf" );
    425 }
    426 
    427 /**
    428 ***
    429 **/
    430282
    431283static int
     
    440292    if( EVBUFFER_LENGTH(inbuf) < needlen )
    441293        return READ_MORE;
    442 fprintf( stderr, "%*.*s\n", HANDSHAKE_NAME_LEN, HANDSHAKE_NAME_LEN, EVBUFFER_DATA(inbuf) );
    443294
    444295    isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
     
    449300    }
    450301
    451     fprintf( stderr, "got a %s handshake\n", (isEncrypted ? "encrypted" : "plaintext") );
     302    dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") );
     303
    452304    handshake->peerSupportsEncryption = isEncrypted;
    453     tr_peerIoSetEncryption( handshake->io, isEncrypted
    454         ? PEER_ENCRYPTION_RC4
    455         : PEER_ENCRYPTION_PLAINTEXT );
     305    tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
     306                                                       : PEER_ENCRYPTION_NONE );
    456307    if( !isEncrypted ) {
    457308        setState( handshake, AWAITING_HANDSHAKE );
     
    503354        /* crypto_provide */
    504355        crypto_provide = 0;
    505         if( handshake->encryptionPreference != HANDSHAKE_PLAINTEXT_REQUIRED )
    506             crypto_provide |= (1<<0);
    507         if( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED )
     356        crypto_provide |= (1<<0); /* encryption */
     357        if( !handshake->shunUnencryptedPeers ) /* plaintext */
    508358            crypto_provide |= (1<<1);
    509359        assert( 1<=crypto_provide && crypto_provide<=3 );
     
    528378    {
    529379        uint16_t i;
    530         uint8_t msg[HANDSHAKE_SIZE];
    531         buildHandshakeMessage( handshake, msg );
    532 
    533         i = htons( HANDSHAKE_SIZE );
     380        int msgSize;
     381        uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize );
     382
     383        i = htons( msgSize );
    534384        tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i );
    535385        evbuffer_add( outbuf, &i, sizeof(uint16_t) );
    536386
    537         tr_cryptoEncrypt( handshake->crypto, HANDSHAKE_SIZE, msg, msg );
     387        tr_cryptoEncrypt( handshake->crypto, msgSize, msg, msg );
    538388        evbuffer_add( outbuf, msg, HANDSHAKE_SIZE );
     389        handshake->haveSentBitTorrentHandshake = 1;
     390
     391        tr_free( msg );
    539392    }
    540393
     
    562415    {
    563416        if( EVBUFFER_LENGTH(inbuf) < VC_LENGTH ) {
    564             fprintf( stderr, "not enough bytes... returning read_more\n" );
     417            dbgmsg( handshake, "not enough bytes... returning read_more" );
    565418            return READ_MORE;
    566419        }
     
    575428    }
    576429
    577     fprintf( stderr, "got it!\n" );
     430    dbgmsg( handshake, "got it!" );
    578431    evbuffer_drain( inbuf, key_len );
    579432    setState( handshake, AWAITING_CRYPTO_SELECT );
     
    594447    assert( crypto_select==1 || crypto_select==2 );
    595448    handshake->crypto_select = crypto_select;
    596     fprintf( stderr, "crypto select is %d\n", crypto_select );
     449    dbgmsg( handshake, "crypto select is %d", (int)crypto_select );
    597450
    598451    tr_peerIoReadUint16( handshake->io, inbuf, &pad_d_len );
    599     fprintf( stderr, "pad_d_len is %d\n", (int)pad_d_len );
     452    dbgmsg( handshake, "pad_d_len is %d", (int)pad_d_len );
    600453    assert( pad_d_len <= 512 );
    601454    handshake->pad_d_len = pad_d_len;
     
    611464    uint8_t * tmp;
    612465
    613 fprintf( stderr, "pad d: need %d, got %d\n", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );
     466    dbgmsg( handshake, "pad d: need %d, got %d", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );
    614467    if( EVBUFFER_LENGTH(inbuf) < needlen )
    615468        return READ_MORE;
     
    626479}
    627480
     481/***
     482****
     483****  INCOMING CONNECTIONS
     484****
     485***/
     486
    628487static void
    629 gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg );
    630 
    631 /*ccc*/
     488tr_handshakeDone( tr_handshake * handshake, int isConnected );
     489
    632490static int
    633491readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
    634492{
    635493    int i;
    636     int ltep = 0;
    637     int azmp = 0;
    638     int isEncrypted;
     494    uint8_t ltep = 0;
     495    uint8_t azmp = 0;
    639496    uint8_t pstrlen;
    640497    uint8_t * pstr;
    641498    uint8_t reserved[8];
    642499    uint8_t hash[SHA_DIGEST_LENGTH];
    643     int bytesRead = 0;
    644 
    645 fprintf( stderr, "handshake payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
     500
     501    dbgmsg( handshake, "payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
    646502
    647503    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
    648504        return READ_MORE;
    649505
    650     /* pstrlen */
    651     pstrlen = EVBUFFER_DATA(inbuf)[0];
    652     fprintf( stderr, "pstrlen 1 is %d [%c]\n", (int)pstrlen, pstrlen );
    653     fprintf( stderr, "the buf is [%c][%c][%c][%c]",
    654         EVBUFFER_DATA(inbuf)[0],
    655         EVBUFFER_DATA(inbuf)[1],
    656         EVBUFFER_DATA(inbuf)[2],
    657         EVBUFFER_DATA(inbuf)[3] );
    658     isEncrypted = pstrlen != 19;
    659     handshake->peerSupportsEncryption = isEncrypted;
    660     tr_peerIoSetEncryption( handshake->io, isEncrypted
    661         ? PEER_ENCRYPTION_RC4
    662         : PEER_ENCRYPTION_PLAINTEXT );
    663     if( isEncrypted ) {
    664         fprintf( stderr, "I guess it's encrypted...\n" );
    665         if( tr_peerIoIsIncoming( handshake->io ) ) {
     506for( i=0; i<(int)EVBUFFER_LENGTH(inbuf); ++i )
     507fprintf( stderr, "[%c]", EVBUFFER_DATA(inbuf)[i] );
     508fprintf( stderr, "\n" );
     509
     510    pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read.  We may be
     511                                          handing inbuf to AWAITING_YA */
     512
     513    if( pstrlen == 19 ) /* unencrypted */
     514    {
     515        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
     516    }
     517    else /* encrypted or corrupt */
     518    {
     519        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );
     520
     521        if( tr_peerIoIsIncoming( handshake->io ) )
     522        {
     523            dbgmsg( handshake, "I think peer is sending us an encrypted handshake..." );
    666524            setState( handshake, AWAITING_YA );
    667525            return READ_AGAIN;
    668526        }
    669527        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
    670     }
    671     bytesRead++;
     528
     529        if( pstrlen != 19 )
     530        {
     531            dbgmsg( handshake, "I think peer has sent us a corrupt handshake..." );
     532            tr_handshakeDone( handshake, FALSE );
     533            return READ_DONE;
     534        }
     535    }
     536
    672537    evbuffer_drain( inbuf, 1 );
    673     fprintf( stderr, "pstrlen is %d [%c]\n", (int)pstrlen, pstrlen );
    674     assert( pstrlen == 19 );
    675538
    676539    /* pstr (BitTorrent) */
     
    678541    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
    679542    pstr[pstrlen] = '\0';
    680     fprintf( stderr, "pstrlen is [%s]\n", pstr );
    681     bytesRead += pstrlen;
    682     fprintf( stderr, "%*.*s", pstrlen, pstrlen, (char*)pstr );
    683543    if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) {
    684544        tr_free( pstr );
    685         gotError( NULL, 0, handshake );
     545        tr_handshakeDone( handshake, FALSE );
    686546        return READ_DONE;
    687547    }
     
    690550    /* reserved bytes */
    691551    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) );
    692     bytesRead += sizeof(reserved);
    693552
    694553    /* torrent hash */
    695554    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) );
    696     bytesRead += sizeof(hash);
    697555    if( tr_peerIoIsIncoming( handshake->io ) )
    698556    {
    699         assert( !tr_peerIoHasTorrentHash( handshake->io ) );
    700         tr_peerIoSetTorrentHash( handshake->io, hash );
    701     }
    702     else
    703     {
     557        if( !tr_torrentExists( handshake->handle, hash ) )
     558        {
     559            dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." );
     560            tr_handshakeDone( handshake, FALSE );
     561            return READ_DONE;
     562        }
     563        else
     564        {
     565            assert( !tr_peerIoHasTorrentHash( handshake->io ) );
     566            tr_peerIoSetTorrentHash( handshake->io, hash );
     567        }
     568    }
     569    else /* outgoing */
     570    {
     571        assert( tr_torrentExists( handshake->handle, hash ) );
    704572        assert( tr_peerIoHasTorrentHash( handshake->io ) );
    705         assert( !memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) );
     573        if( memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) )
     574        {
     575            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
     576            tr_handshakeDone( handshake, FALSE );
     577            return READ_DONE;
     578        }
    706579    }
    707580
     
    709582    tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
    710583    tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
    711     bytesRead += sizeof(handshake->peer_id);
    712584    handshake->havePeerID = TRUE;
    713585
    714     assert( bytesRead == HANDSHAKE_SIZE );
    715 
    716586    /**
    717     ***
     587    *** Extension negotiation
    718588    **/
    719589
    720     ltep = HANDSHAKE_HAS_EXTMSGS( reserved ) ? 1 : 0;
    721     azmp = HANDSHAKE_HAS_AZPROTO( reserved ) ? 1 : 0;
     590    ltep = HANDSHAKE_HAS_EXTMSGS( reserved );
     591    azmp = HANDSHAKE_HAS_AZPROTO( reserved );
    722592    if( ltep && azmp ) {
    723593        switch( HANDSHAKE_GET_EXTPREF( reserved ) ) {
     
    733603    }
    734604    assert( !ltep || !azmp );
    735          if( ltep ) { i = LT_EXTENSIONS_LTEP; fprintf(stderr,"using ltep\n" ); }
    736     else if( azmp ) { i = LT_EXTENSIONS_AZMP; fprintf(stderr,"using azmp\n" ); }
    737     else            { i = LT_EXTENSIONS_NONE; fprintf(stderr,"using no extensions\n" ); }
     605         if( ltep ) { i = LT_EXTENSIONS_LTEP; dbgmsg(handshake,"using ltep" ); }
     606    else if( azmp ) { i = LT_EXTENSIONS_AZMP; dbgmsg(handshake,"using azmp" ); }
     607    else            { i = LT_EXTENSIONS_NONE; dbgmsg(handshake,"using no extensions" ); }
    738608    tr_peerIoSetExtension( handshake->io, i );
    739609
    740610
    741     if( i == LT_EXTENSIONS_LTEP )
    742     {
    743         sendLtepHandshake( handshake );
    744         return READ_DONE;
    745     }
    746     else if( !tr_peerIoIsIncoming( handshake->io ) && ( i != LT_EXTENSIONS_AZMP ) )
    747     {
    748         fireDoneCB( handshake, TRUE );
    749         return READ_DONE;
    750     }
    751 
    752 
    753     fprintf( stderr, " UNHANDLED -- azmp " );
    754     return 0;
    755 }
    756 
    757 /**
    758 ***
    759 **/
     611    /**
     612    ***  If this is an incoming message, then we need to send a response handshake
     613    **/
     614
     615    if( !handshake->haveSentBitTorrentHandshake )
     616    {
     617        const int ext = ltep ? HANDSHAKE_EXTPREF_LTEP_FORCE
     618                             : HANDSHAKE_EXTPREF_AZMP_FORCE;
     619        int msgSize;
     620        uint8_t * msg = buildHandshakeMessage( handshake, ext, &msgSize );
     621        tr_peerIoWrite( handshake->io, msg, msgSize );
     622        tr_free( msg );
     623        handshake->haveSentBitTorrentHandshake = 1;
     624    }
     625
     626    /* we've completed the BT handshake... pass the work on to peer-msgs */
     627    tr_handshakeDone( handshake, TRUE );
     628    return READ_DONE;
     629}
     630
     631static int
     632readYa( tr_handshake * handshake, struct evbuffer  * inbuf )
     633{
     634    uint8_t ya[KEY_LEN];
     635    uint8_t *walk, outbuf[KEY_LEN + PadB_MAXLEN];
     636    const uint8_t *myKey, *secret;
     637    int len;
     638
     639    if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )
     640        return READ_MORE;
     641
     642    /* read the incoming peer's public key */
     643    evbuffer_remove( inbuf, ya, KEY_LEN );
     644    secret = tr_cryptoComputeSecret( handshake->crypto, ya );
     645    memcpy( handshake->mySecret, secret, KEY_LEN );
     646    tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
     647
     648    /* send our public key to the peer */
     649    walk = outbuf;
     650    myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
     651    memcpy( walk, myKey, len );
     652    len = tr_rand( PadB_MAXLEN );
     653    while( len-- )
     654        *walk++ = tr_rand( UCHAR_MAX );
     655
     656    setReadState( handshake, AWAITING_PAD_A );
     657    tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );
     658
     659    return READ_DONE;
     660}
     661
     662static int
     663readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
     664{
     665    uint8_t * pch;
     666
     667    /**
     668    *** Resynchronizing on HASH('req1',S)
     669    **/
     670
     671    pch = memchr( EVBUFFER_DATA(inbuf),
     672                  handshake->myReq1[0],
     673                  EVBUFFER_LENGTH(inbuf) );
     674    if( pch == NULL ) {
     675        evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );
     676        return READ_MORE;
     677    }
     678    evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );
     679    if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )
     680        return READ_MORE;
     681    if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {
     682        evbuffer_drain( inbuf, 1 );
     683        return READ_AGAIN;
     684    }
     685
     686    setState( handshake, AWAITING_CRYPTO_PROVIDE );
     687    return READ_AGAIN;
     688}
     689
     690static int
     691readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf )
     692{
     693    /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */
     694
     695    int i;
     696    uint8_t vc_in[VC_LENGTH];
     697    uint8_t req2[SHA_DIGEST_LENGTH];
     698    uint8_t req3[SHA_DIGEST_LENGTH];
     699    uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
     700    uint16_t padc_len = 0;
     701    uint32_t crypto_provide = 0;
     702    const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len);
     703    tr_torrent * tor = NULL;
     704
     705    if( EVBUFFER_LENGTH(inbuf) < needlen )
     706        return READ_MORE;
     707
     708    /* TODO: confirm they sent HASH('req1',S) here? */
     709    evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
     710
     711    /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
     712     * we can get the first half of that (the obufscatedTorrentHash)
     713     * by building the latter and xor'ing it with what the peer sent us */
     714    dbgmsg( handshake, "reading obfuscated torrent hash...\n" );
     715    evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
     716    tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
     717    for( i=0; i<SHA_DIGEST_LENGTH; ++i )
     718        obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
     719    tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash );
     720    assert( tor != NULL );
     721    dbgmsg( handshake, "found the torrent; it's [%s]\n", tor->info.name );
     722    tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
     723
     724    /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
     725
     726    tr_cryptoDecryptInit( handshake->crypto );
     727
     728    tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
     729
     730    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
     731    dbgmsg( handshake, "crypto_provide is %d\n", (int)crypto_provide );
     732
     733    tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
     734    dbgmsg( handshake, "padc is %d\n", (int)padc_len );
     735    handshake->pad_c_len = padc_len;
     736    setState( handshake, AWAITING_PAD_C );
     737    return READ_AGAIN;
     738}
     739
     740static int
     741readPadC( tr_handshake * handshake, struct evbuffer * inbuf )
     742{
     743    uint16_t ia_len;
     744    const size_t needlen = handshake->pad_c_len + sizeof(uint16_t);
     745
     746    if( EVBUFFER_LENGTH(inbuf) < needlen )
     747        return READ_MORE;
     748
     749    evbuffer_drain( inbuf, needlen );
     750
     751    tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
     752    dbgmsg( handshake, "ia_len is %d", (int)ia_len );
     753    handshake->ia_len = ia_len;
     754    setState( handshake, AWAITING_IA );
     755    return READ_AGAIN;
     756}
     757
     758static int
     759readIA( tr_handshake * handshake, struct evbuffer * inbuf )
     760{
     761    const size_t needlen = handshake->ia_len;
     762
     763    if( EVBUFFER_LENGTH(inbuf) < needlen )
     764        return READ_MORE;
     765
     766    return readHandshake( handshake, inbuf );
     767}
     768
     769/***
     770****
     771****
     772****
     773***/
    760774
    761775static ReadState
     
    765779    struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
    766780    ReadState ret;
    767     fprintf( stderr, "handshake %p handling canRead; state is [%s]\n", handshake, getStateName(handshake->state) );
     781    dbgmsg( handshake, "handling canRead; state is [%s]\n", getStateName(handshake->state) );
    768782
    769783    switch( handshake->state )
     
    788802
    789803static void
    790 tr_handshakeFree( tr_handshake * handshake )
    791 {
    792     tr_free( handshake );
    793 }
    794 
    795 static void
    796 fireDoneCB( tr_handshake * handshake, int isConnected )
     804fireDoneFunc( tr_handshake * handshake, int isConnected )
    797805{
    798806    const uint8_t * peer_id = isConnected && handshake->havePeerID
     
    805813                          handshake->peerSupportsEncryption,
    806814                          handshake->doneUserData );
    807     tr_handshakeFree( handshake );
     815}
     816
     817void
     818tr_handshakeDone( tr_handshake * handshake, int isOK )
     819{
     820    dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" );
     821    tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
     822    fireDoneFunc( handshake, isOK );
     823    tr_free( handshake );
     824}
     825
     826void
     827tr_handshakeAbort( tr_handshake * handshake )
     828{
     829    tr_handshakeDone( handshake, FALSE );
    808830}
    809831
     
    817839     * try a plaintext handshake */
    818840    if(    ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) )
    819         && ( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED )
     841        && ( !handshake->shunUnencryptedPeers )
    820842        && ( !tr_peerIoReconnect( handshake->io ) ) )
    821843    {
    822 fprintf( stderr, "handshake %p trying again in plaintext...\n", handshake );
    823         handshake->encryptionPreference = HANDSHAKE_PLAINTEXT_REQUIRED;
    824         sendPlaintextHandshake( handshake );
     844        int msgSize;
     845        uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize );
     846        setReadState( handshake, AWAITING_HANDSHAKE );
     847        tr_peerIoWrite( handshake->io, msg, msgSize );
     848        tr_free( msg );
    825849    }
    826850    else
    827851    {
    828         tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
    829         fireDoneCB( handshake, FALSE );
     852        tr_handshakeDone( handshake, FALSE );
    830853    }
    831854}
     
    836859
    837860tr_handshake*
    838 tr_handshakeNew( tr_peerIo        * io,
    839                  int                encryptionPreference,
    840                  handshakeDoneCB    doneCB,
    841                  void             * doneUserData )
     861tr_handshakeNew( tr_peerIo           * io,
     862                 tr_encryption_mode    encryption_mode,
     863                 handshakeDoneCB       doneCB,
     864                 void                * doneUserData )
    842865{
    843866    tr_handshake * handshake;
    844867
    845 //w00t
     868// w00t
    846869//static int count = 0;
    847870//if( count++ ) return NULL;
     
    850873    handshake->io = io;
    851874    handshake->crypto = tr_peerIoGetCrypto( io );
    852     handshake->encryptionPreference = encryptionPreference;
     875    handshake->shunUnencryptedPeers = encryption_mode==TR_ENCRYPTION_REQUIRED;
    853876    handshake->doneCB = doneCB;
    854877    handshake->doneUserData = doneUserData;
     
    858881    tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake );
    859882
    860 fprintf( stderr, "handshake %p: new handshake for io %p\n", handshake, io );
     883dbgmsg( handshake, "new handshake for io %p", io );
    861884
    862885    if( tr_peerIoIsIncoming( io ) )
    863     {
    864886        setReadState( handshake, AWAITING_HANDSHAKE );
    865     }
    866887    else
    867     {
    868         sendHandshake( handshake );
    869     }
     888        sendYa( handshake );
    870889
    871890    return handshake;
    872891}
    873 
    874 void
    875 tr_handshakeAbort( tr_handshake * handshake )
    876 {
    877     tr_peerIoFree( handshake->io );
    878     tr_handshakeFree( handshake );
    879 }
  • branches/encryption/libtransmission/handshake.h

    r3076 r3101  
    1414#define TR_HANDSHAKE_H
    1515
    16 enum EncryptionPreference
    17 {
    18     HANDSHAKE_ENCRYPTION_PREFERRED,
    19     HANDSHAKE_ENCRYPTION_REQUIRED,
    20     HANDSHAKE_PLAINTEXT_PREFERRED,
    21     HANDSHAKE_PLAINTEXT_REQUIRED
    22 };
     16#include "transmission.h"
    2317
    2418struct tr_peerIo;
     
    3226                                void                * userData );
    3327
    34 tr_handshake *  tr_handshakeNew( struct tr_peerIo * io,
    35                                  int                encryptionPreference,
    36                                  handshakeDoneCB    doneCB,
    37                                  void             * doneUserData );
     28tr_handshake *  tr_handshakeNew( struct tr_peerIo   * io,
     29                                 tr_encryption_mode   encryptionMode,
     30                                 handshakeDoneCB      doneCB,
     31                                 void               * doneUserData );
    3832
    39 void tr_handshakeAbort( tr_handshake * );
     33void tr_handshakeAbort( tr_handshake  * handshake );
    4034
    4135#endif
  • branches/encryption/libtransmission/internal.h

    r3090 r3101  
    6363void tr_torrentChangeMyPort  ( tr_torrent *, int port );
    6464
     65int tr_torrentExists( tr_handle *, const uint8_t * );
    6566tr_torrent* tr_torrentFindFromHash( tr_handle *, const uint8_t * );
    6667tr_torrent* tr_torrentFindFromObfuscatedHash( tr_handle *, const uint8_t* );
     
    168169struct tr_handle
    169170{
     171    tr_encryption_mode         encryptionMode;
     172
    170173    struct tr_event_handle   * events;
    171174
  • branches/encryption/libtransmission/peer-io.c

    r3089 r3101  
    200200}
    201201
     202const char*
     203tr_peerIoGetAddrStr( const tr_peerIo * io )
     204{
     205    static char buf[512];
     206    assert( io != NULL );
     207    snprintf( buf, sizeof(buf), "%s:%u", inet_ntoa( io->in_addr ), (unsigned int)io->port );
     208    return buf;
     209}
     210
    202211void
    203212tr_peerIoSetIOFuncs( tr_peerIo          * io,
     
    377386{
    378387    assert( io != NULL );
    379     assert( encryptionMode==PEER_ENCRYPTION_PLAINTEXT || encryptionMode==PEER_ENCRYPTION_RC4 );
     388    assert( encryptionMode==PEER_ENCRYPTION_NONE || encryptionMode==PEER_ENCRYPTION_RC4 );
    380389
    381390    io->encryptionMode = encryptionMode;
     
    398407    switch( io->encryptionMode )
    399408    {
    400         case PEER_ENCRYPTION_PLAINTEXT:
     409        case PEER_ENCRYPTION_NONE:
    401410            /*fprintf( stderr, "writing %d plaintext bytes to outbuf...\n", byteCount );*/
    402411            evbuffer_add( outbuf, bytes, byteCount );
     
    444453    switch( io->encryptionMode )
    445454    {
    446         case PEER_ENCRYPTION_PLAINTEXT:
     455        case PEER_ENCRYPTION_NONE:
    447456            /*fprintf( stderr, "reading %d plaintext bytes from inbuf...\n", byteCount );*/
    448457            evbuffer_remove(  inbuf, bytes, byteCount );
  • branches/encryption/libtransmission/peer-io.h

    r3089 r3101  
    6464***
    6565**/
     66
     67const char*
     68      tr_peerIoGetAddrStr( const tr_peerIo * io );
    6669
    6770const struct in_addr*
     
    132135{
    133136    /* these match the values in MSE's crypto_select */
    134     PEER_ENCRYPTION_PLAINTEXT = (1<<0),
    135     PEER_ENCRYPTION_RC4       = (1<<1)
     137    PEER_ENCRYPTION_NONE = (1<<0),
     138    PEER_ENCRYPTION_RC4   = (1<<1)
    136139}
    137140EncryptionMode;
  • branches/encryption/libtransmission/peer-mgr.c

    r3098 r3101  
    225225tr_peerMgrFree( tr_peerMgr * manager )
    226226{
    227     int i, n;
    228227fprintf( stderr, "timer peerMgrFree\n" );
     228
     229    while( !tr_ptrArrayEmpty( manager->handshakes ) )
     230        tr_handshakeAbort( (tr_handshake*)tr_ptrArrayNth( manager->handshakes, 0) );
     231    tr_ptrArrayFree( manager->handshakes );
    229232
    230233    while( !tr_ptrArrayEmpty( manager->torrents ) )
    231234        freeTorrent( manager, (Torrent*)tr_ptrArrayNth( manager->torrents, 0) );
    232235    tr_ptrArrayFree( manager->torrents );
    233 
    234     for( i=0, n=tr_ptrArraySize(manager->handshakes); i<n; ++i )
    235         tr_handshakeAbort( (tr_handshake*) tr_ptrArrayNth( manager->handshakes, i) );
    236     tr_ptrArrayFree( manager->handshakes );
    237236
    238237    tr_free( manager );
     
    605604{
    606605    tr_handshake * handshake = tr_handshakeNew( io,
    607                                                 HANDSHAKE_ENCRYPTION_PREFERRED,
     606                                                manager->handle->encryptionMode,
    608607                                                myHandshakeDoneCB,
    609608                                                manager );
  • branches/encryption/libtransmission/peer-msgs.c

    r3095 r3101  
    4141#define PEX_INTERVAL (60 * 1000)
    4242
    43 #define PEER_PULSE_INTERVAL (50)
     43#define PEER_PULSE_INTERVAL (100)
    4444
    4545enum
     
    5757    BT_LTEP            = 20,
    5858
    59     LTEP_HANDSHAKE     = 0
     59    LTEP_HANDSHAKE     = 0,
     60
     61    OUR_LTEP_PEX       = 1
    6062};
    6163
     
    111113    time_t clientSentPexAt;
    112114
    113     unsigned int notListening    : 1;
    114     unsigned int peerSupportsPex : 1;
     115    unsigned int notListening          : 1;
     116    unsigned int peerSupportsPex       : 1;
     117    unsigned int hasSentLtepHandshake  : 1;
    115118
    116119    uint8_t state;
     
    125128    tr_pex * pex;
    126129};
     130
     131/**
     132***
     133**/
     134
     135static void
     136myDebug( const char * file, int line, const struct tr_peermsgs * msgs, const char * fmt, ... )
     137{
     138    va_list args;
     139    const char * addr = tr_peerIoGetAddrStr( msgs->io );
     140    struct evbuffer * buf = evbuffer_new( );
     141    evbuffer_add_printf( buf, "[%s:%d] %s (%p) ", file, line, addr, msgs );
     142    va_start( args, fmt );
     143    evbuffer_add_vprintf( buf, fmt, args );
     144    va_end( args );
     145
     146    fprintf( stderr, "%s\n", EVBUFFER_DATA(buf) );
     147
     148    evbuffer_free( buf );
     149}
     150
     151#define dbgmsg(handshake, fmt...) myDebug(__FILE__, __LINE__, handshake, ##fmt )
    127152
    128153/**
     
    231256    const uint32_t len = sizeof(uint8_t);
    232257    const uint8_t bt_msgid = weAreInterested ? BT_INTERESTED : BT_NOT_INTERESTED;
    233 const time_t now = time( NULL );
    234258
    235259    assert( msgs != NULL );
     
    237261
    238262    msgs->info->clientIsInterested = weAreInterested;
    239     fprintf( stderr, "peer %p: sending an %s message at %s\n", msgs, (weAreInterested ? "INTERESTED" : "NOT_INTERESTED"), ctime(&now) );
     263    dbgmsg( msgs, ": sending an %s message", (weAreInterested ? "INTERESTED" : "NOT_INTERESTED") );
    240264    tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len );
    241265    tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 );
     
    258282    assert( msgs->info != NULL );
    259283    assert( choke==0 || choke==1 );
    260 const time_t now = time( NULL );
    261284
    262285    if( msgs->info->peerIsChoked != choke )
     
    272295        }
    273296
    274         fprintf( stderr, "peer %p: sending a %s message at %s\n", msgs, (choke ? "CHOKE" : "UNCHOKE"), ctime(&now) );
     297        dbgmsg( msgs, "sending a %s message", (choke ? "CHOKE" : "UNCHOKE") );
    275298        tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len );
    276299        tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 );
     
    325348    const uint8_t bt_msgid = BT_HAVE;
    326349    const uint32_t len = sizeof(uint8_t) + sizeof(uint32_t);
    327     fprintf( stderr, "peer %p: w00t telling them we HAVE piece #%d\n", msgs, pieceIndex );
     350    dbgmsg( msgs, "w00t telling them we HAVE piece #%d", pieceIndex );
    328351    tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len );
    329352    tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 );
     
    368391        return TR_ADDREQ_FULL;
    369392
    370     fprintf( stderr, "w00t peer %p has a max request queue size of %d... adding request for piece %d, offset %d\n", msgs, maxSize, (int)index, (int)offset );
     393    dbgmsg( msgs, "w00t peer has a max request queue size of %d... adding request for piece %d, offset %d", maxSize, (int)index, (int)offset );
    371394
    372395    /* queue the request */
     
    394417
    395418static void
    396 parseLtepHandshake( tr_peermsgs * peer, int len, struct evbuffer * inbuf )
     419sendLtepHandshake( tr_peermsgs * msgs )
     420{
     421    benc_val_t val, *m;
     422    char * buf;
     423    int len;
     424    const char * v = TR_NAME " " USERAGENT_PREFIX;
     425    const int port = tr_getPublicPort( msgs->handle );
     426    struct evbuffer * outbuf = evbuffer_new( );
     427    uint32_t msglen;
     428    const uint8_t tr_msgid = 20; /* ltep extension id */
     429    const uint8_t ltep_msgid = 0; /* handshake id */
     430
     431    dbgmsg( msgs, "sending an ltep handshake" );
     432    tr_bencInit( &val, TYPE_DICT );
     433    tr_bencDictReserve( &val, 3 );
     434    m  = tr_bencDictAdd( &val, "m" );
     435    tr_bencInit( m, TYPE_DICT );
     436    tr_bencDictReserve( m, 1 );
     437    tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), OUR_LTEP_PEX );
     438    if( port > 0 )
     439        tr_bencInitInt( tr_bencDictAdd( &val, "p" ), port );
     440    tr_bencInitStr( tr_bencDictAdd( &val, "v" ), v, 0, 1 );
     441    buf = tr_bencSaveMalloc( &val,  &len );
     442    tr_bencPrint( &val );
     443
     444    msglen = sizeof(tr_msgid) + sizeof(ltep_msgid) + len;
     445    tr_peerIoWriteUint32( msgs->io, outbuf, msglen );
     446    tr_peerIoWriteBytes ( msgs->io, outbuf, &tr_msgid, 1 );
     447    tr_peerIoWriteBytes ( msgs->io, outbuf, &ltep_msgid, 1 );
     448    tr_peerIoWriteBytes ( msgs->io, outbuf, buf, len );
     449
     450    tr_peerIoWriteBuf( msgs->io, outbuf );
     451
     452    msgs->hasSentLtepHandshake = 1;
     453
     454    /* cleanup */
     455    tr_bencFree( &val );
     456    tr_free( buf );
     457    evbuffer_free( outbuf );
     458
     459}
     460
     461static void
     462parseLtepHandshake( tr_peermsgs * msgs, int len, struct evbuffer * inbuf )
    397463{
    398464    benc_val_t val, * sub;
     
    401467
    402468    if( tr_bencLoad( tmp, len, &val, NULL ) || val.type!=TYPE_DICT ) {
    403         fprintf( stderr, "GET  extended-handshake, couldn't get dictionary\n" );
     469        dbgmsg( msgs, "GET  extended-handshake, couldn't get dictionary" );
    404470        tr_free( tmp );
    405471        return;
     
    413479        sub = tr_bencDictFind( sub, "ut_pex" );
    414480        if( tr_bencIsInt( sub ) ) {
    415             peer->peerSupportsPex = 1;
    416             peer->ut_pex_id = (uint8_t) sub->val.i;
    417             fprintf( stderr, "peer->ut_pex is %d\n", (int)peer->ut_pex_id );
     481            msgs->peerSupportsPex = 1;
     482            msgs->ut_pex_id = (uint8_t) sub->val.i;
     483            dbgmsg( msgs, "msgs->ut_pex is %d", (int)msgs->ut_pex_id );
    418484        }
    419485    }
     
    424490    if( tr_bencIsStr( sub ) ) {
    425491int i;
    426         tr_free( peer->info->client );
     492        tr_free( msgs->info->client );
    427493        fprintf( stderr, "dictionary says client is [%s]\n", sub->val.s.s );
    428         peer->info->client = tr_strndup( sub->val.s.s, sub->val.s.i );
     494        msgs->info->client = tr_strndup( sub->val.s.s, sub->val.s.i );
    429495for( i=0; i<sub->val.s.i; ++i ) { fprintf( stderr, "[%c] (%d)\n", sub->val.s.s[i], (int)sub->val.s.s[i] );
    430                                   if( (int)peer->info->client[i]==-75 ) peer->info->client[i]='u'; }
    431         fprintf( stderr, "peer->client is now [%s]\n", peer->info->client );
     496                                  if( (int)msgs->info->client[i]==-75 ) msgs->info->client[i]='u'; }
     497        fprintf( stderr, "msgs->client is now [%s]\n", msgs->info->client );
    432498    }
    433499#endif
     
    436502    sub = tr_bencDictFind( &val, "p" );
    437503    if( tr_bencIsInt( sub ) ) {
    438         peer->listeningPort = htons( (uint16_t)sub->val.i );
    439         fprintf( stderr, "peer->port is now %hu\n", peer->listeningPort );
     504        msgs->listeningPort = htons( (uint16_t)sub->val.i );
     505        dbgmsg( msgs, "msgs->port is now %hu", msgs->listeningPort );
    440506    }
    441507
     
    457523
    458524    if( tr_bencLoad( tmp, msglen, &val, NULL ) || !tr_bencIsDict( &val ) ) {
    459         fprintf( stderr, "GET can't read extended-pex dictionary\n" );
     525        dbgmsg( msgs, "GET can't read extended-pex dictionary" );
    460526        tr_free( tmp );
    461527        return;
     
    465531    if( tr_bencIsStr(sub) && ((sub->val.s.i % 6) == 0)) {
    466532        const int n = sub->val.s.i / 6 ;
    467         fprintf( stderr, "got %d peers from uT pex\n", n );
     533        dbgmsg( msgs, "got %d peers from uT pex", n );
    468534        tr_peerMgrAddPeers( msgs->handle->peerMgr,
    469535                            msgs->torrent->info.hash,
     
    489555    if( ltep_msgid == LTEP_HANDSHAKE )
    490556    {
    491         fprintf( stderr, "got ltep handshake\n" );
     557        dbgmsg( msgs, "got ltep handshake" );
    492558        parseLtepHandshake( msgs, msglen, inbuf );
     559        if( !msgs->hasSentLtepHandshake )
     560            sendLtepHandshake( msgs );
    493561    }
    494562    else if( ltep_msgid == msgs->ut_pex_id )
    495563    {
    496         fprintf( stderr, "got ut pex\n" );
     564        dbgmsg( msgs, "got ut pex" );
    497565        msgs->peerSupportsPex = 1;
    498566        parseUtPex( msgs, msglen, inbuf );
     
    500568    else
    501569    {
    502         fprintf( stderr, "skipping unknown ltep message (%d)\n", (int)ltep_msgid );
     570        dbgmsg( msgs, "skipping unknown ltep message (%d)", (int)ltep_msgid );
    503571        evbuffer_drain( inbuf, msglen );
    504572    }
     
    517585
    518586    if( len == 0 ) { /* peer sent us a keepalive message */
    519         fprintf( stderr, "peer %p sent us a keepalive message...\n", msgs );
     587        dbgmsg( msgs, "peer sent us a keepalive message..." );
    520588        msgs->gotKeepAliveTime = time( NULL );
    521589    } else {
    522         fprintf( stderr, "peer %p is sending us a message with %"PRIu64" bytes...\n", msgs, (uint64_t)len );
     590        dbgmsg( msgs, "peer is sending us a message with %"PRIu64" bytes...\n", (uint64_t)len );
    523591        msgs->incomingMessageLength = len;
    524592        msgs->state = AWAITING_BT_MESSAGE;
     
    532600    uint32_t ui32;
    533601    uint32_t msglen = msgs->incomingMessageLength;
    534 const time_t now = time( NULL );
    535602
    536603    if( EVBUFFER_LENGTH(inbuf) < msglen )
     
    539606    tr_peerIoReadBytes( msgs->io, inbuf, &id, 1 );
    540607    msglen--;
    541     fprintf( stderr, "peer %p sent us a message... "
    542                      "bt id number is %d, and remaining len is %d\n", msgs, (int)id, (int)msglen );
     608    dbgmsg( msgs, "peer sent us a message... "
     609                  "bt id number is %d, and remaining len is %d", (int)id, (int)msglen );
    543610
    544611    switch( id )
     
    546613        case BT_CHOKE:
    547614            assert( msglen == 0 );
    548             fprintf( stderr, "w00t peer-msgs %p sent us a BT_CHOKE at %s\n", msgs, ctime(&now) );
     615            dbgmsg( msgs, "w00t peer sent us a BT_CHOKE" );
    549616            msgs->info->clientIsChoked = 1;
    550617            tr_list_foreach( msgs->peerAskedFor, tr_free );
     
    556623        case BT_UNCHOKE:
    557624            assert( msglen == 0 );
    558             fprintf( stderr, "w00t peer-msgs %p sent us a BT_UNCHOKE at %s\n", msgs, ctime(&now) );
     625            dbgmsg( msgs, "w00t peer sent us a BT_UNCHOKE" );
    559626            msgs->info->clientIsChoked = 0;
    560627            fireNeedReq( msgs );
     
    563630        case BT_INTERESTED:
    564631            assert( msglen == 0 );
    565             fprintf( stderr, "w00t peer-msgs %p sent us a BT_INTERESTED at %s\n", msgs, ctime(&now) );
     632            dbgmsg( msgs, "w00t peer sent us a BT_INTERESTED" );
    566633            msgs->info->peerIsInterested = 1;
    567634            break;
     
    569636        case BT_NOT_INTERESTED:
    570637            assert( msglen == 0 );
    571             fprintf( stderr, "w00t peer-msgs %p sent us a BT_NOT_INTERESTED at %s\n", msgs, ctime(&now) );
     638            dbgmsg( msgs, "w00t peer sent us a BT_NOT_INTERESTED" );
    572639            msgs->info->peerIsInterested = 0;
    573640            break;
     
    575642        case BT_HAVE:
    576643            assert( msglen == 4 );
    577             fprintf( stderr, "peer-msgs %p sent us a BT_HAVE\n", msgs );
     644            dbgmsg( msgs, "w00t peer sent us a BT_HAVE" );
    578645            tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
    579646            tr_bitfieldAdd( msgs->info->have, ui32 );
    580647            msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) / (float)msgs->torrent->info.pieceCount;
    581             fprintf( stderr, "after the HAVE message, peer progress is %f\n", msgs->info->progress );
     648            dbgmsg( msgs, "after the HAVE message, peer progress is %f", msgs->info->progress );
    582649            updateInterest( msgs );
    583650            break;
     
    585652        case BT_BITFIELD:
    586653            assert( msglen == msgs->info->have->len );
    587             fprintf( stderr, "peer-msgs %p sent us a BT_BITFIELD\n", msgs );
     654            dbgmsg( msgs, "w00t peer sent us a BT_BITFIELD" );
    588655            tr_peerIoReadBytes( msgs->io, inbuf, msgs->info->have->bits, msglen );
    589656            msgs->info->progress = tr_bitfieldCountTrueBits( msgs->info->have ) / (float)msgs->torrent->info.pieceCount;
    590             fprintf( stderr, "after the BITFIELD peer progress is %f\n", msgs->info->progress );
     657            dbgmsg( msgs, "after the HAVE message, peer progress is %f", msgs->info->progress );
    591658            updateInterest( msgs );
     659            fireNeedReq( msgs );
    592660            /* FIXME: maybe unchoke */
    593661            break;
     
    596664            struct peer_request * req;
    597665            assert( msglen == 12 );
    598             fprintf( stderr, "got a BT_REQUEST\n" );
     666            dbgmsg( msgs, "peer sent us a BT_REQUEST" );
    599667            req = tr_new( struct peer_request, 1 );
    600668            tr_peerIoReadUint32( msgs->io, inbuf, &req->index );
     
    610678            tr_list * node;
    611679            assert( msglen == 12 );
    612             fprintf( stderr, "got a BT_CANCEL\n" );
     680            dbgmsg( msgs, "peer sent us a BT_CANCEL" );
    613681            tr_peerIoReadUint32( msgs->io, inbuf, &req.index );
    614682            tr_peerIoReadUint32( msgs->io, inbuf, &req.offset );
     
    616684            node = tr_list_find( msgs->peerAskedFor, &req, peer_request_compare );
    617685            if( node != NULL ) {
    618                 fprintf( stderr, "found the req that peer is cancelling... cancelled.\n" );
    619                 tr_list_remove_data( &msgs->peerAskedFor, node->data );
     686                void * data = node->data;
     687                tr_list_remove_data( &msgs->peerAskedFor, data );
     688                tr_free( data );
     689                dbgmsg( msgs, "found the req that peer is cancelling... cancelled." );
    620690            }
    621691            break;
     
    623693
    624694        case BT_PIECE: {
    625             fprintf( stderr, "peer-msgs %p sent us a BT_PIECE\n", msgs );
     695            dbgmsg( msgs, "peer sent us a BT_PIECE" );
    626696            assert( msgs->blockToUs.length == 0 );
    627697            msgs->state = READING_BT_PIECE;
     
    638708        case BT_PORT: {
    639709            assert( msglen == 2 );
    640             fprintf( stderr, "peer-msgs %p sent us a BT_PORT\n", msgs );
     710            dbgmsg( msgs, "peer sent us a BT_PORT" );
    641711            tr_peerIoReadUint16( msgs->io, inbuf, &msgs->listeningPort );
    642712            break;
     
    644714
    645715        case BT_LTEP:
    646             fprintf( stderr, "peer-msgs %p sent us a BT_LTEP\n", msgs );
     716            dbgmsg( msgs, "peer sent us a BT_LTEP" );
    647717            parseLtep( msgs, msglen, inbuf );
    648718            break;
    649719
    650720        default:
    651             fprintf( stderr, "peer-msgs %p sent us an UNKNOWN: %d\n", msgs, (int)id );
     721            dbgmsg( msgs, "peer sent us an UNKNOWN: %d", (int)id );
    652722            tr_peerIoDrain( msgs->io, inbuf, msglen );
    653723            assert( 0 );
     
    740810    const int block = _tr_block( tor, index, offset );
    741811    struct peer_request key, *req;
    742     const time_t now = time( NULL );
    743812
    744813    /**
     
    751820    req = (struct peer_request*) tr_list_remove( &msgs->clientAskedFor, &key,
    752821                                                 peer_request_compare );
    753     fprintf( stderr, "w00t got a block from %p. turnaround time for this block was %d seconds... at %s\n",
    754                      msgs, (int)(time(NULL) - req->time_requested), ctime(&now) );
     822    dbgmsg( msgs, "w00t peer sent us a block.  turnaround time was %d seconds",
     823                     (int)(time(NULL) - req->time_requested) );
    755824    if( req == NULL ) {
    756825        gotUnwantedBlock( msgs, index, offset, length );
    757         fprintf( stderr, "we didn't ask for this message...\n" );
    758         tr_dbg( "we didn't ask the peer for this message..." );
     826        dbgmsg( msgs, "we didn't ask for this message..." );
    759827        return;
    760828    }
    761829    tr_free( req );
    762     fprintf( stderr, "peer %p now has %d block requests in its outbox\n",
    763              msgs, tr_list_size(msgs->clientAskedFor));
     830    dbgmsg( msgs, "peer has %d more blocks we've asked for",
     831                 tr_list_size(msgs->clientAskedFor));
    764832
    765833    /**
     
    768836
    769837    if( tr_cpBlockIsComplete( tor->completion, block ) ) {
    770         fprintf( stderr, "have this block already...\n" );
     838        dbgmsg( msgs, "have this block already..." );
    771839        tr_dbg( "have this block already..." );
    772840        gotUnwantedBlock( msgs, index, offset, length );
     
    775843
    776844    if( (int)length != tr_torBlockCountBytes( tor, block ) ) {
    777         fprintf( stderr, "block is the wrong length..." );
     845        dbgmsg( msgs, "block is the wrong length..." );
    778846        tr_dbg( "block is the wrong length..." );
    779847        gotUnwantedBlock( msgs, index, offset, length );
     
    839907    if( !msgs->blockToUs.length )
    840908    {
    841         fprintf( stderr, "w00t -- got block index %u, offset %u\n", msgs->blockToUs.index, msgs->blockToUs.offset );
     909        dbgmsg( msgs, "w00t -- got block index %u, offset %u", msgs->blockToUs.index, msgs->blockToUs.offset );
    842910        assert( (int)EVBUFFER_LENGTH( msgs->inBlock ) == tr_torBlockCountBytes( msgs->torrent, _tr_block(msgs->torrent,msgs->blockToUs.index, msgs->blockToUs.offset) ) );
    843911        gotBlock( msgs, msgs->inBlock,
     
    879947{
    880948    /* don't let our outbuffer get too large */
    881     if( tr_peerIoWriteBytesWaiting( msgs->io ) > 2048 )
     949    if( tr_peerIoWriteBytesWaiting( msgs->io ) > 4096 )
    882950        return FALSE;
    883951
     
    926994        while ( len && canUpload( msgs ) )
    927995        {
    928             const size_t outlen = MIN( len, 2048 );
     996            const size_t outlen = MIN( len, 4096 );
    929997            tr_peerIoWrite( msgs->io, EVBUFFER_DATA(msgs->outBlock), outlen );
    930998            evbuffer_drain( msgs->outBlock, outlen );
    931999            peerGotBytes( msgs, outlen );
    9321000            len -= outlen;
     1001            dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len );
    9331002        }
    9341003    }
     
    9391008    else if(( msgs->peerAskedFor ))
    9401009    {
    941         struct peer_request * req = (struct peer_request*) msgs->peerAskedFor->data;
     1010        struct peer_request * req = tr_list_pop_front( &msgs->peerAskedFor );
    9421011        uint8_t * tmp = tr_new( uint8_t, req->length );
    9431012        const uint8_t msgid = BT_PIECE;
     
    9501019        tr_peerIoWriteBytes ( msgs->io, msgs->outBlock, tmp, req->length );
    9511020        tr_free( tmp );
     1021        dbgmsg( msgs, "putting req into out queue: index %d, offset %d, length %d ... %d blocks left in our queue", (int)req->index, (int)req->offset, (int)req->length, tr_list_size(msgs->peerAskedFor) );
     1022        tr_free( req );
    9521023    }
    9531024
     
    9681039
    9691040static void
    970 sendBitfield( tr_peermsgs * peer )
    971 {
    972     const tr_bitfield * bitfield = tr_cpPieceBitfield( peer->torrent->completion );
     1041sendBitfield( tr_peermsgs * msgs )
     1042{
     1043    const tr_bitfield * bitfield = tr_cpPieceBitfield( msgs->torrent->completion );
    9731044    const uint32_t len = sizeof(uint8_t) + bitfield->len;
    9741045    const uint8_t bt_msgid = BT_BITFIELD;
    9751046
    976     fprintf( stderr, "peer %p: enqueueing a bitfield message\n", peer );
    977     tr_peerIoWriteUint32( peer->io, peer->outMessages, len );
    978     tr_peerIoWriteBytes( peer->io, peer->outMessages, &bt_msgid, 1 );
    979     tr_peerIoWriteBytes( peer->io, peer->outMessages, bitfield->bits, bitfield->len );
     1047    dbgmsg( msgs, "sending peer a bitfield message\n", msgs );
     1048    tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len );
     1049    tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 );
     1050    tr_peerIoWriteBytes( msgs->io, msgs->outMessages, bitfield->bits, bitfield->len );
    9801051}
    9811052
     
    10491120        int bencLen;
    10501121        const uint8_t bt_msgid = BT_LTEP;
    1051         const uint8_t ltep_msgid = msgs->ut_pex_id;
     1122        const uint8_t ltep_msgid = OUR_LTEP_PEX;
    10521123
    10531124        /* build the diffs */
     
    10631134                        tr_pexCompare, sizeof(tr_pex),
    10641135                        pexRemovedCb, pexAddedCb, pexElementCb, &diffs );
    1065         fprintf( stderr, "pex: old peer count %d, new peer count %d, added %d, removed %d\n", msgs->pexCount, newCount, diffs.addedCount, diffs.droppedCount );
     1136        dbgmsg( msgs, "pex: old peer count %d, new peer count %d, added %d, removed %d", msgs->pexCount, newCount, diffs.addedCount, diffs.droppedCount );
    10661137
    10671138        /* update peer */
     
    10881159        tmp = walk = tr_new( uint8_t, diffs.addedCount );
    10891160        for( i=0; i<diffs.addedCount; ++i ) {
    1090             fprintf( stderr, "PEX -->> -->> flag is %d\n", (int)diffs.added[i].flags );
     1161            dbgmsg( msgs, "PEX -->> -->> flag is %d", (int)diffs.added[i].flags );
    10911162            *walk++ = diffs.added[i].flags;
    10921163        }
     
    11361207tr_peerMsgsNew( struct tr_torrent * torrent, struct tr_peer * info )
    11371208{
    1138     tr_peermsgs * peer;
     1209    tr_peermsgs * msgs;
    11391210
    11401211    assert( info != NULL );
    11411212    assert( info->io != NULL );
    11421213
    1143     peer = tr_new0( tr_peermsgs, 1 );
    1144     peer->publisher = tr_publisherNew( );
    1145     peer->info = info;
    1146     peer->handle = torrent->handle;
    1147     peer->torrent = torrent;
    1148     peer->io = info->io;
    1149     peer->info->clientIsChoked = 1;
    1150     peer->info->peerIsChoked = 1;
    1151     peer->info->clientIsInterested = 0;
    1152     peer->info->peerIsInterested = 0;
    1153     peer->info->have = tr_bitfieldNew( torrent->info.pieceCount );
    1154     peer->pulseTimer = tr_timerNew( peer->handle, pulse, peer, PEER_PULSE_INTERVAL );
    1155     peer->pexTimer = tr_timerNew( peer->handle, pexPulse, peer, PEX_INTERVAL );
    1156     peer->outMessages = evbuffer_new( );
    1157     peer->outBlock = evbuffer_new( );
    1158     peer->inBlock = evbuffer_new( );
    1159 
    1160     tr_peerIoSetIOFuncs( peer->io, canRead, didWrite, gotError, peer );
    1161     tr_peerIoSetIOMode( peer->io, EV_READ|EV_WRITE, 0 );
    1162 
    1163     sendBitfield( peer );
    1164     fireNeedReq( peer );
    1165 
    1166     return peer;
     1214    msgs = tr_new0( tr_peermsgs, 1 );
     1215    msgs->publisher = tr_publisherNew( );
     1216    msgs->info = info;
     1217    msgs->handle = torrent->handle;
     1218    msgs->torrent = torrent;
     1219    msgs->io = info->io;
     1220    msgs->info->clientIsChoked = 1;
     1221    msgs->info->peerIsChoked = 1;
     1222    msgs->info->clientIsInterested = 0;
     1223    msgs->info->peerIsInterested = 0;
     1224    msgs->info->have = tr_bitfieldNew( torrent->info.pieceCount );
     1225    msgs->pulseTimer = tr_timerNew( msgs->handle, pulse, msgs, PEER_PULSE_INTERVAL );
     1226    msgs->pexTimer = tr_timerNew( msgs->handle, pexPulse, msgs, PEX_INTERVAL );
     1227    msgs->outMessages = evbuffer_new( );
     1228    msgs->outBlock = evbuffer_new( );
     1229    msgs->inBlock = evbuffer_new( );
     1230
     1231    tr_peerIoSetIOFuncs( msgs->io, canRead, didWrite, gotError, msgs );
     1232    tr_peerIoSetIOMode( msgs->io, EV_READ|EV_WRITE, 0 );
     1233
     1234    /**
     1235    ***  If we initiated this connection,
     1236    ***  we may need to send LTEP/AZMP handshakes.
     1237    ***  Otherwise we'll wait for the peer to send theirs first.
     1238    **/
     1239    if( !tr_peerIoIsIncoming( msgs->io ) )
     1240    {
     1241        const int extensions = tr_peerIoGetExtension( msgs->io );
     1242        switch( extensions )
     1243        {
     1244            case LT_EXTENSIONS_NONE:
     1245                /* no-op */
     1246                break;
     1247
     1248            case LT_EXTENSIONS_LTEP:
     1249                sendLtepHandshake( msgs );
     1250                break;
     1251
     1252            case LT_EXTENSIONS_AZMP:
     1253                dbgmsg( msgs, "FIXME: need to send AZMP handshake" );
     1254                break;
     1255        }
     1256    }
     1257
     1258    sendBitfield( msgs );
     1259    return msgs;
    11671260}
    11681261
  • branches/encryption/libtransmission/torrent.c

    r3090 r3101  
    5252***/
    5353
     54int
     55tr_torrentExists( tr_handle       * handle,
     56                  const uint8_t   * torrentHash )
     57{
     58    return tr_torrentFindFromHash( handle, torrentHash ) != NULL;
     59}
     60
    5461tr_torrent*
    5562tr_torrentFindFromHash( tr_handle      * handle,
     
    167174
    168175        case TR_TRACKER_STOPPED:
    169             assert( tor->runStatus == TR_RUN_STOPPING );
     176            //assert( tor->runStatus == TR_RUN_STOPPING );
    170177            tor->runStatus = TR_RUN_STOPPED;
    171178            break;
  • branches/encryption/libtransmission/transmission.c

    r3072 r3101  
    7979***/
    8080
     81tr_encryption_mode
     82tr_getEncryptionMode( tr_handle * handle )
     83{
     84    assert( handle != NULL );
     85
     86    return handle->encryptionMode;
     87}
     88
     89void
     90tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode )
     91{
     92    assert( handle != NULL );
     93    assert( mode==TR_ENCRYPTION_PREFERRED || mode==TR_ENCRYPTION_REQUIRED );
     94
     95    handle->encryptionMode = mode;
     96}
     97
     98/***
     99****
     100***/
     101
    81102
    82103/***********************************************************************
     
    100121    if( !h )
    101122        return NULL;
     123
     124    h->encryptionMode = TR_ENCRYPTION_PREFERRED;
    102125
    103126    tr_eventInit( h );
  • branches/encryption/libtransmission/transmission.h

    r3090 r3101  
    102102 *   beos cli daemon gtk macosx
    103103 **********************************************************************/
     104
    104105typedef struct tr_handle tr_handle;
    105106typedef struct tr_handle tr_handle_t;
     107
    106108tr_handle * tr_init( const char * tag );
    107109
    108110typedef struct tr_tracker_info tr_tracker_info;
    109111typedef struct tr_tracker_info tr_tracker_info_t;
     112
     113/**
     114***
     115**/
     116
     117typedef enum
     118{
     119    TR_ENCRYPTION_PREFERRED,
     120    TR_ENCRYPTION_REQUIRED
     121}
     122tr_encryption_mode;
     123
     124tr_encryption_mode tr_getEncryptionMode( tr_handle * handle );
     125
     126void tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode );
    110127
    111128/***********************************************************************
Note: See TracChangeset for help on using the changeset viewer.