diff options
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r-- | src/dht/gnunet-service-dht.c | 286 |
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 | */ | ||
43 | struct 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 | */ | ||
81 | struct 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 | */ |
45 | struct GNUNET_MessageHeader *GDS_my_hello; | 113 | struct GNUNET_MessageHeader *GDS_my_hello; |
46 | 114 | ||
47 | /** | 115 | /** |
48 | * Handle to get our current HELLO. | 116 | * Handles for the DHT underlays. |
117 | */ | ||
118 | static struct Underlay *u_head; | ||
119 | |||
120 | /** | ||
121 | * Handles for the DHT underlays. | ||
122 | */ | ||
123 | static struct Underlay *u_tail; | ||
124 | |||
125 | /** | ||
126 | * Head of addresses of this peer. | ||
127 | */ | ||
128 | static struct MyAddress *a_head; | ||
129 | |||
130 | /** | ||
131 | * Tail of addresses of this peer. | ||
49 | */ | 132 | */ |
50 | static struct GNUNET_TRANSPORT_HelloGetHandle *ghh; | 133 | static struct MyAddress *a_tail; |
51 | 134 | ||
52 | /** | 135 | /** |
53 | * Hello address expiration | 136 | * Hello address expiration |
54 | */ | 137 | */ |
55 | struct GNUNET_TIME_Relative hello_expiration; | 138 | struct 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 | */ | ||
144 | static 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 | */ | ||
156 | static void | ||
157 | update_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 | */ |
187 | double | ||
188 | GDS_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 | */ |
68 | static void | 200 | static void |
69 | process_hello (void *cls, | 201 | update_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 | */ | ||
217 | static void | ||
218 | u_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 | */ | ||
243 | static void | ||
244 | u_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, | |||
85 | static void | 262 | static void |
86 | shutdown_task (void *cls) | 263 | shutdown_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 | */ | ||
293 | static void | ||
294 | load_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 | ||