Changeset 6791


Ignore:
Timestamp:
Sep 19, 2008, 5:03:25 PM (13 years ago)
Author:
charles
Message:

fix at least one possible cause for the new crash reported by persept

Location:
trunk/libtransmission
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/handshake.c

    r6782 r6791  
    195195}
    196196
    197 static void
     197static int
    198198tr_handshakeDone( tr_handshake * handshake, int isConnected );
    199199
     
    217217
    218218    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
    219         return READ_MORE;
     219        return READ_LATER;
    220220
    221221    /* confirm the protocol */
     
    362362
    363363    if( EVBUFFER_LENGTH(inbuf) < needlen )
    364         return READ_MORE;
     364        return READ_LATER;
    365365
    366366    isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
     
    368368        needlen = KEY_LEN;
    369369        if( EVBUFFER_LENGTH(inbuf) < needlen )
    370             return READ_MORE;
     370            return READ_LATER;
    371371    }
    372372
     
    377377    if( !isEncrypted ) {
    378378        setState( handshake, AWAITING_HANDSHAKE );
    379         return READ_AGAIN;
     379        return READ_NOW;
    380380    }
    381381
     
    442442    /* cleanup */
    443443    evbuffer_free( outbuf );
    444     return READ_DONE;
     444    return READ_LATER;
    445445}
    446446
     
    459459        if( EVBUFFER_LENGTH(inbuf) < VC_LENGTH ) {
    460460            dbgmsg( handshake, "not enough bytes... returning read_more" );
    461             return READ_MORE;
     461            return READ_LATER;
    462462        }
    463463
     
    474474    evbuffer_drain( inbuf, key_len );
    475475    setState( handshake, AWAITING_CRYPTO_SELECT );
    476     return READ_AGAIN;
     476    return READ_NOW;
    477477}
    478478
     
    485485
    486486    if( EVBUFFER_LENGTH(inbuf) < needlen )
    487         return READ_MORE;
     487        return READ_LATER;
    488488
    489489    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_select );
     
    493493    {
    494494        dbgmsg( handshake, "peer selected an encryption option we didn't provide" );
    495         tr_handshakeDone( handshake, FALSE );
    496         return READ_DONE;
     495        return tr_handshakeDone( handshake, FALSE );
    497496    }
    498497
     
    503502    {
    504503        dbgmsg( handshake, "encryption handshake: pad_d_len is too long" );
    505         tr_handshakeDone( handshake, FALSE );
    506         return READ_DONE;
     504        return tr_handshakeDone( handshake, FALSE );
    507505    }
    508506
     
    510508
    511509    setState( handshake, AWAITING_PAD_D );
    512     return READ_AGAIN;
     510    return READ_NOW;
    513511}
    514512
     
    521519    dbgmsg( handshake, "pad d: need %d, got %d", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );
    522520    if( EVBUFFER_LENGTH(inbuf) < needlen )
    523         return READ_MORE;
     521        return READ_LATER;
    524522
    525523    tmp = tr_new( uint8_t, needlen );
     
    531529
    532530    setState( handshake, AWAITING_HANDSHAKE );
    533     return READ_AGAIN;
     531    return READ_NOW;
    534532}
    535533
     
    551549
    552550    if( EVBUFFER_LENGTH(inbuf) < INCOMING_HANDSHAKE_LEN )
    553         return READ_MORE;
     551        return READ_LATER;
    554552
    555553    pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read.  We may be
     
    563561        {
    564562            dbgmsg( handshake, "peer is unencrypted, and we're disallowing that" );
    565             tr_handshakeDone( handshake, FALSE );
    566             return READ_DONE;
     563            return tr_handshakeDone( handshake, FALSE );
    567564        }
    568565    }
     
    575572            dbgmsg( handshake, "I think peer is sending us an encrypted handshake..." );
    576573            setState( handshake, AWAITING_YA );
    577             return READ_AGAIN;
     574            return READ_NOW;
    578575        }
    579576        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
     
    582579        {
    583580            dbgmsg( handshake, "I think peer has sent us a corrupt handshake..." );
    584             tr_handshakeDone( handshake, FALSE );
    585             return READ_DONE;
     581            return tr_handshakeDone( handshake, FALSE );
    586582        }
    587583    }
     
    595591    if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) {
    596592        tr_free( pstr );
    597         tr_handshakeDone( handshake, FALSE );
    598         return READ_DONE;
     593        return tr_handshakeDone( handshake, FALSE );
    599594    }
    600595    tr_free( pstr );
     
    625620        {
    626621            dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." );
    627             tr_handshakeDone( handshake, FALSE );
    628             return READ_DONE;
     622            return tr_handshakeDone( handshake, FALSE );
    629623        }
    630624        else
     
    640634        {
    641635            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
    642             tr_handshakeDone( handshake, FALSE );
    643             return READ_DONE;
     636            return tr_handshakeDone( handshake, FALSE );
    644637        }
    645638    }
     
    659652
    660653    setReadState( handshake, AWAITING_PEER_ID );
    661     return READ_AGAIN;
     654    return READ_NOW;
    662655}
    663656
     
    669662
    670663    if( EVBUFFER_LENGTH(inbuf) < PEER_ID_LEN )
    671         return READ_MORE;
     664        return READ_LATER;
    672665
    673666    /* peer id */
     
    681674    peerIsGood = memcmp( handshake->peer_id, tr_getPeerId(), PEER_ID_LEN ) ? 1 : 0;
    682675    dbgmsg( handshake, "isPeerGood == %d", peerIsGood );
    683     tr_handshakeDone( handshake, peerIsGood );
    684     return READ_DONE;
     676    return tr_handshakeDone( handshake, peerIsGood );
    685677}
    686678
     
    695687dbgmsg( handshake, "in readYa... need %d, have %d", (int)KEY_LEN, (int)EVBUFFER_LENGTH( inbuf ) );
    696688    if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )
    697         return READ_MORE;
     689        return READ_LATER;
    698690
    699691    /* read the incoming peer's public key */
     
    715707    setReadState( handshake, AWAITING_PAD_A );
    716708    tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );
    717     return READ_AGAIN;
     709    return READ_NOW;
    718710}
    719711
     
    734726        dbgmsg( handshake, "no luck so far.. draining %d bytes", (int)EVBUFFER_LENGTH(inbuf) );
    735727        evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );
    736         return READ_MORE;
     728        return READ_LATER;
    737729    }
    738730    dbgmsg( handshake, "looking for hash('req',S) ... draining %d bytes", (int)(pch-EVBUFFER_DATA(inbuf)) );
    739731    evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );
    740732    if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )
    741         return READ_MORE;
     733        return READ_LATER;
    742734    if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {
    743735        dbgmsg( handshake, "draining one more byte" );
    744736        evbuffer_drain( inbuf, 1 );
    745         return READ_AGAIN;
     737        return READ_NOW;
    746738    }
    747739
    748740dbgmsg( handshake, "found it... looking setting to awaiting_crypto_provide" );
    749741    setState( handshake, AWAITING_CRYPTO_PROVIDE );
    750     return READ_AGAIN;
     742    return READ_NOW;
    751743}
    752744
     
    771763
    772764    if( EVBUFFER_LENGTH(inbuf) < needlen )
    773         return READ_MORE;
     765        return READ_LATER;
    774766
    775767    /* TODO: confirm they sent HASH('req1',S) here? */
     
    794786        {
    795787            dbgmsg( handshake, "a peer has tried to reconnect to us!" );
    796             tr_handshakeDone( handshake, FALSE );
    797             return READ_DONE;
     788            return tr_handshakeDone( handshake, FALSE );
    798789        }
    799790    }
     
    801792    {
    802793        dbgmsg( handshake, "can't find that torrent..." );
    803         tr_handshakeDone( handshake, FALSE );
    804         return READ_DONE;
     794        return tr_handshakeDone( handshake, FALSE );
    805795    }
    806796
     
    819809    handshake->pad_c_len = padc_len;
    820810    setState( handshake, AWAITING_PAD_C );
    821     return READ_AGAIN;
     811    return READ_NOW;
    822812}
    823813
     
    829819
    830820    if( EVBUFFER_LENGTH(inbuf) < needlen )
    831         return READ_MORE;
     821        return READ_LATER;
    832822
    833823    evbuffer_drain( inbuf, handshake->pad_c_len );
     
    837827    handshake->ia_len = ia_len;
    838828    setState( handshake, AWAITING_IA );
    839     return READ_AGAIN;
     829    return READ_NOW;
    840830}
    841831
     
    850840dbgmsg( handshake, "reading IA... have %d, need %d", (int)EVBUFFER_LENGTH(inbuf), (int)needlen );
    851841    if( EVBUFFER_LENGTH(inbuf) < needlen )
    852         return READ_MORE;
     842        return READ_LATER;
    853843
    854844dbgmsg( handshake, "reading IA..." );
     
    856846    i = parseHandshake( handshake, inbuf );
    857847dbgmsg( handshake, "parseHandshake returned %d", i );
    858     if( i != HANDSHAKE_OK ) {
    859         tr_handshakeDone( handshake, FALSE );
    860         return READ_DONE;
    861     }
     848    if( i != HANDSHAKE_OK )
     849        return tr_handshakeDone( handshake, FALSE );
    862850
    863851    /**
     
    884872        dbgmsg( handshake, "peer didn't offer an encryption mode we like." );
    885873        evbuffer_free( outbuf );
    886         tr_handshakeDone( handshake, FALSE );
    887         return READ_DONE;
     874        return tr_handshakeDone( handshake, FALSE );
    888875    }
    889876
     
    916903
    917904    /* we've completed the BT handshake... pass the work on to peer-msgs */
    918     tr_handshakeDone( handshake, TRUE );
    919     return READ_DONE;
     905    return tr_handshakeDone( handshake, TRUE );
    920906}
    921907
     
    955941}
    956942
    957 static void
     943static int
    958944fireDoneFunc( tr_handshake * handshake, int isConnected )
    959945{
     
    961947        ? handshake->peer_id
    962948        : NULL;
    963     (*handshake->doneCB)( handshake,
    964                           handshake->io,
    965                           isConnected,
    966                           peer_id,
    967                           handshake->doneUserData );
    968 }
    969 
    970 static void
     949    const int success = (*handshake->doneCB)( handshake,
     950                                              handshake->io,
     951                                              isConnected,
     952                                              peer_id,
     953                                              handshake->doneUserData );
     954    return success;
     955}
     956
     957static int
    971958tr_handshakeDone( tr_handshake * handshake, int isOK )
    972959{
     960    int success;
     961
    973962    dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" );
    974963    tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
    975964
    976     fireDoneFunc( handshake, isOK );
     965    success = fireDoneFunc( handshake, isOK );
    977966
    978967    tr_free( handshake );
     968
     969    return success ? READ_LATER : READ_ERR;
    979970}
    980971
  • trunk/libtransmission/handshake.h

    r6782 r6791  
    2020typedef struct tr_handshake tr_handshake;
    2121
    22 typedef void (*handshakeDoneCB)(struct tr_handshake * handshake,
    23                                 struct tr_peerIo    * io,
    24                                 int                   isConnected,
    25                                 const uint8_t       * peerId,
    26                                 void                * userData );
     22/* returns true on success, false on error */
     23typedef int (*handshakeDoneCB)(struct tr_handshake * handshake,
     24                               struct tr_peerIo    * io,
     25                               int                   isConnected,
     26                               const uint8_t       * peerId,
     27                               void                * userData );
    2728
    2829tr_handshake *  tr_handshakeNew( struct tr_peerIo   * io,
  • trunk/libtransmission/peer-io.c

    r6782 r6791  
    192192{
    193193    int done = 0;
     194    int err = 0;
    194195    tr_peerIo * io = vio;
    195196    tr_session * session = io->session;
     
    217218        tr_globalLock( session );
    218219
    219         while( !done )
     220        while( !done && !err )
    220221        {
    221222            const int ret = io->canRead( e, io->userData );
     
    223224            switch( ret )
    224225            {
    225                 case READ_AGAIN:
     226                case READ_NOW:
    226227                    if( EVBUFFER_LENGTH( e->input ) )
    227228                        continue;
    228                 case READ_MORE:
    229                 case READ_DONE:
    230229                    done = 1;
     230                    break;
     231                case READ_LATER:
     232                    done = 1;
     233                    break;
     234                case READ_ERR:
     235                    err = 1;
     236                    break;
    231237            }
    232238        }
     
    235241    }
    236242
    237     io->bufferSize[TR_DOWN] = EVBUFFER_LENGTH( EVBUFFER_INPUT( e ) );
     243    if( !err )
     244        io->bufferSize[TR_DOWN] = EVBUFFER_LENGTH( EVBUFFER_INPUT( e ) );
    238245}
    239246
  • trunk/libtransmission/peer-io.h

    r6782 r6791  
    9999**/
    100100
    101 typedef enum { READ_MORE, READ_AGAIN, READ_DONE } ReadState;
     101typedef enum
     102{
     103    READ_NOW,
     104    READ_LATER,
     105    READ_ERR
     106}
     107ReadState;
     108
    102109typedef ReadState (*tr_can_read_cb)(struct bufferevent*, void* user_data);
    103110typedef void (*tr_did_write_cb)(struct bufferevent *, void *);
  • trunk/libtransmission/peer-mgr.c

    r6784 r6791  
    950950
    951951/* FIXME: this is kind of a mess. */
    952 static void
     952static int
    953953myHandshakeDoneCB( tr_handshake    * handshake,
    954954                   tr_peerIo       * io,
     
    958958{
    959959    int ok = isConnected;
     960    int success = FALSE;
    960961    uint16_t port;
    961962    const struct in_addr * addr;
     
    10391040                peer->io = io;
    10401041                peer->msgs = tr_peerMsgsNew( t->tor, peer, peerCallbackFunc, t, &peer->msgsTag );
     1042
     1043                success = TRUE;
    10411044            }
    10421045        }
     
    10451048    if( t )
    10461049        torrentUnlock( t );
     1050
     1051    return success;
    10471052}
    10481053
  • trunk/libtransmission/peer-msgs.c

    r6782 r6791  
    10941094
    10951095    if( inlen < sizeof(len) )
    1096         return READ_MORE;
     1096        return READ_LATER;
    10971097
    10981098    tr_peerIoReadUint32( msgs->io, inbuf, &len );
     
    11051105    }
    11061106
    1107     return READ_AGAIN;
     1107    return READ_NOW;
    11081108}
    11091109
     
    11171117
    11181118    if( inlen < sizeof(uint8_t) )
    1119         return READ_MORE;
     1119        return READ_LATER;
    11201120
    11211121    tr_peerIoReadUint8( msgs->io, inbuf, &id );
     
    11251125    {
    11261126        msgs->state = AWAITING_BT_PIECE;
    1127         return READ_AGAIN;
     1127        return READ_NOW;
    11281128    }
    11291129    else if( msgs->incoming.length != 1 )
    11301130    {
    11311131        msgs->state = AWAITING_BT_MESSAGE;
    1132         return READ_AGAIN;
     1132        return READ_NOW;
    11331133    }
    11341134    else return readBtMessage( msgs, inbuf, inlen-1 );
     
    12581258    {
    12591259        if( inlen < 8 )
    1260             return READ_MORE;
     1260            return READ_LATER;
    12611261
    12621262        tr_peerIoReadUint32( msgs->io, inbuf, &req->index );
     
    12641264        req->length = msgs->incoming.length - 9;
    12651265        dbgmsg( msgs, "got incoming block header %u:%u->%u", req->index, req->offset, req->length );
    1266         return READ_AGAIN;
     1266        return READ_NOW;
    12671267    }
    12681268    else
     
    12831283               (int)( req->length - EVBUFFER_LENGTH(msgs->incoming.block) ) );
    12841284        if( EVBUFFER_LENGTH(msgs->incoming.block) < req->length )
    1285             return READ_MORE;
     1285            return READ_LATER;
    12861286
    12871287        /* we've got the whole block ... process it */
     
    12931293        msgs->state = AWAITING_BT_LENGTH;
    12941294        if( !err )
    1295             return READ_AGAIN;
     1295            return READ_NOW;
    12961296        else {
    12971297            fireError( msgs, err );
    1298             return READ_DONE;
     1298            return READ_ERR;
    12991299        }
    13001300    }
     
    13121312
    13131313    if( inlen < msglen )
    1314         return READ_MORE;
     1314        return READ_LATER;
    13151315
    13161316    dbgmsg( msgs, "got BT id %d, len %d, buffer size is %d", (int)id, (int)msglen, (int)inlen );
     
    13201320        dbgmsg( msgs, "bad packet - BT message #%d with a length of %d", (int)id, (int)msglen );
    13211321        fireError( msgs, TR_ERROR );
    1322         return READ_DONE;
     1322        return READ_ERR;
    13231323    }
    13241324
     
    14511451
    14521452    msgs->state = AWAITING_BT_LENGTH;
    1453     return READ_AGAIN;
     1453    return READ_NOW;
    14541454}
    14551455
     
    15511551    if( !inlen )
    15521552    {
    1553         ret = READ_DONE;
     1553        ret = READ_LATER;
    15541554    }
    15551555    else if( msgs->state == AWAITING_BT_PIECE )
    15561556    {
    1557         ret = inlen ? readBtPiece( msgs, in, inlen ) : READ_DONE;
     1557        ret = inlen ? readBtPiece( msgs, in, inlen ) : READ_LATER;
    15581558    }
    15591559    else switch( msgs->state )
  • trunk/libtransmission/verify.h

    r5126 r6791  
    88 * the Transmission project.
    99 *
    10  * $Id:$
     10 * $Id$
    1111 */
    1212
Note: See TracChangeset for help on using the changeset viewer.