Changeset 12162


Ignore:
Timestamp:
Mar 14, 2011, 2:15:58 PM (11 years ago)
Author:
jordan
Message:

(trunk libT) #117 "UDP tracker protocol support (BEP #15)": (1) use the UDP tracker error response's error string (2) better handling of requests that timeout (3) better filtering of non-tracker UDP messages

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/announcer-udp.c

    r12159 r12162  
    115115    TAU_ACTION_ANNOUNCE = 1,
    116116    TAU_ACTION_SCRAPE   = 2,
    117     TAU_ACTION_ERROR    = 3,
    118 
    119     TAU_ACTION_MAX      = 3
     117    TAU_ACTION_ERROR    = 3
    120118}
    121119tau_action_t;
    122120
     121static tr_bool
     122is_tau_response_message( int action, int msglen )
     123{
     124    if( action == TAU_ACTION_CONNECT  ) return msglen == 16;
     125    if( action == TAU_ACTION_ANNOUNCE ) return msglen >= 20;
     126    if( action == TAU_ACTION_SCRAPE   ) return msglen >= 20;
     127    if( action == TAU_ACTION_ERROR    ) return msglen >= 8;
     128    return FALSE;
     129}
     130
    123131enum
    124132{
    125     TAU_REQUEST_TTL = 120
     133    TAU_REQUEST_TTL = 60
    126134};
    127135
     
    138146
    139147    time_t sent_at;
     148    time_t created_at;
    140149    tau_transaction_t transaction_id;
    141150
     
    152161    int i;
    153162    struct evbuffer * buf;
    154 
    155     struct tau_scrape_request * req = tr_new0( struct tau_scrape_request, 1 );
    156     req->transaction_id = tau_transaction_new( );
     163    struct tau_scrape_request * req;
     164    const tau_transaction_t transaction_id = tau_transaction_new( );
     165
     166    /* build the payload */
     167    buf = evbuffer_new( );
     168    evbuffer_add_hton_32( buf, TAU_ACTION_SCRAPE );
     169    evbuffer_add_hton_32( buf, transaction_id );
     170    for( i=0; i<in->info_hash_count; ++i )
     171        evbuffer_add( buf, in->info_hash[i], SHA_DIGEST_LENGTH );
     172
     173    /* build the tau_scrape_request */
     174    req = tr_new0( struct tau_scrape_request, 1 );
     175    req->created_at = tr_time( );
     176    req->transaction_id = transaction_id;
    157177    req->callback = callback;
    158178    req->user_data = user_data;
    159179    req->response.url = tr_strdup( in->url );
    160180    req->response.row_count = in->info_hash_count;
     181    req->payload_len = evbuffer_get_length( buf );
     182    req->payload = tr_memdup( evbuffer_pullup( buf, -1 ), req->payload_len );
    161183    for( i=0; i<req->response.row_count; ++i )
    162184        memcpy( req->response.rows[i].info_hash,
    163185                in->info_hash[i], SHA_DIGEST_LENGTH );
    164186
    165     /* build the payload */
    166     buf = evbuffer_new( );
    167     evbuffer_add_hton_32( buf, TAU_ACTION_SCRAPE );
    168     evbuffer_add_hton_32( buf, req->transaction_id );
    169     for( i=0; i<in->info_hash_count; ++i )
    170         evbuffer_add( buf, in->info_hash[i], SHA_DIGEST_LENGTH );
    171     req->payload_len = evbuffer_get_length( buf );
    172     req->payload = tr_memdup( evbuffer_pullup( buf, -1 ), req->payload_len );
     187    /* cleanup */
    173188    evbuffer_free( buf );
    174 
    175189    return req;
    176190}
     
    235249    else
    236250    {
    237         assert( action == TAU_ACTION_ERROR );
    238 
    239         tau_scrape_request_fail( session, request,
    240                                  TRUE, FALSE, _( "Unknown error" ) );
     251        char * errmsg;
     252        const size_t buflen = evbuffer_get_length( buf );
     253
     254        if( ( action == TAU_ACTION_ERROR ) && ( buflen > 0 ) )
     255            errmsg = tr_strndup( evbuffer_pullup( buf, -1 ), buflen );
     256        else
     257            errmsg = tr_strdup( _( "Unknown error" ) );
     258
     259        tau_scrape_request_fail( session, request, TRUE, FALSE, errmsg );
     260        tr_free( errmsg );
    241261    }
    242262}
     
    253273    size_t payload_len;
    254274
     275    time_t created_at;
    255276    time_t sent_at;
    256277    tau_transaction_t transaction_id;
     
    289310{
    290311    struct evbuffer * buf;
    291 
    292     struct tau_announce_request * r = tr_new0( struct tau_announce_request, 1 );
    293     r->transaction_id = tau_transaction_new( );
    294     r->callback = callback;
    295     r->user_data = user_data;
    296     memcpy( r->response.info_hash, in->info_hash, SHA_DIGEST_LENGTH );
    297 
    298     /* build the announce payload */
     312    struct tau_announce_request * req;
     313    const tau_transaction_t transaction_id = tau_transaction_new( );
     314
     315    /* build the payload */
    299316    buf = evbuffer_new( );
    300317    evbuffer_add_hton_32( buf, TAU_ACTION_ANNOUNCE );
    301     evbuffer_add_hton_32( buf, r->transaction_id );
     318    evbuffer_add_hton_32( buf, transaction_id );
    302319    evbuffer_add        ( buf, in->info_hash, SHA_DIGEST_LENGTH );
    303320    evbuffer_add        ( buf, in->peer_id, PEER_ID_LEN );
     
    310327    evbuffer_add_hton_32( buf, in->numwant );
    311328    evbuffer_add_hton_16( buf, in->port );
    312     r->payload_len = evbuffer_get_length( buf );
    313     r->payload = tr_memdup( evbuffer_pullup( buf, -1 ), r->payload_len );
     329
     330    /* build the tau_announce_request */
     331    req = tr_new0( struct tau_announce_request, 1 );
     332    req->created_at = tr_time( );
     333    req->transaction_id = transaction_id;
     334    req->callback = callback;
     335    req->user_data = user_data;
     336    req->payload_len = evbuffer_get_length( buf );
     337    req->payload = tr_memdup( evbuffer_pullup( buf, -1 ), req->payload_len );
     338    memcpy( req->response.info_hash, in->info_hash, SHA_DIGEST_LENGTH );
     339
    314340    evbuffer_free( buf );
    315 
    316     return r;
     341    return req;
    317342}
    318343
     
    374399    else
    375400    {
    376         assert( action == TAU_ACTION_ERROR );
    377 
    378         tau_announce_request_fail( session, request,
    379                                    TRUE, FALSE, _( "Unknown error" ) );
     401        char * errmsg;
     402        const size_t buflen = evbuffer_get_length( buf );
     403
     404        if( ( action == TAU_ACTION_ERROR ) && ( buflen > 0 ) )
     405            errmsg = tr_strndup( evbuffer_pullup( buf, -1 ), buflen );
     406        else
     407            errmsg = tr_strdup( _( "Unknown error" ) );
     408
     409        tau_announce_request_fail( session, request, TRUE, FALSE, errmsg );
     410        tr_free( errmsg );
    380411    }
    381412}
     
    471502        dbgmsg( tracker->key, "DNS lookup succeeded" );
    472503        tracker->addr = addr;
    473         tracker->addr_expiration_time = tr_time() + 1800;
     504        tracker->addr_expiration_time = tr_time() + (60*60); /* one hour */
    474505        tau_tracker_upkeep( tracker );
    475506    }
     
    477508
    478509static void
    479 tau_tracker_send_request( struct tau_tracker * tracker,
    480                           const void * payload,
    481                           size_t payload_len )
     510tau_tracker_send_request( struct tau_tracker  * tracker,
     511                          const void          * payload,
     512                          size_t                payload_len )
    482513{
    483514    struct evbuffer * buf = evbuffer_new( );
     
    558589            tau_tracker_send_request( tracker, req->payload, req->payload_len );
    559590        }
    560         else if( req->sent_at && ( req->sent_at + TAU_REQUEST_TTL < now ) ) {
     591        else if( req->created_at && ( req->created_at + TAU_REQUEST_TTL < now ) ) {
    561592            tau_announce_request_fail( tracker->session, req, FALSE, TRUE, NULL );
    562593            tau_announce_request_free( req );
     
    577608            tau_tracker_send_request( tracker, req->payload, req->payload_len );
    578609        }
    579         else if( req->sent_at && ( req->sent_at + TAU_REQUEST_TTL < now ) ) {
     610        else if( req->created_at && ( req->created_at + TAU_REQUEST_TTL < now ) ) {
    580611            tau_scrape_request_fail( tracker->session, req, FALSE, TRUE, NULL );
    581612            tau_scrape_request_free( req );
     
    715746    struct evbuffer * buf;
    716747
    717 /*fprintf( stderr, "got an incoming udp message w/len %zu\n", msglen );*/
     748    /*fprintf( stderr, "got an incoming udp message w/len %zu\n", msglen );*/
     749
    718750    if( !session || !session->announcer_udp )
    719751        return FALSE;
     
    721753        return FALSE;
    722754
    723     /* extract the action_id and transaction_id */
     755    /* extract the action_id and see if it makes sense */
    724756    buf = evbuffer_new( );
    725757    evbuffer_add_reference( buf, msg, msglen, NULL, NULL );
    726     action_id      = evbuffer_read_ntoh_32( buf );
    727     transaction_id = evbuffer_read_ntoh_32( buf );
    728 /*fprintf( stderr, "UDP got a transaction_id of %u...\n", transaction_id );*/
    729     if( action_id > TAU_ACTION_MAX ) {
     758    action_id = evbuffer_read_ntoh_32( buf );
     759    if( !is_tau_response_message( action_id, msglen ) ) {
    730760        evbuffer_free( buf );
    731761        return FALSE;
    732762    }
    733763
    734     /* look for a match to this transaction id */
     764    /* extract the transaction_id and look for a match */
    735765    tau = session->announcer_udp;
     766    transaction_id = evbuffer_read_ntoh_32( buf );
     767    /*fprintf( stderr, "UDP got a transaction_id of %u...\n", transaction_id );*/
    736768    for( i=0, n=tr_ptrArraySize( &tau->trackers ); i<n; ++i )
    737769    {
Note: See TracChangeset for help on using the changeset viewer.