/* This callback is called when a search result arrives or a search completes */ void dht_callback_func( void *closure, int event, const UCHAR *info_hash, const void *data, size_t data_len ) { struct results_t *results; IP addr; size_t i; results = results_find( info_hash ); if( results == NULL ) { return; } switch( event ) { case DHT_EVENT_VALUES: if( gconf->af == AF_INET ) { dht_addr4_t *data4 = (dht_addr4_t *) data; for( i = 0; i < (data_len / sizeof(dht_addr4_t)); i++ ) { to_addr( &addr, &data4[i].addr, 4, data4[i].port ); results_add_addr( results, &addr ); } } break; case DHT_EVENT_VALUES6: if( gconf->af == AF_INET6 ) { dht_addr6_t *data6 = (dht_addr6_t *) data; for( i = 0; i < (data_len / sizeof(dht_addr6_t)); i++ ) { to_addr( &addr, &data6[i].addr, 16, data6[i].port ); results_add_addr( results, &addr ); } } break; case DHT_EVENT_SEARCH_DONE: case DHT_EVENT_SEARCH_DONE6: results_done( results, 1 ); break; } }
/* * Lookup known nodes that are nearest to the given id. */ int kad_lookup_value( const char _query[], IP addr_array[], size_t *addr_num ) { char query[QUERY_MAX_SIZE]; struct results_t *results; int is_new; int rc; if( query_sanitize( query, sizeof(query), _query ) != 0 ) { return -2; } log_debug( "KAD: Lookup string: %s", query ); dht_lock(); /* Find existing or create new item */ results = results_add( query, &is_new ); if( results && is_new ) { /* Search own announced values */ kad_lookup_local_values( results ); } if( results == NULL ) { /* Failed to create a new search */ rc = -1; } else if( results->done ) { /* * The search exists already but has finished. Restart the search when * no results have been found or more than half of the searches lifetime * has expired. */ if( results_entries_count( results ) == 0 || (time_now_sec() - results->start_time) > (MAX_SEARCH_LIFETIME / 2) ) { /* Mark search as in progress */ results_done( results, 0 ); /* Start another search for this id */ dht_search( results->id, 0, gconf->af, dht_callback_func, NULL ); } rc = 2; } else if( is_new ) { /* Start a new DHT search */ dht_search( results->id, 0, gconf->af, dht_callback_func, NULL ); rc = 1; } else { /* Search is still running */ rc = 0; } /* Collect addresses to be returned */ *addr_num = results_collect( results, addr_array, *addr_num ); dht_unlock(); return rc; }
/* This callback is called when a search result arrives or a search completes */ void dht_callback_func( void *closure, int event, UCHAR *info_hash, void *data, size_t data_len ) { switch( event ) { case DHT_EVENT_VALUES: case DHT_EVENT_VALUES6: results_import( info_hash, data, data_len ); break; case DHT_EVENT_SEARCH_DONE: case DHT_EVENT_SEARCH_DONE6: results_done( info_hash ); break; } }