maybe fix incoming handshakes with peers that don't send their peer_id immediately

This commit is contained in:
Charles Kerr 2007-10-23 14:14:37 +00:00
parent 50c8c88c04
commit 799954843e
1 changed files with 43 additions and 31 deletions

View File

@ -116,6 +116,7 @@ enum
{ {
/* incoming */ /* incoming */
AWAITING_HANDSHAKE, AWAITING_HANDSHAKE,
AWAITING_PEER_ID,
AWAITING_YA, AWAITING_YA,
AWAITING_PAD_A, AWAITING_PAD_A,
AWAITING_CRYPTO_PROVIDE, AWAITING_CRYPTO_PROVIDE,
@ -165,6 +166,7 @@ static const char* getStateName( short state )
const char * str = "f00!"; const char * str = "f00!";
switch( state ) { switch( state ) {
case AWAITING_HANDSHAKE: str = "awaiting handshake"; break; case AWAITING_HANDSHAKE: str = "awaiting handshake"; break;
case AWAITING_PEER_ID: str = "awaiting peer_id"; break;
case AWAITING_YA: str = "awaiting ya"; break; case AWAITING_YA: str = "awaiting ya"; break;
case AWAITING_PAD_A: str = "awaiting pad a"; break; case AWAITING_PAD_A: str = "awaiting pad a"; break;
case AWAITING_CRYPTO_PROVIDE: str = "awaiting crypto_provide"; break; case AWAITING_CRYPTO_PROVIDE: str = "awaiting crypto_provide"; break;
@ -529,13 +531,13 @@ readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
uint8_t * pstr; uint8_t * pstr;
uint8_t reserved[HANDSHAKE_FLAGS_LEN]; uint8_t reserved[HANDSHAKE_FLAGS_LEN];
uint8_t hash[SHA_DIGEST_LENGTH]; uint8_t hash[SHA_DIGEST_LENGTH];
char * client; const size_t sizeNeeded = HANDSHAKE_SIZE - PEER_ID_LEN;
/* FIXME: use readHandshake here */ /* FIXME: use readHandshake here */
dbgmsg( handshake, "payload: need %d, got %d", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) ); dbgmsg( handshake, "payload: need %d, got %d", (int)sizeNeeded, (int)EVBUFFER_LENGTH(inbuf) );
if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE ) if( EVBUFFER_LENGTH(inbuf) < sizeNeeded )
return READ_MORE; return READ_MORE;
pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read. We may be pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read. We may be
@ -615,19 +617,6 @@ readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
} }
} }
/* peer id */
tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
handshake->havePeerID = TRUE;
client = tr_clientForId( handshake->peer_id );
dbgmsg( handshake, "peer-id is [%s]", client );
tr_free( client );
if( !memcmp( handshake->peer_id, getPeerId(), PEER_ID_LEN ) ) {
dbgmsg( handshake, "streuth! we've connected to ourselves." );
tr_handshakeDone( handshake, FALSE );
return READ_DONE;
}
/** /**
*** Extension negotiation *** Extension negotiation
**/ **/
@ -656,8 +645,30 @@ readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
handshake->haveSentBitTorrentHandshake = 1; handshake->haveSentBitTorrentHandshake = 1;
} }
setReadState( handshake, AWAITING_PEER_ID );
return READ_AGAIN;
}
static int
readPeerId( tr_handshake * handshake, struct evbuffer * inbuf )
{
int connectedToSelf;
char * client;
const size_t sizeNeeded = HANDSHAKE_SIZE - PEER_ID_LEN;
if( EVBUFFER_LENGTH(inbuf) < sizeNeeded )
return READ_MORE;
/* peer id */
tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
handshake->havePeerID = TRUE;
client = tr_clientForId( handshake->peer_id );
dbgmsg( handshake, "peer-id is [%s]", client );
tr_free( client );
/* we've completed the BT handshake... pass the work on to peer-msgs */ /* we've completed the BT handshake... pass the work on to peer-msgs */
tr_handshakeDone( handshake, TRUE ); connectedToSelf = memcmp( handshake->peer_id, getPeerId(), PEER_ID_LEN ) != 0;
tr_handshakeDone( handshake, !connectedToSelf );
return READ_DONE; return READ_DONE;
} }
@ -901,24 +912,25 @@ dbgmsg( handshake, "sending handshake" );
static ReadState static ReadState
canRead( struct bufferevent * evin, void * arg ) canRead( struct bufferevent * evin, void * arg )
{ {
tr_handshake * handshake = (tr_handshake *) arg; tr_handshake * h = arg;
struct evbuffer * inbuf = EVBUFFER_INPUT ( evin ); struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
ReadState ret; ReadState ret;
dbgmsg( handshake, "handling canRead; state is [%s]", getStateName(handshake->state) ); dbgmsg( h, "handling canRead; state is [%s]", getStateName(h->state) );
switch( handshake->state ) switch( h->state )
{ {
case AWAITING_HANDSHAKE: ret = readHandshake ( handshake, inbuf ); break; case AWAITING_HANDSHAKE: ret = readHandshake ( h, inbuf ); break;
case AWAITING_YA: ret = readYa ( handshake, inbuf ); break; case AWAITING_PEER_ID: ret = readPeerId ( h, inbuf ); break;
case AWAITING_PAD_A: ret = readPadA ( handshake, inbuf ); break; case AWAITING_YA: ret = readYa ( h, inbuf ); break;
case AWAITING_CRYPTO_PROVIDE: ret = readCryptoProvide( handshake, inbuf ); break; case AWAITING_PAD_A: ret = readPadA ( h, inbuf ); break;
case AWAITING_PAD_C: ret = readPadC ( handshake, inbuf ); break; case AWAITING_CRYPTO_PROVIDE: ret = readCryptoProvide( h, inbuf ); break;
case AWAITING_IA: ret = readIA ( handshake, inbuf ); break; case AWAITING_PAD_C: ret = readPadC ( h, inbuf ); break;
case AWAITING_IA: ret = readIA ( h, inbuf ); break;
case AWAITING_YB: ret = readYb ( handshake, inbuf ); break; case AWAITING_YB: ret = readYb ( h, inbuf ); break;
case AWAITING_VC: ret = readVC ( handshake, inbuf ); break; case AWAITING_VC: ret = readVC ( h, inbuf ); break;
case AWAITING_CRYPTO_SELECT: ret = readCryptoSelect ( handshake, inbuf ); break; case AWAITING_CRYPTO_SELECT: ret = readCryptoSelect ( h, inbuf ); break;
case AWAITING_PAD_D: ret = readPadD ( handshake, inbuf ); break; case AWAITING_PAD_D: ret = readPadD ( h, inbuf ); break;
default: assert( 0 ); default: assert( 0 );
} }