diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dv/dv_api.c | 6 | ||||
-rw-r--r-- | src/dv/gnunet-service-dv.c | 167 |
2 files changed, 125 insertions, 48 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c index 4cd072eb7f..5932c7459f 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c @@ -200,7 +200,7 @@ reconnect (struct GNUNET_DV_ServiceHandle *sh); /** * Gives a message from our queue to the DV service. * - * @param cls handle to the dv service (struct GNUNET_DV_ServiceHandle) + * @param cls handle to the dv service (`struct GNUNET_DV_ServiceHandle`) * @param size how many bytes can we send * @param buf where to copy the message to send * @return how many bytes we copied to @a buf @@ -228,6 +228,10 @@ transmit_pending (void *cls, size_t size, void *buf) sh->th_tail, th); memcpy (&cbuf[ret], th->msg, tsize); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Passing %u bytes of type %u to DV service\n", + tsize, + ntohs (th->msg->type)); th->msg = NULL; ret += tsize; if (NULL != th->cb) diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 4d88d10797..5a1e0b274d 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c @@ -97,7 +97,7 @@ struct Target struct RouteMessage { /** - * Type: GNUNET_MESSAGE_TYPE_DV_ROUTE + * Type: #GNUNET_MESSAGE_TYPE_DV_ROUTE */ struct GNUNET_MessageHeader header; @@ -938,7 +938,7 @@ handle_direct_connect (struct DirectNeighbor *neighbor) } else neighbor->initiate_task = GNUNET_SCHEDULER_add_now (&initiate_set_union, - neighbor); + neighbor); } else { @@ -1028,6 +1028,33 @@ free_targets (void *cls, /** + * Add a new route to the given @a target via the given @a neighbor. + * + * @param target the target of the route + * @param neighbor the next hop for communicating with the @a target + */ +static void +add_new_route (struct Target *target, + struct DirectNeighbor *neighbor) +{ + struct Route *route; + + route = GNUNET_new (struct Route); + route->next_hop = neighbor; + route->target.peer = target->peer; + allocate_route (route, ntohl (target->distance) + 1); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multipeermap_put (all_routes, + &route->target.peer, + route, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + send_connect_to_plugin (&route->target.peer, + ntohl (route->target.distance), + neighbor->network); +} + + +/** * Multipeerhmap iterator for checking if a given route is * (now) useful to this peer. * @@ -1068,18 +1095,7 @@ check_possible_route (void *cls, } if (ntohl (target->distance) >= DEFAULT_FISHEYE_DEPTH) return GNUNET_YES; /* distance is too large to be interesting */ - route = GNUNET_new (struct Route); - route->next_hop = neighbor; - route->target.peer = target->peer; - allocate_route (route, ntohl (target->distance) + 1); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multipeermap_put (all_routes, - &route->target.peer, - route, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - send_connect_to_plugin (&route->target.peer, - ntohl (route->target.distance), - neighbor->network); + add_new_route (target, neighbor); return GNUNET_YES; } @@ -1525,25 +1541,26 @@ handle_set_union_result (void *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; + 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, @@ -1757,6 +1774,7 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *payload; struct Route *route; struct DirectNeighbor *neighbor; + struct Target *target; uint32_t distance; char me[5]; char src[5]; @@ -1775,9 +1793,10 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, strncpy (dst, GNUNET_i2s (&rm->target), 4); prev[4] = me[4] = src[4] = dst[4] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Handling DV message from %s to %s routed by %s to me (%s)\n", + "Handling DV message from %s to %s routed by %s to me (%s @ %u)\n", src, dst, - prev, me); + prev, me, + (unsigned int) ntohl (rm->distance)); payload = (const struct GNUNET_MessageHeader *) &rm[1]; if (ntohs (message->size) != sizeof (struct RouteMessage) + ntohs (payload->size)) @@ -1792,17 +1811,38 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, /* message is for me, check reverse route! */ route = GNUNET_CONTAINER_multipeermap_get (all_routes, &rm->sender); - if (NULL == route) + if ( (NULL == route) && + (NULL == GNUNET_CONTAINER_multipeermap_get (direct_neighbors, + &rm->sender)) && + (ntohs (rm->distance) < DEFAULT_FISHEYE_DEPTH) ) { - /* don't have reverse route, drop */ + /* don't have reverse route yet, learn it! */ + neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, + peer); + if (NULL == neighbor) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + target = GNUNET_new (struct Target); + target->peer = rm->sender; + target->distance = htonl (ntohl (rm->distance)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No reverse route to %s, dropping %u bytes!\n", + "Learning target %s at distance %u from delivery!\n", GNUNET_i2s (&rm->sender), - ntohs (payload->size)); - GNUNET_STATISTICS_update (stats, - "# message discarded (no reverse route)", - 1, GNUNET_NO); - return GNUNET_OK; + 1 + ntohs (rm->distance)); + if (NULL == neighbor->neighbor_table) + neighbor->neighbor_table = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); + if (GNUNET_YES != + GNUNET_CONTAINER_multipeermap_put (neighbor->neighbor_table, + &target->peer, + target, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + GNUNET_break_op (0); + GNUNET_free (target); + } + add_new_route (target, neighbor); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delivering %u bytes to myself!\n", @@ -1812,6 +1852,39 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, ntohl (route->target.distance)); return GNUNET_OK; } + if ( (NULL == GNUNET_CONTAINER_multipeermap_get (direct_neighbors, + &rm->sender)) && + (NULL == GNUNET_CONTAINER_multipeermap_get (all_routes, + &rm->sender)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Learning target %s at distance %u from forwarding!\n", + GNUNET_i2s (&rm->sender), + 1 + ntohs (rm->distance)); + neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, + peer); + if (NULL == neighbor) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + target = GNUNET_new (struct Target); + target->peer = rm->sender; + target->distance = htonl (ntohl (rm->distance)); + if (NULL == neighbor->neighbor_table) + neighbor->neighbor_table = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); + if (GNUNET_YES != + GNUNET_CONTAINER_multipeermap_put (neighbor->neighbor_table, + &target->peer, + target, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + GNUNET_break_op (0); + GNUNET_free (target); + } + add_new_route (target, neighbor); + } + route = GNUNET_CONTAINER_multipeermap_get (all_routes, &rm->target); if (NULL == route) @@ -2081,9 +2154,9 @@ shutdown_task (void *cls, * @return #GNUNET_OK (continue to iterate) */ static int -add_route (void *cls, - const struct GNUNET_PeerIdentity *key, - void *value) +notify_client_about_route (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { struct GNUNET_SERVER_Client *client = cls; struct Route *route = value; @@ -2118,7 +2191,7 @@ handle_start (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_notification_context_add (nc, client); GNUNET_SERVER_receive_done (client, GNUNET_OK); GNUNET_CONTAINER_multipeermap_iterate (all_routes, - &add_route, + ¬ify_client_about_route, client); } |