diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-12-18 14:29:56 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-12-18 14:29:56 +0000 |
commit | bcc375bf6c191efd5243ff21e274d261354d99a4 (patch) | |
tree | e725b75240af320db072818182c972463e2f09ba | |
parent | 920f6c8c466a11852d1bd7298e3f76deda69b6f3 (diff) | |
download | gnunet-bcc375bf6c191efd5243ff21e274d261354d99a4.tar.gz gnunet-bcc375bf6c191efd5243ff21e274d261354d99a4.zip |
-learn routes from forwarding/receiving as well
-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 4cd072eb7..5932c7459 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c | |||
@@ -200,7 +200,7 @@ reconnect (struct GNUNET_DV_ServiceHandle *sh); | |||
200 | /** | 200 | /** |
201 | * Gives a message from our queue to the DV service. | 201 | * Gives a message from our queue to the DV service. |
202 | * | 202 | * |
203 | * @param cls handle to the dv service (struct GNUNET_DV_ServiceHandle) | 203 | * @param cls handle to the dv service (`struct GNUNET_DV_ServiceHandle`) |
204 | * @param size how many bytes can we send | 204 | * @param size how many bytes can we send |
205 | * @param buf where to copy the message to send | 205 | * @param buf where to copy the message to send |
206 | * @return how many bytes we copied to @a buf | 206 | * @return how many bytes we copied to @a buf |
@@ -228,6 +228,10 @@ transmit_pending (void *cls, size_t size, void *buf) | |||
228 | sh->th_tail, | 228 | sh->th_tail, |
229 | th); | 229 | th); |
230 | memcpy (&cbuf[ret], th->msg, tsize); | 230 | memcpy (&cbuf[ret], th->msg, tsize); |
231 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
232 | "Passing %u bytes of type %u to DV service\n", | ||
233 | tsize, | ||
234 | ntohs (th->msg->type)); | ||
231 | th->msg = NULL; | 235 | th->msg = NULL; |
232 | ret += tsize; | 236 | ret += tsize; |
233 | if (NULL != th->cb) | 237 | if (NULL != th->cb) |
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 4d88d1079..5a1e0b274 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c | |||
@@ -97,7 +97,7 @@ struct Target | |||
97 | struct RouteMessage | 97 | struct RouteMessage |
98 | { | 98 | { |
99 | /** | 99 | /** |
100 | * Type: GNUNET_MESSAGE_TYPE_DV_ROUTE | 100 | * Type: #GNUNET_MESSAGE_TYPE_DV_ROUTE |
101 | */ | 101 | */ |
102 | struct GNUNET_MessageHeader header; | 102 | struct GNUNET_MessageHeader header; |
103 | 103 | ||
@@ -938,7 +938,7 @@ handle_direct_connect (struct DirectNeighbor *neighbor) | |||
938 | } | 938 | } |
939 | else | 939 | else |
940 | neighbor->initiate_task = GNUNET_SCHEDULER_add_now (&initiate_set_union, | 940 | neighbor->initiate_task = GNUNET_SCHEDULER_add_now (&initiate_set_union, |
941 | neighbor); | 941 | neighbor); |
942 | } | 942 | } |
943 | else | 943 | else |
944 | { | 944 | { |
@@ -1028,6 +1028,33 @@ free_targets (void *cls, | |||
1028 | 1028 | ||
1029 | 1029 | ||
1030 | /** | 1030 | /** |
1031 | * Add a new route to the given @a target via the given @a neighbor. | ||
1032 | * | ||
1033 | * @param target the target of the route | ||
1034 | * @param neighbor the next hop for communicating with the @a target | ||
1035 | */ | ||
1036 | static void | ||
1037 | add_new_route (struct Target *target, | ||
1038 | struct DirectNeighbor *neighbor) | ||
1039 | { | ||
1040 | struct Route *route; | ||
1041 | |||
1042 | route = GNUNET_new (struct Route); | ||
1043 | route->next_hop = neighbor; | ||
1044 | route->target.peer = target->peer; | ||
1045 | allocate_route (route, ntohl (target->distance) + 1); | ||
1046 | GNUNET_assert (GNUNET_YES == | ||
1047 | GNUNET_CONTAINER_multipeermap_put (all_routes, | ||
1048 | &route->target.peer, | ||
1049 | route, | ||
1050 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1051 | send_connect_to_plugin (&route->target.peer, | ||
1052 | ntohl (route->target.distance), | ||
1053 | neighbor->network); | ||
1054 | } | ||
1055 | |||
1056 | |||
1057 | /** | ||
1031 | * Multipeerhmap iterator for checking if a given route is | 1058 | * Multipeerhmap iterator for checking if a given route is |
1032 | * (now) useful to this peer. | 1059 | * (now) useful to this peer. |
1033 | * | 1060 | * |
@@ -1068,18 +1095,7 @@ check_possible_route (void *cls, | |||
1068 | } | 1095 | } |
1069 | if (ntohl (target->distance) >= DEFAULT_FISHEYE_DEPTH) | 1096 | if (ntohl (target->distance) >= DEFAULT_FISHEYE_DEPTH) |
1070 | return GNUNET_YES; /* distance is too large to be interesting */ | 1097 | return GNUNET_YES; /* distance is too large to be interesting */ |
1071 | route = GNUNET_new (struct Route); | 1098 | add_new_route (target, neighbor); |
1072 | route->next_hop = neighbor; | ||
1073 | route->target.peer = target->peer; | ||
1074 | allocate_route (route, ntohl (target->distance) + 1); | ||
1075 | GNUNET_assert (GNUNET_YES == | ||
1076 | GNUNET_CONTAINER_multipeermap_put (all_routes, | ||
1077 | &route->target.peer, | ||
1078 | route, | ||
1079 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1080 | send_connect_to_plugin (&route->target.peer, | ||
1081 | ntohl (route->target.distance), | ||
1082 | neighbor->network); | ||
1083 | return GNUNET_YES; | 1099 | return GNUNET_YES; |
1084 | } | 1100 | } |
1085 | 1101 | ||
@@ -1525,25 +1541,26 @@ handle_set_union_result (void *cls, | |||
1525 | struct Target *target; | 1541 | struct Target *target; |
1526 | char *status_str; | 1542 | char *status_str; |
1527 | 1543 | ||
1528 | switch (status) { | 1544 | switch (status) |
1529 | case GNUNET_SET_STATUS_OK: | 1545 | { |
1530 | status_str = "GNUNET_SET_STATUS_OK"; | 1546 | case GNUNET_SET_STATUS_OK: |
1531 | break; | 1547 | status_str = "GNUNET_SET_STATUS_OK"; |
1532 | case GNUNET_SET_STATUS_TIMEOUT: | 1548 | break; |
1533 | status_str = "GNUNET_SET_STATUS_TIMEOUT"; | 1549 | case GNUNET_SET_STATUS_TIMEOUT: |
1534 | break; | 1550 | status_str = "GNUNET_SET_STATUS_TIMEOUT"; |
1535 | case GNUNET_SET_STATUS_FAILURE: | 1551 | break; |
1536 | status_str = "GNUNET_SET_STATUS_FAILURE"; | 1552 | case GNUNET_SET_STATUS_FAILURE: |
1537 | break; | 1553 | status_str = "GNUNET_SET_STATUS_FAILURE"; |
1538 | case GNUNET_SET_STATUS_HALF_DONE: | 1554 | break; |
1539 | status_str = "GNUNET_SET_STATUS_HALF_DONE"; | 1555 | case GNUNET_SET_STATUS_HALF_DONE: |
1540 | break; | 1556 | status_str = "GNUNET_SET_STATUS_HALF_DONE"; |
1541 | case GNUNET_SET_STATUS_DONE: | 1557 | break; |
1542 | status_str = "GNUNET_SET_STATUS_DONE"; | 1558 | case GNUNET_SET_STATUS_DONE: |
1543 | break; | 1559 | status_str = "GNUNET_SET_STATUS_DONE"; |
1544 | default: | 1560 | break; |
1545 | status_str = "UNDEFINED"; | 1561 | default: |
1546 | break; | 1562 | status_str = "UNDEFINED"; |
1563 | break; | ||
1547 | } | 1564 | } |
1548 | 1565 | ||
1549 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1566 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1757,6 +1774,7 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1757 | const struct GNUNET_MessageHeader *payload; | 1774 | const struct GNUNET_MessageHeader *payload; |
1758 | struct Route *route; | 1775 | struct Route *route; |
1759 | struct DirectNeighbor *neighbor; | 1776 | struct DirectNeighbor *neighbor; |
1777 | struct Target *target; | ||
1760 | uint32_t distance; | 1778 | uint32_t distance; |
1761 | char me[5]; | 1779 | char me[5]; |
1762 | char src[5]; | 1780 | char src[5]; |
@@ -1775,9 +1793,10 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1775 | strncpy (dst, GNUNET_i2s (&rm->target), 4); | 1793 | strncpy (dst, GNUNET_i2s (&rm->target), 4); |
1776 | prev[4] = me[4] = src[4] = dst[4] = '\0'; | 1794 | prev[4] = me[4] = src[4] = dst[4] = '\0'; |
1777 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1795 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1778 | "Handling DV message from %s to %s routed by %s to me (%s)\n", | 1796 | "Handling DV message from %s to %s routed by %s to me (%s @ %u)\n", |
1779 | src, dst, | 1797 | src, dst, |
1780 | prev, me); | 1798 | prev, me, |
1799 | (unsigned int) ntohl (rm->distance)); | ||
1781 | 1800 | ||
1782 | payload = (const struct GNUNET_MessageHeader *) &rm[1]; | 1801 | payload = (const struct GNUNET_MessageHeader *) &rm[1]; |
1783 | if (ntohs (message->size) != sizeof (struct RouteMessage) + ntohs (payload->size)) | 1802 | 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, | |||
1792 | /* message is for me, check reverse route! */ | 1811 | /* message is for me, check reverse route! */ |
1793 | route = GNUNET_CONTAINER_multipeermap_get (all_routes, | 1812 | route = GNUNET_CONTAINER_multipeermap_get (all_routes, |
1794 | &rm->sender); | 1813 | &rm->sender); |
1795 | if (NULL == route) | 1814 | if ( (NULL == route) && |
1815 | (NULL == GNUNET_CONTAINER_multipeermap_get (direct_neighbors, | ||
1816 | &rm->sender)) && | ||
1817 | (ntohs (rm->distance) < DEFAULT_FISHEYE_DEPTH) ) | ||
1796 | { | 1818 | { |
1797 | /* don't have reverse route, drop */ | 1819 | /* don't have reverse route yet, learn it! */ |
1820 | neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, | ||
1821 | peer); | ||
1822 | if (NULL == neighbor) | ||
1823 | { | ||
1824 | GNUNET_break (0); | ||
1825 | return GNUNET_SYSERR; | ||
1826 | } | ||
1827 | target = GNUNET_new (struct Target); | ||
1828 | target->peer = rm->sender; | ||
1829 | target->distance = htonl (ntohl (rm->distance)); | ||
1798 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1830 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1799 | "No reverse route to %s, dropping %u bytes!\n", | 1831 | "Learning target %s at distance %u from delivery!\n", |
1800 | GNUNET_i2s (&rm->sender), | 1832 | GNUNET_i2s (&rm->sender), |
1801 | ntohs (payload->size)); | 1833 | 1 + ntohs (rm->distance)); |
1802 | GNUNET_STATISTICS_update (stats, | 1834 | if (NULL == neighbor->neighbor_table) |
1803 | "# message discarded (no reverse route)", | 1835 | neighbor->neighbor_table = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); |
1804 | 1, GNUNET_NO); | 1836 | if (GNUNET_YES != |
1805 | return GNUNET_OK; | 1837 | GNUNET_CONTAINER_multipeermap_put (neighbor->neighbor_table, |
1838 | &target->peer, | ||
1839 | target, | ||
1840 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1841 | { | ||
1842 | GNUNET_break_op (0); | ||
1843 | GNUNET_free (target); | ||
1844 | } | ||
1845 | add_new_route (target, neighbor); | ||
1806 | } | 1846 | } |
1807 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1847 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1808 | "Delivering %u bytes to myself!\n", | 1848 | "Delivering %u bytes to myself!\n", |
@@ -1812,6 +1852,39 @@ handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1812 | ntohl (route->target.distance)); | 1852 | ntohl (route->target.distance)); |
1813 | return GNUNET_OK; | 1853 | return GNUNET_OK; |
1814 | } | 1854 | } |
1855 | if ( (NULL == GNUNET_CONTAINER_multipeermap_get (direct_neighbors, | ||
1856 | &rm->sender)) && | ||
1857 | (NULL == GNUNET_CONTAINER_multipeermap_get (all_routes, | ||
1858 | &rm->sender)) ) | ||
1859 | { | ||
1860 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1861 | "Learning target %s at distance %u from forwarding!\n", | ||
1862 | GNUNET_i2s (&rm->sender), | ||
1863 | 1 + ntohs (rm->distance)); | ||
1864 | neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, | ||
1865 | peer); | ||
1866 | if (NULL == neighbor) | ||
1867 | { | ||
1868 | GNUNET_break (0); | ||
1869 | return GNUNET_SYSERR; | ||
1870 | } | ||
1871 | target = GNUNET_new (struct Target); | ||
1872 | target->peer = rm->sender; | ||
1873 | target->distance = htonl (ntohl (rm->distance)); | ||
1874 | if (NULL == neighbor->neighbor_table) | ||
1875 | neighbor->neighbor_table = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | ||
1876 | if (GNUNET_YES != | ||
1877 | GNUNET_CONTAINER_multipeermap_put (neighbor->neighbor_table, | ||
1878 | &target->peer, | ||
1879 | target, | ||
1880 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1881 | { | ||
1882 | GNUNET_break_op (0); | ||
1883 | GNUNET_free (target); | ||
1884 | } | ||
1885 | add_new_route (target, neighbor); | ||
1886 | } | ||
1887 | |||
1815 | route = GNUNET_CONTAINER_multipeermap_get (all_routes, | 1888 | route = GNUNET_CONTAINER_multipeermap_get (all_routes, |
1816 | &rm->target); | 1889 | &rm->target); |
1817 | if (NULL == route) | 1890 | if (NULL == route) |
@@ -2081,9 +2154,9 @@ shutdown_task (void *cls, | |||
2081 | * @return #GNUNET_OK (continue to iterate) | 2154 | * @return #GNUNET_OK (continue to iterate) |
2082 | */ | 2155 | */ |
2083 | static int | 2156 | static int |
2084 | add_route (void *cls, | 2157 | notify_client_about_route (void *cls, |
2085 | const struct GNUNET_PeerIdentity *key, | 2158 | const struct GNUNET_PeerIdentity *key, |
2086 | void *value) | 2159 | void *value) |
2087 | { | 2160 | { |
2088 | struct GNUNET_SERVER_Client *client = cls; | 2161 | struct GNUNET_SERVER_Client *client = cls; |
2089 | struct Route *route = value; | 2162 | struct Route *route = value; |
@@ -2118,7 +2191,7 @@ handle_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
2118 | GNUNET_SERVER_notification_context_add (nc, client); | 2191 | GNUNET_SERVER_notification_context_add (nc, client); |
2119 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 2192 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
2120 | GNUNET_CONTAINER_multipeermap_iterate (all_routes, | 2193 | GNUNET_CONTAINER_multipeermap_iterate (all_routes, |
2121 | &add_route, | 2194 | ¬ify_client_about_route, |
2122 | client); | 2195 | client); |
2123 | } | 2196 | } |
2124 | 2197 | ||