Changeset 3101
- Timestamp:
- Sep 20, 2007, 4:11:09 AM (15 years ago)
- Location:
- branches/encryption/libtransmission
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/encryption/libtransmission/handshake.c
r3079 r3101 44 44 #define HANDSHAKE_SIZE 68 45 45 46 /*** 47 **** 48 ***/ 49 50 enum 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 46 59 #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 ) 49 62 #else 50 63 #define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 ) … … 53 66 54 67 #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 ) 57 70 #else 58 71 #define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 ) … … 70 83 #define HANDSHAKE_EXTPREF_AZMP_FORCE ( 0x3 ) 71 84 85 enum 86 { 87 PadA_MAXLEN = 512, 88 PadB_MAXLEN = 512, 89 PadC_MAXLEN = 512, 90 PadD_MAXLEN = 512 91 }; 92 72 93 extern const char* getPeerId( void ) ; 73 94 … … 77 98 struct tr_handshake 78 99 { 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; 81 104 tr_peerIo * io; 82 105 tr_crypto * crypto; … … 85 108 uint8_t mySecret[96]; 86 109 uint8_t state; 87 uint8_t encryptionPreference;88 110 uint16_t pad_c_len; 89 111 uint16_t pad_d_len; … … 96 118 }; 97 119 98 static void99 fireDoneCB( tr_handshake * handshake, int isConnected );100 101 120 /** 102 121 *** 103 122 **/ 104 123 105 enum /*ccc*/124 enum 106 125 { 107 126 /* incoming */ … … 123 142 *** 124 143 **/ 144 145 static void 146 myDebug( 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 ) 125 162 126 163 static const char* getStateName( short state ) … … 141 178 case AWAITING_CRYPTO_SELECT: str = "awaiting crypto select"; break; 142 179 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; 144 181 } 145 182 return str; … … 149 186 setState( tr_handshake * handshake, short state ) 150 187 { 151 fprintf( stderr, "handshake %p: setting to state [%s]\n", handshake, getStateName(state) );188 dbgmsg( handshake, "setting to state [%s]", getStateName(state) ); 152 189 handshake->state = state; 153 190 } … … 160 197 } 161 198 199 static uint8_t * 200 buildHandshakeMessage( 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 */ 162 254 static void 163 send PublicKey( tr_handshake * handshake )255 sendYa( tr_handshake * handshake ) 164 256 { 165 257 int i; … … 167 259 const uint8_t * public_key; 168 260 struct evbuffer * outbuf = evbuffer_new( ); 169 uint8_t pad [512];261 uint8_t pad_a[PadA_MAXLEN]; 170 262 171 263 /* add our public key (Ya) */ … … 176 268 177 269 /* add some bullshit padding */ 178 len = tr_rand( 512);270 len = tr_rand( PadA_MAXLEN ); 179 271 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 ); 182 274 183 275 /* send it */ 184 276 setReadState( handshake, AWAITING_YB ); 185 //setState( handshake, SENDING_YA );186 277 tr_peerIoWriteBuf( handshake->io, outbuf ); 187 278 … … 189 280 evbuffer_free( outbuf ); 190 281 } 191 192 static void193 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 void213 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 void223 sendHandshake( tr_handshake * handshake )224 {225 if( ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_PREFERRED ) ||226 ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_REQUIRED ) )227 {228 sendPublicKey( handshake );229 }230 else231 {232 sendPlaintextHandshake( handshake );233 }234 }235 236 static void237 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, <ep_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 int284 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 int315 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 int343 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 int393 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 int411 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 **/430 282 431 283 static int … … 440 292 if( EVBUFFER_LENGTH(inbuf) < needlen ) 441 293 return READ_MORE; 442 fprintf( stderr, "%*.*s\n", HANDSHAKE_NAME_LEN, HANDSHAKE_NAME_LEN, EVBUFFER_DATA(inbuf) );443 294 444 295 isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN ); … … 449 300 } 450 301 451 fprintf( stderr, "got a %s handshake\n", (isEncrypted ? "encrypted" : "plaintext") ); 302 dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") ); 303 452 304 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 ); 456 307 if( !isEncrypted ) { 457 308 setState( handshake, AWAITING_HANDSHAKE ); … … 503 354 /* crypto_provide */ 504 355 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 */ 508 358 crypto_provide |= (1<<1); 509 359 assert( 1<=crypto_provide && crypto_provide<=3 ); … … 528 378 { 529 379 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 ); 534 384 tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i ); 535 385 evbuffer_add( outbuf, &i, sizeof(uint16_t) ); 536 386 537 tr_cryptoEncrypt( handshake->crypto, HANDSHAKE_SIZE, msg, msg );387 tr_cryptoEncrypt( handshake->crypto, msgSize, msg, msg ); 538 388 evbuffer_add( outbuf, msg, HANDSHAKE_SIZE ); 389 handshake->haveSentBitTorrentHandshake = 1; 390 391 tr_free( msg ); 539 392 } 540 393 … … 562 415 { 563 416 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" ); 565 418 return READ_MORE; 566 419 } … … 575 428 } 576 429 577 fprintf( stderr, "got it!\n" );430 dbgmsg( handshake, "got it!" ); 578 431 evbuffer_drain( inbuf, key_len ); 579 432 setState( handshake, AWAITING_CRYPTO_SELECT ); … … 594 447 assert( crypto_select==1 || crypto_select==2 ); 595 448 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 ); 597 450 598 451 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 ); 600 453 assert( pad_d_len <= 512 ); 601 454 handshake->pad_d_len = pad_d_len; … … 611 464 uint8_t * tmp; 612 465 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) ); 614 467 if( EVBUFFER_LENGTH(inbuf) < needlen ) 615 468 return READ_MORE; … … 626 479 } 627 480 481 /*** 482 **** 483 **** INCOMING CONNECTIONS 484 **** 485 ***/ 486 628 487 static void 629 gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg ); 630 631 /*ccc*/ 488 tr_handshakeDone( tr_handshake * handshake, int isConnected ); 489 632 490 static int 633 491 readHandshake( tr_handshake * handshake, struct evbuffer * inbuf ) 634 492 { 635 493 int i; 636 int ltep = 0; 637 int azmp = 0; 638 int isEncrypted; 494 uint8_t ltep = 0; 495 uint8_t azmp = 0; 639 496 uint8_t pstrlen; 640 497 uint8_t * pstr; 641 498 uint8_t reserved[8]; 642 499 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) ); 646 502 647 503 if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE ) 648 504 return READ_MORE; 649 505 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 ) ) { 506 for( i=0; i<(int)EVBUFFER_LENGTH(inbuf); ++i ) 507 fprintf( stderr, "[%c]", EVBUFFER_DATA(inbuf)[i] ); 508 fprintf( 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..." ); 666 524 setState( handshake, AWAITING_YA ); 667 525 return READ_AGAIN; 668 526 } 669 527 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 672 537 evbuffer_drain( inbuf, 1 ); 673 fprintf( stderr, "pstrlen is %d [%c]\n", (int)pstrlen, pstrlen );674 assert( pstrlen == 19 );675 538 676 539 /* pstr (BitTorrent) */ … … 678 541 tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen ); 679 542 pstr[pstrlen] = '\0'; 680 fprintf( stderr, "pstrlen is [%s]\n", pstr );681 bytesRead += pstrlen;682 fprintf( stderr, "%*.*s", pstrlen, pstrlen, (char*)pstr );683 543 if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) { 684 544 tr_free( pstr ); 685 gotError( NULL, 0, handshake);545 tr_handshakeDone( handshake, FALSE ); 686 546 return READ_DONE; 687 547 } … … 690 550 /* reserved bytes */ 691 551 tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) ); 692 bytesRead += sizeof(reserved);693 552 694 553 /* torrent hash */ 695 554 tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) ); 696 bytesRead += sizeof(hash);697 555 if( tr_peerIoIsIncoming( handshake->io ) ) 698 556 { 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 ) ); 704 572 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 } 706 579 } 707 580 … … 709 582 tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) ); 710 583 tr_peerIoSetPeersId( handshake->io, handshake->peer_id ); 711 bytesRead += sizeof(handshake->peer_id);712 584 handshake->havePeerID = TRUE; 713 585 714 assert( bytesRead == HANDSHAKE_SIZE );715 716 586 /** 717 *** 587 *** Extension negotiation 718 588 **/ 719 589 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 ); 722 592 if( ltep && azmp ) { 723 593 switch( HANDSHAKE_GET_EXTPREF( reserved ) ) { … … 733 603 } 734 604 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" ); } 738 608 tr_peerIoSetExtension( handshake->io, i ); 739 609 740 610 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 631 static int 632 readYa( 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 662 static int 663 readPadA( 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 690 static int 691 readCryptoProvide( 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 740 static int 741 readPadC( 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 758 static int 759 readIA( 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 ***/ 760 774 761 775 static ReadState … … 765 779 struct evbuffer * inbuf = EVBUFFER_INPUT ( evin ); 766 780 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) ); 768 782 769 783 switch( handshake->state ) … … 788 802 789 803 static void 790 tr_handshakeFree( tr_handshake * handshake ) 791 { 792 tr_free( handshake ); 793 } 794 795 static void 796 fireDoneCB( tr_handshake * handshake, int isConnected ) 804 fireDoneFunc( tr_handshake * handshake, int isConnected ) 797 805 { 798 806 const uint8_t * peer_id = isConnected && handshake->havePeerID … … 805 813 handshake->peerSupportsEncryption, 806 814 handshake->doneUserData ); 807 tr_handshakeFree( handshake ); 815 } 816 817 void 818 tr_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 826 void 827 tr_handshakeAbort( tr_handshake * handshake ) 828 { 829 tr_handshakeDone( handshake, FALSE ); 808 830 } 809 831 … … 817 839 * try a plaintext handshake */ 818 840 if( ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) ) 819 && ( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED)841 && ( !handshake->shunUnencryptedPeers ) 820 842 && ( !tr_peerIoReconnect( handshake->io ) ) ) 821 843 { 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 ); 825 849 } 826 850 else 827 851 { 828 tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL ); 829 fireDoneCB( handshake, FALSE ); 852 tr_handshakeDone( handshake, FALSE ); 830 853 } 831 854 } … … 836 859 837 860 tr_handshake* 838 tr_handshakeNew( tr_peerIo * io,839 int encryptionPreference,840 handshakeDoneCB doneCB,841 void * doneUserData )861 tr_handshakeNew( tr_peerIo * io, 862 tr_encryption_mode encryption_mode, 863 handshakeDoneCB doneCB, 864 void * doneUserData ) 842 865 { 843 866 tr_handshake * handshake; 844 867 845 // w00t868 // w00t 846 869 //static int count = 0; 847 870 //if( count++ ) return NULL; … … 850 873 handshake->io = io; 851 874 handshake->crypto = tr_peerIoGetCrypto( io ); 852 handshake-> encryptionPreference = encryptionPreference;875 handshake->shunUnencryptedPeers = encryption_mode==TR_ENCRYPTION_REQUIRED; 853 876 handshake->doneCB = doneCB; 854 877 handshake->doneUserData = doneUserData; … … 858 881 tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake ); 859 882 860 fprintf( stderr, "handshake %p: new handshake for io %p\n", handshake, io );883 dbgmsg( handshake, "new handshake for io %p", io ); 861 884 862 885 if( tr_peerIoIsIncoming( io ) ) 863 {864 886 setReadState( handshake, AWAITING_HANDSHAKE ); 865 }866 887 else 867 { 868 sendHandshake( handshake ); 869 } 888 sendYa( handshake ); 870 889 871 890 return handshake; 872 891 } 873 874 void875 tr_handshakeAbort( tr_handshake * handshake )876 {877 tr_peerIoFree( handshake->io );878 tr_handshakeFree( handshake );879 } -
branches/encryption/libtransmission/handshake.h
r3076 r3101 14 14 #define TR_HANDSHAKE_H 15 15 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" 23 17 24 18 struct tr_peerIo; … … 32 26 void * userData ); 33 27 34 tr_handshake * tr_handshakeNew( struct tr_peerIo * io,35 int encryptionPreference,36 handshakeDoneCB doneCB,37 void * doneUserData );28 tr_handshake * tr_handshakeNew( struct tr_peerIo * io, 29 tr_encryption_mode encryptionMode, 30 handshakeDoneCB doneCB, 31 void * doneUserData ); 38 32 39 void tr_handshakeAbort( tr_handshake *);33 void tr_handshakeAbort( tr_handshake * handshake ); 40 34 41 35 #endif -
branches/encryption/libtransmission/internal.h
r3090 r3101 63 63 void tr_torrentChangeMyPort ( tr_torrent *, int port ); 64 64 65 int tr_torrentExists( tr_handle *, const uint8_t * ); 65 66 tr_torrent* tr_torrentFindFromHash( tr_handle *, const uint8_t * ); 66 67 tr_torrent* tr_torrentFindFromObfuscatedHash( tr_handle *, const uint8_t* ); … … 168 169 struct tr_handle 169 170 { 171 tr_encryption_mode encryptionMode; 172 170 173 struct tr_event_handle * events; 171 174 -
branches/encryption/libtransmission/peer-io.c
r3089 r3101 200 200 } 201 201 202 const char* 203 tr_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 202 211 void 203 212 tr_peerIoSetIOFuncs( tr_peerIo * io, … … 377 386 { 378 387 assert( io != NULL ); 379 assert( encryptionMode==PEER_ENCRYPTION_ PLAINTEXT|| encryptionMode==PEER_ENCRYPTION_RC4 );388 assert( encryptionMode==PEER_ENCRYPTION_NONE || encryptionMode==PEER_ENCRYPTION_RC4 ); 380 389 381 390 io->encryptionMode = encryptionMode; … … 398 407 switch( io->encryptionMode ) 399 408 { 400 case PEER_ENCRYPTION_ PLAINTEXT:409 case PEER_ENCRYPTION_NONE: 401 410 /*fprintf( stderr, "writing %d plaintext bytes to outbuf...\n", byteCount );*/ 402 411 evbuffer_add( outbuf, bytes, byteCount ); … … 444 453 switch( io->encryptionMode ) 445 454 { 446 case PEER_ENCRYPTION_ PLAINTEXT:455 case PEER_ENCRYPTION_NONE: 447 456 /*fprintf( stderr, "reading %d plaintext bytes from inbuf...\n", byteCount );*/ 448 457 evbuffer_remove( inbuf, bytes, byteCount ); -
branches/encryption/libtransmission/peer-io.h
r3089 r3101 64 64 *** 65 65 **/ 66 67 const char* 68 tr_peerIoGetAddrStr( const tr_peerIo * io ); 66 69 67 70 const struct in_addr* … … 132 135 { 133 136 /* these match the values in MSE's crypto_select */ 134 PEER_ENCRYPTION_ PLAINTEXT= (1<<0),135 PEER_ENCRYPTION_RC4 137 PEER_ENCRYPTION_NONE = (1<<0), 138 PEER_ENCRYPTION_RC4 = (1<<1) 136 139 } 137 140 EncryptionMode; -
branches/encryption/libtransmission/peer-mgr.c
r3098 r3101 225 225 tr_peerMgrFree( tr_peerMgr * manager ) 226 226 { 227 int i, n;228 227 fprintf( 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 ); 229 232 230 233 while( !tr_ptrArrayEmpty( manager->torrents ) ) 231 234 freeTorrent( manager, (Torrent*)tr_ptrArrayNth( manager->torrents, 0) ); 232 235 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 );237 236 238 237 tr_free( manager ); … … 605 604 { 606 605 tr_handshake * handshake = tr_handshakeNew( io, 607 HANDSHAKE_ENCRYPTION_PREFERRED,606 manager->handle->encryptionMode, 608 607 myHandshakeDoneCB, 609 608 manager ); -
branches/encryption/libtransmission/peer-msgs.c
r3095 r3101 41 41 #define PEX_INTERVAL (60 * 1000) 42 42 43 #define PEER_PULSE_INTERVAL ( 50)43 #define PEER_PULSE_INTERVAL (100) 44 44 45 45 enum … … 57 57 BT_LTEP = 20, 58 58 59 LTEP_HANDSHAKE = 0 59 LTEP_HANDSHAKE = 0, 60 61 OUR_LTEP_PEX = 1 60 62 }; 61 63 … … 111 113 time_t clientSentPexAt; 112 114 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; 115 118 116 119 uint8_t state; … … 125 128 tr_pex * pex; 126 129 }; 130 131 /** 132 *** 133 **/ 134 135 static void 136 myDebug( 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 ) 127 152 128 153 /** … … 231 256 const uint32_t len = sizeof(uint8_t); 232 257 const uint8_t bt_msgid = weAreInterested ? BT_INTERESTED : BT_NOT_INTERESTED; 233 const time_t now = time( NULL );234 258 235 259 assert( msgs != NULL ); … … 237 261 238 262 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") ); 240 264 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len ); 241 265 tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 ); … … 258 282 assert( msgs->info != NULL ); 259 283 assert( choke==0 || choke==1 ); 260 const time_t now = time( NULL );261 284 262 285 if( msgs->info->peerIsChoked != choke ) … … 272 295 } 273 296 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") ); 275 298 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len ); 276 299 tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 ); … … 325 348 const uint8_t bt_msgid = BT_HAVE; 326 349 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 ); 328 351 tr_peerIoWriteUint32( msgs->io, msgs->outMessages, len ); 329 352 tr_peerIoWriteBytes( msgs->io, msgs->outMessages, &bt_msgid, 1 ); … … 368 391 return TR_ADDREQ_FULL; 369 392 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 ); 371 394 372 395 /* queue the request */ … … 394 417 395 418 static void 396 parseLtepHandshake( tr_peermsgs * peer, int len, struct evbuffer * inbuf ) 419 sendLtepHandshake( 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, <ep_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 461 static void 462 parseLtepHandshake( tr_peermsgs * msgs, int len, struct evbuffer * inbuf ) 397 463 { 398 464 benc_val_t val, * sub; … … 401 467 402 468 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" ); 404 470 tr_free( tmp ); 405 471 return; … … 413 479 sub = tr_bencDictFind( sub, "ut_pex" ); 414 480 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 ); 418 484 } 419 485 } … … 424 490 if( tr_bencIsStr( sub ) ) { 425 491 int i; 426 tr_free( peer->info->client );492 tr_free( msgs->info->client ); 427 493 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 ); 429 495 for( 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 ); 432 498 } 433 499 #endif … … 436 502 sub = tr_bencDictFind( &val, "p" ); 437 503 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 ); 440 506 } 441 507 … … 457 523 458 524 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" ); 460 526 tr_free( tmp ); 461 527 return; … … 465 531 if( tr_bencIsStr(sub) && ((sub->val.s.i % 6) == 0)) { 466 532 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 ); 468 534 tr_peerMgrAddPeers( msgs->handle->peerMgr, 469 535 msgs->torrent->info.hash, … … 489 555 if( ltep_msgid == LTEP_HANDSHAKE ) 490 556 { 491 fprintf( stderr, "got ltep handshake\n" );557 dbgmsg( msgs, "got ltep handshake" ); 492 558 parseLtepHandshake( msgs, msglen, inbuf ); 559 if( !msgs->hasSentLtepHandshake ) 560 sendLtepHandshake( msgs ); 493 561 } 494 562 else if( ltep_msgid == msgs->ut_pex_id ) 495 563 { 496 fprintf( stderr, "got ut pex\n" );564 dbgmsg( msgs, "got ut pex" ); 497 565 msgs->peerSupportsPex = 1; 498 566 parseUtPex( msgs, msglen, inbuf ); … … 500 568 else 501 569 { 502 fprintf( stderr, "skipping unknown ltep message (%d)\n", (int)ltep_msgid );570 dbgmsg( msgs, "skipping unknown ltep message (%d)", (int)ltep_msgid ); 503 571 evbuffer_drain( inbuf, msglen ); 504 572 } … … 517 585 518 586 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..." ); 520 588 msgs->gotKeepAliveTime = time( NULL ); 521 589 } 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 ); 523 591 msgs->incomingMessageLength = len; 524 592 msgs->state = AWAITING_BT_MESSAGE; … … 532 600 uint32_t ui32; 533 601 uint32_t msglen = msgs->incomingMessageLength; 534 const time_t now = time( NULL );535 602 536 603 if( EVBUFFER_LENGTH(inbuf) < msglen ) … … 539 606 tr_peerIoReadBytes( msgs->io, inbuf, &id, 1 ); 540 607 msglen--; 541 fprintf( stderr, "peer %psent 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 ); 543 610 544 611 switch( id ) … … 546 613 case BT_CHOKE: 547 614 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" ); 549 616 msgs->info->clientIsChoked = 1; 550 617 tr_list_foreach( msgs->peerAskedFor, tr_free ); … … 556 623 case BT_UNCHOKE: 557 624 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" ); 559 626 msgs->info->clientIsChoked = 0; 560 627 fireNeedReq( msgs ); … … 563 630 case BT_INTERESTED: 564 631 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" ); 566 633 msgs->info->peerIsInterested = 1; 567 634 break; … … 569 636 case BT_NOT_INTERESTED: 570 637 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" ); 572 639 msgs->info->peerIsInterested = 0; 573 640 break; … … 575 642 case BT_HAVE: 576 643 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" ); 578 645 tr_peerIoReadUint32( msgs->io, inbuf, &ui32 ); 579 646 tr_bitfieldAdd( msgs->info->have, ui32 ); 580 647 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 ); 582 649 updateInterest( msgs ); 583 650 break; … … 585 652 case BT_BITFIELD: 586 653 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" ); 588 655 tr_peerIoReadBytes( msgs->io, inbuf, msgs->info->have->bits, msglen ); 589 656 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 ); 591 658 updateInterest( msgs ); 659 fireNeedReq( msgs ); 592 660 /* FIXME: maybe unchoke */ 593 661 break; … … 596 664 struct peer_request * req; 597 665 assert( msglen == 12 ); 598 fprintf( stderr, "got a BT_REQUEST\n" );666 dbgmsg( msgs, "peer sent us a BT_REQUEST" ); 599 667 req = tr_new( struct peer_request, 1 ); 600 668 tr_peerIoReadUint32( msgs->io, inbuf, &req->index ); … … 610 678 tr_list * node; 611 679 assert( msglen == 12 ); 612 fprintf( stderr, "got a BT_CANCEL\n" );680 dbgmsg( msgs, "peer sent us a BT_CANCEL" ); 613 681 tr_peerIoReadUint32( msgs->io, inbuf, &req.index ); 614 682 tr_peerIoReadUint32( msgs->io, inbuf, &req.offset ); … … 616 684 node = tr_list_find( msgs->peerAskedFor, &req, peer_request_compare ); 617 685 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." ); 620 690 } 621 691 break; … … 623 693 624 694 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" ); 626 696 assert( msgs->blockToUs.length == 0 ); 627 697 msgs->state = READING_BT_PIECE; … … 638 708 case BT_PORT: { 639 709 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" ); 641 711 tr_peerIoReadUint16( msgs->io, inbuf, &msgs->listeningPort ); 642 712 break; … … 644 714 645 715 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" ); 647 717 parseLtep( msgs, msglen, inbuf ); 648 718 break; 649 719 650 720 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 ); 652 722 tr_peerIoDrain( msgs->io, inbuf, msglen ); 653 723 assert( 0 ); … … 740 810 const int block = _tr_block( tor, index, offset ); 741 811 struct peer_request key, *req; 742 const time_t now = time( NULL );743 812 744 813 /** … … 751 820 req = (struct peer_request*) tr_list_remove( &msgs->clientAskedFor, &key, 752 821 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) ); 755 824 if( req == NULL ) { 756 825 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..." ); 759 827 return; 760 828 } 761 829 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)); 764 832 765 833 /** … … 768 836 769 837 if( tr_cpBlockIsComplete( tor->completion, block ) ) { 770 fprintf( stderr, "have this block already...\n" );838 dbgmsg( msgs, "have this block already..." ); 771 839 tr_dbg( "have this block already..." ); 772 840 gotUnwantedBlock( msgs, index, offset, length ); … … 775 843 776 844 if( (int)length != tr_torBlockCountBytes( tor, block ) ) { 777 fprintf( stderr, "block is the wrong length..." );845 dbgmsg( msgs, "block is the wrong length..." ); 778 846 tr_dbg( "block is the wrong length..." ); 779 847 gotUnwantedBlock( msgs, index, offset, length ); … … 839 907 if( !msgs->blockToUs.length ) 840 908 { 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 ); 842 910 assert( (int)EVBUFFER_LENGTH( msgs->inBlock ) == tr_torBlockCountBytes( msgs->torrent, _tr_block(msgs->torrent,msgs->blockToUs.index, msgs->blockToUs.offset) ) ); 843 911 gotBlock( msgs, msgs->inBlock, … … 879 947 { 880 948 /* don't let our outbuffer get too large */ 881 if( tr_peerIoWriteBytesWaiting( msgs->io ) > 2048)949 if( tr_peerIoWriteBytesWaiting( msgs->io ) > 4096 ) 882 950 return FALSE; 883 951 … … 926 994 while ( len && canUpload( msgs ) ) 927 995 { 928 const size_t outlen = MIN( len, 2048);996 const size_t outlen = MIN( len, 4096 ); 929 997 tr_peerIoWrite( msgs->io, EVBUFFER_DATA(msgs->outBlock), outlen ); 930 998 evbuffer_drain( msgs->outBlock, outlen ); 931 999 peerGotBytes( msgs, outlen ); 932 1000 len -= outlen; 1001 dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len ); 933 1002 } 934 1003 } … … 939 1008 else if(( msgs->peerAskedFor )) 940 1009 { 941 struct peer_request * req = (struct peer_request*) msgs->peerAskedFor->data;1010 struct peer_request * req = tr_list_pop_front( &msgs->peerAskedFor ); 942 1011 uint8_t * tmp = tr_new( uint8_t, req->length ); 943 1012 const uint8_t msgid = BT_PIECE; … … 950 1019 tr_peerIoWriteBytes ( msgs->io, msgs->outBlock, tmp, req->length ); 951 1020 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 ); 952 1023 } 953 1024 … … 968 1039 969 1040 static void 970 sendBitfield( tr_peermsgs * peer)971 { 972 const tr_bitfield * bitfield = tr_cpPieceBitfield( peer->torrent->completion );1041 sendBitfield( tr_peermsgs * msgs ) 1042 { 1043 const tr_bitfield * bitfield = tr_cpPieceBitfield( msgs->torrent->completion ); 973 1044 const uint32_t len = sizeof(uint8_t) + bitfield->len; 974 1045 const uint8_t bt_msgid = BT_BITFIELD; 975 1046 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 ); 980 1051 } 981 1052 … … 1049 1120 int bencLen; 1050 1121 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; 1052 1123 1053 1124 /* build the diffs */ … … 1063 1134 tr_pexCompare, sizeof(tr_pex), 1064 1135 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 ); 1066 1137 1067 1138 /* update peer */ … … 1088 1159 tmp = walk = tr_new( uint8_t, diffs.addedCount ); 1089 1160 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 ); 1091 1162 *walk++ = diffs.added[i].flags; 1092 1163 } … … 1136 1207 tr_peerMsgsNew( struct tr_torrent * torrent, struct tr_peer * info ) 1137 1208 { 1138 tr_peermsgs * peer;1209 tr_peermsgs * msgs; 1139 1210 1140 1211 assert( info != NULL ); 1141 1212 assert( info->io != NULL ); 1142 1213 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; 1167 1260 } 1168 1261 -
branches/encryption/libtransmission/torrent.c
r3090 r3101 52 52 ***/ 53 53 54 int 55 tr_torrentExists( tr_handle * handle, 56 const uint8_t * torrentHash ) 57 { 58 return tr_torrentFindFromHash( handle, torrentHash ) != NULL; 59 } 60 54 61 tr_torrent* 55 62 tr_torrentFindFromHash( tr_handle * handle, … … 167 174 168 175 case TR_TRACKER_STOPPED: 169 assert( tor->runStatus == TR_RUN_STOPPING );176 //assert( tor->runStatus == TR_RUN_STOPPING ); 170 177 tor->runStatus = TR_RUN_STOPPED; 171 178 break; -
branches/encryption/libtransmission/transmission.c
r3072 r3101 79 79 ***/ 80 80 81 tr_encryption_mode 82 tr_getEncryptionMode( tr_handle * handle ) 83 { 84 assert( handle != NULL ); 85 86 return handle->encryptionMode; 87 } 88 89 void 90 tr_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 81 102 82 103 /*********************************************************************** … … 100 121 if( !h ) 101 122 return NULL; 123 124 h->encryptionMode = TR_ENCRYPTION_PREFERRED; 102 125 103 126 tr_eventInit( h ); -
branches/encryption/libtransmission/transmission.h
r3090 r3101 102 102 * beos cli daemon gtk macosx 103 103 **********************************************************************/ 104 104 105 typedef struct tr_handle tr_handle; 105 106 typedef struct tr_handle tr_handle_t; 107 106 108 tr_handle * tr_init( const char * tag ); 107 109 108 110 typedef struct tr_tracker_info tr_tracker_info; 109 111 typedef struct tr_tracker_info tr_tracker_info_t; 112 113 /** 114 *** 115 **/ 116 117 typedef enum 118 { 119 TR_ENCRYPTION_PREFERRED, 120 TR_ENCRYPTION_REQUIRED 121 } 122 tr_encryption_mode; 123 124 tr_encryption_mode tr_getEncryptionMode( tr_handle * handle ); 125 126 void tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode ); 110 127 111 128 /***********************************************************************
Note: See TracChangeset
for help on using the changeset viewer.