X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdv%2Fgnunet-service-dv.c;h=84bdc11c23020c69c34710f043ee0140921206ff;hb=37defe2dbd9ea4e5a37710404e8046acbdf4a18e;hp=cd4517164f52942187d79d0e6a35ec656a0dbca9;hpb=61c39c60565b386e0e12ea669556b030e8cd7180;p=oweals%2Fgnunet.git diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index cd4517164..84bdc11c2 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c @@ -249,6 +249,16 @@ struct DirectNeighbor */ unsigned int pm_queue_size; + /** + * Elements in consensus + */ + unsigned int consensus_elements; + + /** + * Direct one hop route + */ + struct Route *direct_route; + /** * Flag set within 'check_target_removed' to trigger full global route refresh. */ @@ -684,9 +694,11 @@ get_consensus_slot (uint32_t distance) while ( (i < cs->array_length) && (NULL != cs->targets[i]) ) i++; if (i == cs->array_length) + { GNUNET_array_grow (cs->targets, cs->array_length, cs->array_length * 2 + 2); + } return i; } @@ -747,6 +759,11 @@ move_route (struct Route *route, * Initialize this neighbors 'my_set' and when done give * it to the pending set operation for execution. * + * Add a single element to the set per call: + * + * If we reached the last element of a consensus element: increase distance + * + * * @param cls the neighbor for which we are building the set */ static void @@ -754,15 +771,17 @@ build_set (void *cls) { struct DirectNeighbor *neighbor = cls; struct GNUNET_SET_Element element; - + struct Target *target; + target = NULL; while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) && (consensi[neighbor->consensus_insertion_distance].array_length == neighbor->consensus_insertion_offset) ) { + /* If we reached the last element of a consensus array element: increase distance and start with next array */ neighbor->consensus_insertion_offset = 0; neighbor->consensus_insertion_distance++; /* skip over NULL entries */ while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) && - (consensi[neighbor->consensus_insertion_distance].array_length < neighbor->consensus_insertion_offset) && + (consensi[neighbor->consensus_insertion_distance].array_length > neighbor->consensus_insertion_offset) && (NULL == consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]) ) neighbor->consensus_insertion_offset++; } @@ -770,28 +789,46 @@ build_set (void *cls) { /* we have added all elements to the set, run the operation */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finished building my SET, committing\n"); + "Finished building my SET for peer `%s' with %u elements, committing\n", + GNUNET_i2s(&neighbor->peer), + neighbor->consensus_elements); GNUNET_SET_commit (neighbor->set_op, neighbor->my_set); GNUNET_SET_destroy (neighbor->my_set); neighbor->my_set = NULL; return; } + + target = &consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]->target; element.size = sizeof (struct Target); element.type = htons (0); /* do we need this? */ - element.data = &consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset++]->target; + element.data = target; + /* Find next non-NULL entry */ + neighbor->consensus_insertion_offset++; /* skip over NULL entries */ while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) && - (consensi[neighbor->consensus_insertion_distance].array_length < neighbor->consensus_insertion_offset) && + (consensi[neighbor->consensus_insertion_distance].array_length > neighbor->consensus_insertion_offset) && (NULL == consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]) ) + { neighbor->consensus_insertion_offset++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Adding element to SET\n"); - GNUNET_SET_add_element (neighbor->my_set, - &element, - &build_set, neighbor); + } + if ( (0 != memcmp(&target->peer, &my_identity, sizeof (my_identity))) && + (0 != memcmp(&target->peer, &neighbor->peer, sizeof (neighbor->peer))) ) + { + /* Add target if it is not the neighbor or this peer */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Adding peer `%s' with distance %u to SET\n", + GNUNET_i2s (&target->peer), + ntohl (target->distance)); + GNUNET_SET_add_element (neighbor->my_set, + &element, + &build_set, neighbor); + neighbor->consensus_elements++; + } + else + build_set(neighbor); } @@ -822,6 +859,18 @@ handle_direct_connect (struct DirectNeighbor *neighbor) release_route (route); GNUNET_free (route); } + + neighbor->direct_route = GNUNET_new (struct Route); + neighbor->direct_route->next_hop = neighbor; + neighbor->direct_route->target.peer= neighbor->peer; + neighbor->direct_route->target.distance = DIRECT_NEIGHBOR_COST; + allocate_route (neighbor->direct_route, DIRECT_NEIGHBOR_COST); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Adding direct route to %s\n", + GNUNET_i2s (&neighbor->direct_route->target.peer)); + + /* construct session ID seed as XOR of both peer's identities */ GNUNET_CRYPTO_hash (&my_identity, sizeof (my_identity), &h1); GNUNET_CRYPTO_hash (&neighbor->peer, sizeof (struct GNUNET_PeerIdentity), &h2); @@ -838,18 +887,31 @@ handle_direct_connect (struct DirectNeighbor *neighbor) &my_identity, sizeof (struct GNUNET_PeerIdentity))) { - neighbor->initiate_task = GNUNET_SCHEDULER_add_now (&initiate_set_union, + if (NULL != neighbor->listen_handle) + { + GNUNET_break (0); + } + else + neighbor->initiate_task = GNUNET_SCHEDULER_add_now (&initiate_set_union, neighbor); } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting SET listen operation\n"); - neighbor->listen_handle = GNUNET_SET_listen (cfg, - GNUNET_SET_OPERATION_UNION, - &neighbor->real_session_id, - &listen_set_union, - neighbor); + if (NULL != neighbor->listen_handle) + { + GNUNET_break (0); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting SET listen operation with peer `%s'\n", + GNUNET_i2s(&neighbor->peer)); + neighbor->listen_handle = GNUNET_SET_listen (cfg, + GNUNET_SET_OPERATION_UNION, + &neighbor->real_session_id, + &listen_set_union, + neighbor); + } } } @@ -1061,6 +1123,14 @@ handle_direct_disconnect (struct DirectNeighbor *neighbor) GNUNET_CORE_notify_transmit_ready_cancel (neighbor->cth); neighbor->cth = NULL; } + + if (NULL != neighbor->direct_route) + { + release_route (neighbor->direct_route); + GNUNET_free (neighbor->direct_route); + neighbor->direct_route = NULL; + } + if (NULL != neighbor->neighbor_table_consensus) { GNUNET_CONTAINER_multipeermap_iterate (neighbor->neighbor_table_consensus, @@ -1127,10 +1197,11 @@ handle_ats_update (void *cls, if (GNUNET_NO == active) return; distance = get_atsi_distance (ats, ats_count); + /* GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS says distance to %s is %u\n", GNUNET_i2s (&address->peer), - (unsigned int) distance); + (unsigned int) distance);*/ /* check if entry exists */ neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, &address->peer); @@ -1302,10 +1373,32 @@ handle_set_union_result (void *cls, { struct DirectNeighbor *neighbor = cls; struct Target *target; + char *status_str; + + switch (status) { + case GNUNET_SET_STATUS_OK: + status_str = "GNUNET_SET_STATUS_OK"; + break; + case GNUNET_SET_STATUS_TIMEOUT: + status_str = "GNUNET_SET_STATUS_TIMEOUT"; + break; + case GNUNET_SET_STATUS_FAILURE: + status_str = "GNUNET_SET_STATUS_FAILURE"; + break; + case GNUNET_SET_STATUS_HALF_DONE: + status_str = "GNUNET_SET_STATUS_HALF_DONE"; + break; + case GNUNET_SET_STATUS_DONE: + status_str = "GNUNET_SET_STATUS_DONE"; + break; + default: + status_str = "UNDEFINED"; + break; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got SET union result: %d\n", - status); + "Got SET union result: %s\n", + status_str); switch (status) { case GNUNET_SET_STATUS_OK: @@ -1316,6 +1409,11 @@ handle_set_union_result (void *cls, } target = GNUNET_new (struct Target); memcpy (target, element->data, sizeof (struct Target)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received information about peer `%s' with distance %u\n", + GNUNET_i2s (&target->peer), ntohl(target->distance)); + if (NULL == neighbor->neighbor_table_consensus) + neighbor->neighbor_table_consensus = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_put (neighbor->neighbor_table_consensus, &target->peer, @@ -1347,34 +1445,38 @@ handle_set_union_result (void *cls, neighbor); break; case GNUNET_SET_STATUS_HALF_DONE: + break; + case GNUNET_SET_STATUS_DONE: /* we got all of our updates; integrate routing table! */ neighbor->target_removed = GNUNET_NO; - GNUNET_CONTAINER_multipeermap_iterate (neighbor->neighbor_table, - &check_target_removed, - neighbor); + if (NULL == neighbor->neighbor_table_consensus) + neighbor->neighbor_table_consensus = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); + if (NULL != neighbor->neighbor_table) + GNUNET_CONTAINER_multipeermap_iterate (neighbor->neighbor_table, + &check_target_removed, + neighbor); if (GNUNET_YES == neighbor->target_removed) { /* check if we got an alternative for the removed routes */ GNUNET_CONTAINER_multipeermap_iterate (direct_neighbors, - &refresh_routes, - NULL); + &refresh_routes, + NULL); } /* add targets that appeared (and check for improved routes) */ GNUNET_CONTAINER_multipeermap_iterate (neighbor->neighbor_table_consensus, - &check_target_added, - neighbor); + &check_target_added, + neighbor); if (NULL != neighbor->neighbor_table) { GNUNET_CONTAINER_multipeermap_iterate (neighbor->neighbor_table, - &free_targets, - NULL); + &free_targets, + NULL); GNUNET_CONTAINER_multipeermap_destroy (neighbor->neighbor_table); neighbor->neighbor_table = NULL; } neighbor->neighbor_table = neighbor->neighbor_table_consensus; neighbor->neighbor_table_consensus = NULL; - break; - case GNUNET_SET_STATUS_DONE: + /* operation done, schedule next run! */ neighbor->set_op = NULL; if (0 < memcmp (&neighbor->peer, @@ -1418,7 +1520,7 @@ listen_set_union (void *cls, if (NULL == request) return; /* why??? */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting to create consensus with %s!\n", + "Starting to create consensus with %s\n", GNUNET_i2s (&neighbor->peer)); if (NULL != neighbor->set_op) { @@ -1436,6 +1538,9 @@ listen_set_union (void *cls, GNUNET_SET_RESULT_ADDED, &handle_set_union_result, neighbor); + neighbor->consensus_insertion_offset = 0; + neighbor->consensus_insertion_distance = 0; + neighbor->consensus_elements = 0; build_set (neighbor); } @@ -1454,7 +1559,8 @@ initiate_set_union (void *cls, struct DirectNeighbor *neighbor = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Initiating SET union\n"); + "Initiating SET union with peer `%s'\n", + GNUNET_i2s (&neighbor->peer)); neighbor->initiate_task = GNUNET_SCHEDULER_NO_TASK; neighbor->my_set = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); @@ -1465,6 +1571,9 @@ initiate_set_union (void *cls, GNUNET_SET_RESULT_ADDED, &handle_set_union_result, neighbor); + neighbor->consensus_insertion_offset = 0; + neighbor->consensus_insertion_distance = 0; + neighbor->consensus_elements = 0; build_set (neighbor); } @@ -1667,6 +1776,7 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) neighbor->connected = GNUNET_NO; if (DIRECT_NEIGHBOR_COST == neighbor->distance) { + GNUNET_STATISTICS_update (stats, "# peers connected (1-hop)", -1, GNUNET_NO);