aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-12-18 14:29:56 +0000
committerChristian Grothoff <christian@grothoff.org>2013-12-18 14:29:56 +0000
commitbcc375bf6c191efd5243ff21e274d261354d99a4 (patch)
treee725b75240af320db072818182c972463e2f09ba
parent920f6c8c466a11852d1bd7298e3f76deda69b6f3 (diff)
downloadgnunet-bcc375bf6c191efd5243ff21e274d261354d99a4.tar.gz
gnunet-bcc375bf6c191efd5243ff21e274d261354d99a4.zip
-learn routes from forwarding/receiving as well
-rw-r--r--src/dv/dv_api.c6
-rw-r--r--src/dv/gnunet-service-dv.c167
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
97struct RouteMessage 97struct 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 */
1036static void
1037add_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 */
2083static int 2156static int
2084add_route (void *cls, 2157notify_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 &notify_client_about_route,
2122 client); 2195 client);
2123} 2196}
2124 2197