aboutsummaryrefslogtreecommitdiff
path: root/src/dhtu/plugin_dhtu_ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhtu/plugin_dhtu_ip.c')
-rw-r--r--src/dhtu/plugin_dhtu_ip.c118
1 files changed, 97 insertions, 21 deletions
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c
index a0da9d680..f80325cbc 100644
--- a/src/dhtu/plugin_dhtu_ip.c
+++ b/src/dhtu/plugin_dhtu_ip.c
@@ -23,18 +23,22 @@
23 * 23 *
24 * @file plugin_dhtu_ip.c 24 * @file plugin_dhtu_ip.c
25 * @brief plain IP based DHT network underlay 25 * @brief plain IP based DHT network underlay
26 *
27 * TODO:
28 * - call NSE callback
29 * - expire destination addresses
30 * - faster lookup of destinations
31 */ 26 */
32#include "platform.h" 27#include "platform.h"
33#include "gnunet_dhtu_plugin.h" 28#include "gnunet_dhtu_plugin.h"
34 29
30/**
31 * How frequently should we re-scan our local interfaces for IPs?
32 */
35#define SCAN_FREQ GNUNET_TIME_UNIT_MINUTES 33#define SCAN_FREQ GNUNET_TIME_UNIT_MINUTES
36 34
37/** 35/**
36 * Maximum number of concurrently active destinations to support.
37 */
38#define MAX_DESTS 256
39
40
41/**
38 * Opaque handle that the underlay offers for our address to be used when 42 * Opaque handle that the underlay offers for our address to be used when
39 * sending messages to another peer. 43 * sending messages to another peer.
40 */ 44 */
@@ -90,7 +94,7 @@ struct GNUNET_DHTU_Source
90 */ 94 */
91struct GNUNET_DHTU_Target 95struct GNUNET_DHTU_Target
92{ 96{
93 // FIXME: add mechanism for targets to expire 97
94 /** 98 /**
95 * Kept in a DLL. 99 * Kept in a DLL.
96 */ 100 */
@@ -182,7 +186,8 @@ struct Plugin
182 struct GNUNET_DHTU_Source *src_tail; 186 struct GNUNET_DHTU_Source *src_tail;
183 187
184 /** 188 /**
185 * Head of destinations that are active. 189 * Head of destinations that are active. Sorted by
190 * last use, with latest used at the head.
186 */ 191 */
187 struct GNUNET_DHTU_Target *dst_head; 192 struct GNUNET_DHTU_Target *dst_head;
188 193
@@ -192,6 +197,11 @@ struct Plugin
192 struct GNUNET_DHTU_Target *dst_tail; 197 struct GNUNET_DHTU_Target *dst_tail;
193 198
194 /** 199 /**
200 * Map from hashes of sockaddrs to targets.
201 */
202 struct GNUNET_CONTAINER_MultiHashMap *dsts;
203
204 /**
195 * Task that scans for IP address changes. 205 * Task that scans for IP address changes.
196 */ 206 */
197 struct GNUNET_SCHEDULER_Task *scan_task; 207 struct GNUNET_SCHEDULER_Task *scan_task;
@@ -276,6 +286,36 @@ create_target (struct Plugin *plugin,
276 static struct GNUNET_DHTU_PublicKey pk; 286 static struct GNUNET_DHTU_PublicKey pk;
277 struct GNUNET_DHTU_Target *dst; 287 struct GNUNET_DHTU_Target *dst;
278 288
289 if (MAX_DESTS >
290 GNUNET_CONTAINER_multihashmap_size (plugin->dsts))
291 {
292 struct GNUNET_HashCode key;
293
294 dst = NULL;
295 for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
296 NULL != pos;
297 pos = pos->next)
298 {
299 /* >= here assures we remove oldest entries first */
300 if ( (NULL == dst) ||
301 (dst->ph_count >= pos->ph_count) )
302 dst = pos;
303 }
304 GNUNET_assert (NULL != dst);
305 plugin->env->disconnect_cb (dst->app_ctx);
306 GNUNET_CRYPTO_hash (&dst->addr,
307 dst->addrlen,
308 &key);
309 GNUNET_assert (GNUNET_YES ==
310 GNUNET_CONTAINER_multihashmap_remove (plugin->dsts,
311 &key,
312 dst));
313 GNUNET_CONTAINER_DLL_remove (plugin->dst_head,
314 plugin->dst_tail,
315 dst);
316 GNUNET_assert (NULL == dst->ph_head);
317 GNUNET_free (dst);
318 }
279 pk.size = htons (sizeof (pk)); 319 pk.size = htons (sizeof (pk));
280 dst = GNUNET_new (struct GNUNET_DHTU_Target); 320 dst = GNUNET_new (struct GNUNET_DHTU_Target);
281 dst->addrlen = addrlen; 321 dst->addrlen = addrlen;
@@ -336,20 +376,38 @@ find_target (struct Plugin *plugin,
336 const void *addr, 376 const void *addr,
337 size_t addrlen) 377 size_t addrlen)
338{ 378{
339 // FIXME-OPTIMIZE: use hash map instead of linear search 379 struct GNUNET_HashCode key;
340 for (struct GNUNET_DHTU_Target *dst = plugin->dst_head; 380 struct GNUNET_DHTU_Target *dst;
341 NULL != dst; 381
342 dst = dst->next) 382 GNUNET_CRYPTO_hash (addr,
383 addrlen,
384 &key);
385 dst = GNUNET_CONTAINER_multihashmap_get (plugin->dsts,
386 &key);
387 if (NULL == dst)
343 { 388 {
344 if ( (addrlen == dst->addrlen) && 389 dst = create_target (plugin,
345 (0 == memcmp (addr, 390 (const struct sockaddr *) addr,
346 &dst->addr, 391 addrlen);
347 addrlen)) ) 392 GNUNET_assert (GNUNET_YES ==
348 return dst; 393 GNUNET_CONTAINER_multihashmap_put (
394 plugin->dsts,
395 &key,
396 dst,
397 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
349 } 398 }
350 return create_target (plugin, 399 else
351 (const struct sockaddr *) addr, 400 {
352 addrlen); 401 /* move to head of DLL */
402 GNUNET_CONTAINER_DLL_remove (plugin->dst_head,
403 plugin->dst_tail,
404 dst);
405 GNUNET_CONTAINER_DLL_insert (plugin->dst_head,
406 plugin->dst_tail,
407 dst);
408
409 }
410 return dst;
353} 411}
354 412
355 413
@@ -818,8 +876,20 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
818 unsigned int nport; 876 unsigned int nport;
819 int sock; 877 int sock;
820 int af; 878 int af;
879 unsigned long long nse;
821 880
822 if (GNUNET_OK != 881 if (GNUNET_OK !=
882 GNUNET_CONFIGURATION_get_value_number (env->cfg,
883 "DHTU-IP",
884 "NSE",
885 &nse))
886 {
887 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
888 "DHTU-IP",
889 "NSE");
890 return NULL;
891 }
892 if (GNUNET_OK !=
823 GNUNET_CONFIGURATION_get_value_string (env->cfg, 893 GNUNET_CONFIGURATION_get_value_string (env->cfg,
824 "DHTU-IP", 894 "DHTU-IP",
825 "UDP_PORT", 895 "UDP_PORT",
@@ -936,13 +1006,18 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
936 } 1006 }
937 break; 1007 break;
938 } 1008 }
1009 plugin->dsts = GNUNET_CONTAINER_multihashmap_create (128,
1010 GNUNET_NO);
939 plugin->sock = GNUNET_NETWORK_socket_box_native (sock); 1011 plugin->sock = GNUNET_NETWORK_socket_box_native (sock);
940 plugin->read_task = GNUNET_SCHEDULER_add_read_net ( 1012 plugin->read_task = GNUNET_SCHEDULER_add_read_net (
941 GNUNET_TIME_UNIT_FOREVER_REL, 1013 GNUNET_TIME_UNIT_FOREVER_REL,
942 plugin->sock, 1014 plugin->sock,
943 &read_cb, 1015 &read_cb,
944 plugin); 1016 plugin);
945 // FIXME: deal with NSE callback... 1017 env->network_size_cb (env->cls,
1018 GNUNET_TIME_UNIT_ZERO_ABS,
1019 log (nse) / log (2),
1020 -1.0 /* stddev */);
946 plugin->scan_task = GNUNET_SCHEDULER_add_now (&scan, 1021 plugin->scan_task = GNUNET_SCHEDULER_add_now (&scan,
947 plugin); 1022 plugin);
948 api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions); 1023 api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions);
@@ -974,6 +1049,7 @@ libgnunet_plugin_dhtu_ip_done (void *cls)
974 while (NULL != (dst = plugin->dst_head)) 1049 while (NULL != (dst = plugin->dst_head))
975 { 1050 {
976 plugin->env->disconnect_cb (dst->app_ctx); 1051 plugin->env->disconnect_cb (dst->app_ctx);
1052 GNUNET_assert (NULL == dst->ph_head);
977 GNUNET_CONTAINER_DLL_remove (plugin->dst_head, 1053 GNUNET_CONTAINER_DLL_remove (plugin->dst_head,
978 plugin->dst_tail, 1054 plugin->dst_tail,
979 dst); 1055 dst);
@@ -988,7 +1064,7 @@ libgnunet_plugin_dhtu_ip_done (void *cls)
988 GNUNET_free (src->address); 1064 GNUNET_free (src->address);
989 GNUNET_free (src); 1065 GNUNET_free (src);
990 } 1066 }
991 1067 GNUNET_CONTAINER_multihashmap_destroy (plugin->dsts);
992 GNUNET_SCHEDULER_cancel (plugin->scan_task); 1068 GNUNET_SCHEDULER_cancel (plugin->scan_task);
993 GNUNET_break (0 == 1069 GNUNET_break (0 ==
994 GNUNET_NETWORK_socket_close (plugin->sock)); 1070 GNUNET_NETWORK_socket_close (plugin->sock));