aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c286
1 files changed, 253 insertions, 33 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index da46dcfee..6f2573d26 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -27,8 +27,6 @@
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_block_lib.h" 28#include "gnunet_block_lib.h"
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_transport_service.h"
31#include "gnunet_transport_hello_service.h"
32#include "gnunet_hello_lib.h" 30#include "gnunet_hello_lib.h"
33#include "gnunet_dht_service.h" 31#include "gnunet_dht_service.h"
34#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
@@ -36,44 +34,223 @@
36#include "gnunet-service-dht_datacache.h" 34#include "gnunet-service-dht_datacache.h"
37#include "gnunet-service-dht_hello.h" 35#include "gnunet-service-dht_hello.h"
38#include "gnunet-service-dht_neighbours.h" 36#include "gnunet-service-dht_neighbours.h"
39#include "gnunet-service-dht_nse.h"
40#include "gnunet-service-dht_routing.h" 37#include "gnunet-service-dht_routing.h"
41 38
39
40/**
41 * Information we keep per underlay.
42 */
43struct Underlay
44{
45
46 /**
47 * Kept in a DLL.
48 */
49 struct Underlay *next;
50
51 /**
52 * Kept in a DLL.
53 */
54 struct Underlay *prev;
55
56 /**
57 * Environment for this underlay.
58 */
59 struct GNUNET_DHTU_PluginEnvironment env;
60
61 /**
62 * Underlay API handle.
63 */
64 struct GNUNET_DHTU_PluginFunctions *dhtu;
65
66 /**
67 * current network size estimate for this underlay.
68 */
69 double network_size_estimate;
70
71 /**
72 * Name of the underlay (i.e. "gnunet" or "ip").
73 */
74 char *name;
75};
76
77
78/**
79 * An address of this peer.
80 */
81struct MyAddress
82{
83 /**
84 * Kept in a DLL.
85 */
86 struct MyAddress *next;
87
88 /**
89 * Kept in a DLL.
90 */
91 struct MyAddress *prev;
92
93 /**
94 * Underlay handle for the address.
95 */
96 struct GNUNET_DHTU_Source *source;
97
98 /**
99 * Textual representation of the address.
100 */
101 char *url;
102
103 /**
104 * Underlay of this address.
105 */
106 struct Underlay *u;
107};
108
109
42/** 110/**
43 * Our HELLO 111 * Our HELLO
44 */ 112 */
45struct GNUNET_MessageHeader *GDS_my_hello; 113struct GNUNET_MessageHeader *GDS_my_hello;
46 114
47/** 115/**
48 * Handle to get our current HELLO. 116 * Handles for the DHT underlays.
117 */
118static struct Underlay *u_head;
119
120/**
121 * Handles for the DHT underlays.
122 */
123static struct Underlay *u_tail;
124
125/**
126 * Head of addresses of this peer.
127 */
128static struct MyAddress *a_head;
129
130/**
131 * Tail of addresses of this peer.
49 */ 132 */
50static struct GNUNET_TRANSPORT_HelloGetHandle *ghh; 133static struct MyAddress *a_tail;
51 134
52/** 135/**
53 * Hello address expiration 136 * Hello address expiration
54 */ 137 */
55struct GNUNET_TIME_Relative hello_expiration; 138struct GNUNET_TIME_Relative hello_expiration;
56 139
140/**
141 * log of the current network size estimate, used as the point where
142 * we switch between random and deterministic routing.
143 */
144static double log_of_network_size_estimate;
57 145
58#include "gnunet-service-dht_clients.c" 146
147/**
148 * Callback that is called when network size estimate is updated.
149 *
150 * @param cls a `struct Underlay`
151 * @param timestamp time when the estimate was received from the server (or created by the server)
152 * @param logestimate the log(Base 2) value of the current network size estimate
153 * @param std_dev standard deviation for the estimate
154 *
155 */
156static void
157update_network_size_estimate (void *cls,
158 struct GNUNET_TIME_Absolute timestamp,
159 double logestimate,
160 double std_dev)
161{
162 struct Underlay *u = cls;
163 double sum = 0.0;
164
165 GNUNET_STATISTICS_update (GDS_stats,
166 "# Network size estimates received",
167 1,
168 GNUNET_NO);
169 /* do not allow estimates < 0.5 */
170 u->network_size_estimate = pow (2.0,
171 GNUNET_MAX (0.5,
172 logestimate));
173 for (struct Underlay *p; NULL != p; p = p->next)
174 sum += p->network_size_estimate;
175 if (sum <= 2.0)
176 log_of_network_size_estimate = 0.5;
177 else
178 log_of_network_size_estimate = log2 (sum);
179}
59 180
60 181
61/** 182/**
62 * Receive the HELLO from transport service, free current and replace 183 * Return the current NSE
63 * if necessary.
64 * 184 *
65 * @param cls NULL 185 * @return the current NSE as a logarithm
66 * @param message HELLO message of peer 186 */
187double
188GDS_NSE_get (void)
189{
190 return log_of_network_size_estimate;
191}
192
193
194#include "gnunet-service-dht_clients.c"
195
196
197/**
198 * Update our HELLO with all of our our addresses.
67 */ 199 */
68static void 200static void
69process_hello (void *cls, 201update_hello (void)
70 const struct GNUNET_MessageHeader *message)
71{ 202{
72 GNUNET_free (GDS_my_hello); 203 GNUNET_free (GDS_my_hello);
73 GDS_my_hello = GNUNET_malloc (ntohs (message->size)); 204 // FIXME: build new HELLO properly!
74 GNUNET_memcpy (GDS_my_hello, 205}
75 message, 206
76 ntohs (message->size)); 207
208/**
209 * Function to call with new addresses of this peer.
210 *
211 * @param cls the closure
212 * @param address address under which we are likely reachable,
213 * pointer will remain valid until @e address_del_cb is called; to be used for HELLOs. Example: "ip+udp://$PID/1.1.1.1:2086/"
214 * @param source handle for sending from this address, NULL if we can only receive
215 * @param[out] ctx storage space for DHT to use in association with this address
216 */
217static void
218u_address_add (void *cls,
219 const char *address,
220 struct GNUNET_DHTU_Source *source,
221 void **ctx)
222{
223 struct Underlay *u = cls;
224 struct MyAddress *a;
225
226 a = GNUNET_new (struct MyAddress);
227 a->source = source;
228 a->url = GNUNET_strdup (address);
229 a->u = u;
230 GNUNET_CONTAINER_DLL_insert (a_head,
231 a_tail,
232 a);
233 *ctx = a;
234 update_hello ();
235}
236
237
238/**
239 * Function to call with expired addresses of this peer.
240 *
241 * @param[in] ctx storage space used by the DHT in association with this address
242 */
243static void
244u_address_del (void *ctx)
245{
246 struct MyAddress *a = ctx;
247
248 GNUNET_CONTAINER_DLL_remove (a_head,
249 a_tail,
250 a);
251 GNUNET_free (a->url);
252 GNUNET_free (a);
253 update_hello ();
77} 254}
78 255
79 256
@@ -85,16 +262,10 @@ process_hello (void *cls,
85static void 262static void
86shutdown_task (void *cls) 263shutdown_task (void *cls)
87{ 264{
88 if (NULL != ghh)
89 {
90 GNUNET_TRANSPORT_hello_get_cancel (ghh);
91 ghh = NULL;
92 }
93 GDS_NEIGHBOURS_done (); 265 GDS_NEIGHBOURS_done ();
94 GDS_DATACACHE_done (); 266 GDS_DATACACHE_done ();
95 GDS_ROUTING_done (); 267 GDS_ROUTING_done ();
96 GDS_HELLO_done (); 268 GDS_HELLO_done ();
97 GDS_NSE_done ();
98 if (NULL != GDS_block_context) 269 if (NULL != GDS_block_context)
99 { 270 {
100 GNUNET_BLOCK_context_destroy (GDS_block_context); 271 GNUNET_BLOCK_context_destroy (GDS_block_context);
@@ -113,6 +284,57 @@ shutdown_task (void *cls)
113 284
114 285
115/** 286/**
287 * Function iterating over all configuration sections.
288 * Loads plugins for enabled DHT underlays.
289 *
290 * @param cls NULL
291 * @param section configuration section to inspect
292 */
293static void
294load_underlay (void *cls,
295 const char *section)
296{
297 struct Underlay *u;
298 char *libname;
299
300 (void) cls;
301 if (0 != strncasecmp (section,
302 "dhtu-",
303 strlen ("dhtu-")))
304 return;
305 if (GNUNET_YES !=
306 GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg,
307 section,
308 "ENABLED"))
309 return;
310 section += strlen ("dhtu-");
311 u = GNUNET_new (struct Underlay);
312 u->env.cls = u;
313 u->env.address_add_cb = &u_address_add;
314 u->env.address_del_cb = &u_address_del;
315 u->env.network_size_cb = &update_network_size_estimate;
316 u->env.connect_cb = &GDS_u_connect;
317 u->env.disconnect_cb = &GDS_u_disconnect;
318 u->env.receive_cb = &GDS_u_receive;
319 GNUNET_asprintf (&libname,
320 "libgnunet_plugin_dhtu_%s",
321 section);
322 u->dhtu = GNUNET_PLUGIN_load (libname,
323 &u->env);
324 if (NULL == u->dhtu)
325 {
326 GNUNET_free (libname);
327 GNUNET_free (u);
328 return;
329 }
330 u->name = GNUNET_strdup (section);
331 GNUNET_CONTAINER_DLL_insert (u_head,
332 u_tail,
333 u);
334}
335
336
337/**
116 * Process dht requests. 338 * Process dht requests.
117 * 339 *
118 * @param cls closure 340 * @param cls closure
@@ -137,23 +359,21 @@ run (void *cls,
137 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); 359 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg);
138 GDS_stats = GNUNET_STATISTICS_create ("dht", 360 GDS_stats = GNUNET_STATISTICS_create ("dht",
139 GDS_cfg); 361 GDS_cfg);
140 GNUNET_SERVICE_suspend (GDS_service);
141 GDS_CLIENTS_init (); 362 GDS_CLIENTS_init ();
142 GDS_ROUTING_init (); 363 GDS_ROUTING_init ();
143 GDS_NSE_init ();
144 GDS_DATACACHE_init (); 364 GDS_DATACACHE_init ();
145 GDS_HELLO_init (); 365 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
146 if (GNUNET_OK != GDS_NEIGHBOURS_init ()) 366 NULL);
367 GNUNET_CONFIGURATION_iterate_sections (GDS_cfg,
368 &load_underlay,
369 NULL);
370 if (NULL == u_head)
147 { 371 {
148 shutdown_task (NULL); 372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
373 "No DHT underlays configured!\n");
374 GNUNET_SCHEDULER_shutdown ();
149 return; 375 return;
150 } 376 }
151 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
152 NULL);
153 ghh = GNUNET_TRANSPORT_hello_get (GDS_cfg,
154 GNUNET_TRANSPORT_AC_GLOBAL,
155 &process_hello,
156 NULL);
157} 377}
158 378
159 379