diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-15 10:35:13 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-15 10:35:13 +0000 |
commit | 914435c7d72b24b9810c5c05712a73de423feb1e (patch) | |
tree | 38bfea92c94ef47f9df1bc0297506c7d282a45d4 /src | |
parent | a815c8c65bb1d10808854e7286e761ee6a4b782c (diff) | |
download | gnunet-914435c7d72b24b9810c5c05712a73de423feb1e.tar.gz gnunet-914435c7d72b24b9810c5c05712a73de423feb1e.zip |
-dv work
Diffstat (limited to 'src')
-rw-r--r-- | src/dv/gnunet_dv_service.h | 11 | ||||
-rw-r--r-- | src/dv/plugin_transport_dv.c | 247 |
2 files changed, 218 insertions, 40 deletions
diff --git a/src/dv/gnunet_dv_service.h b/src/dv/gnunet_dv_service.h index ebb84c2e2..a7d55fc98 100644 --- a/src/dv/gnunet_dv_service.h +++ b/src/dv/gnunet_dv_service.h | |||
@@ -32,6 +32,10 @@ | |||
32 | /** | 32 | /** |
33 | * Signature of a function to be called if DV | 33 | * Signature of a function to be called if DV |
34 | * starts to be able to talk to a peer. | 34 | * starts to be able to talk to a peer. |
35 | * | ||
36 | * @param cls closure | ||
37 | * @param peer newly connected peer | ||
38 | * @param distance distance to the peer | ||
35 | */ | 39 | */ |
36 | typedef void (*GNUNET_DV_ConnectCallback)(void *cls, | 40 | typedef void (*GNUNET_DV_ConnectCallback)(void *cls, |
37 | const struct GNUNET_PeerIdentity *peer, | 41 | const struct GNUNET_PeerIdentity *peer, |
@@ -41,6 +45,10 @@ typedef void (*GNUNET_DV_ConnectCallback)(void *cls, | |||
41 | /** | 45 | /** |
42 | * Signature of a function to be called if DV | 46 | * Signature of a function to be called if DV |
43 | * distance to a peer is changed. | 47 | * distance to a peer is changed. |
48 | * | ||
49 | * @param cls closure | ||
50 | * @param peer connected peer | ||
51 | * @param distance new distance to the peer | ||
44 | */ | 52 | */ |
45 | typedef void (*GNUNET_DV_DistanceChangedCallback)(void *cls, | 53 | typedef void (*GNUNET_DV_DistanceChangedCallback)(void *cls, |
46 | const struct GNUNET_PeerIdentity *peer, | 54 | const struct GNUNET_PeerIdentity *peer, |
@@ -50,6 +58,9 @@ typedef void (*GNUNET_DV_DistanceChangedCallback)(void *cls, | |||
50 | /** | 58 | /** |
51 | * Signature of a function to be called if DV | 59 | * Signature of a function to be called if DV |
52 | * is no longer able to talk to a peer. | 60 | * is no longer able to talk to a peer. |
61 | * | ||
62 | * @param cls closure | ||
63 | * @param peer peer that disconnected | ||
53 | */ | 64 | */ |
54 | typedef void (*GNUNET_DV_DisconnectCallback)(void *cls, | 65 | typedef void (*GNUNET_DV_DisconnectCallback)(void *cls, |
55 | const struct GNUNET_PeerIdentity *peer); | 66 | const struct GNUNET_PeerIdentity *peer); |
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index c07fc52de..3b44d486d 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "gnunet_transport_plugin.h" | 37 | #include "gnunet_transport_plugin.h" |
38 | #include "dv.h" | 38 | #include "dv.h" |
39 | 39 | ||
40 | #define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING | ||
41 | 40 | ||
42 | /** | 41 | /** |
43 | * Encapsulation of all of the state of the plugin. | 42 | * Encapsulation of all of the state of the plugin. |
@@ -52,9 +51,9 @@ struct Session | |||
52 | { | 51 | { |
53 | 52 | ||
54 | /** | 53 | /** |
55 | * Stored in a linked list. | 54 | * Mandatory session header. |
56 | */ | 55 | */ |
57 | struct Session *next; | 56 | struct SessionHeader header; |
58 | 57 | ||
59 | /** | 58 | /** |
60 | * Pointer to the global plugin struct. | 59 | * Pointer to the global plugin struct. |
@@ -62,11 +61,6 @@ struct Session | |||
62 | struct Plugin *plugin; | 61 | struct Plugin *plugin; |
63 | 62 | ||
64 | /** | 63 | /** |
65 | * The client (used to identify this connection) | ||
66 | */ | ||
67 | /* void *client; */ | ||
68 | |||
69 | /** | ||
70 | * Continuation function to call once the transmission buffer | 64 | * Continuation function to call once the transmission buffer |
71 | * has again space available. NULL if there is no | 65 | * has again space available. NULL if there is no |
72 | * continuation to call. | 66 | * continuation to call. |
@@ -79,30 +73,24 @@ struct Session | |||
79 | void *transmit_cont_cls; | 73 | void *transmit_cont_cls; |
80 | 74 | ||
81 | /** | 75 | /** |
82 | * To whom are we talking to (set to our identity | 76 | * To whom are we talking to. |
83 | * if we are still waiting for the welcome message) | ||
84 | */ | 77 | */ |
85 | struct GNUNET_PeerIdentity sender; | 78 | struct GNUNET_PeerIdentity sender; |
86 | 79 | ||
87 | /** | 80 | /** |
88 | * At what time did we reset last_received last? | 81 | * Current distance to the given peer. |
89 | */ | 82 | */ |
90 | struct GNUNET_TIME_Absolute last_quota_update; | 83 | uint32_t distance; |
91 | 84 | ||
92 | /** | 85 | /** |
93 | * How many bytes have we received since the "last_quota_update" | 86 | * Does the transport service know about this session (and we thus |
94 | * timestamp? | 87 | * need to call 'session_end' when it is released?) |
95 | */ | 88 | */ |
96 | uint64_t last_received; | 89 | int active; |
97 | |||
98 | /** | ||
99 | * Number of bytes per ms that this peer is allowed | ||
100 | * to send to us. | ||
101 | */ | ||
102 | uint32_t quota; | ||
103 | 90 | ||
104 | }; | 91 | }; |
105 | 92 | ||
93 | |||
106 | /** | 94 | /** |
107 | * Encapsulation of all of the state of the plugin. | 95 | * Encapsulation of all of the state of the plugin. |
108 | */ | 96 | */ |
@@ -114,9 +102,9 @@ struct Plugin | |||
114 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | 102 | struct GNUNET_TRANSPORT_PluginEnvironment *env; |
115 | 103 | ||
116 | /** | 104 | /** |
117 | * List of open sessions. FIXME: use hash map! | 105 | * Hash map of sessions (active and inactive). |
118 | */ | 106 | */ |
119 | struct Session *sessions; | 107 | struct GNUNET_CONTAINER_MultiHashMap *sessions; |
120 | 108 | ||
121 | /** | 109 | /** |
122 | * Copy of the handler array where the closures are | 110 | * Copy of the handler array where the closures are |
@@ -148,21 +136,110 @@ handle_dv_message_received (void *cls, | |||
148 | { | 136 | { |
149 | struct Plugin *plugin = cls; | 137 | struct Plugin *plugin = cls; |
150 | struct GNUNET_ATS_Information ats; | 138 | struct GNUNET_ATS_Information ats; |
151 | 139 | struct Session *session; | |
140 | |||
141 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
142 | &sender->hashPubKey); | ||
143 | if (NULL == session) | ||
144 | { | ||
145 | GNUNET_break (0); | ||
146 | return; | ||
147 | } | ||
152 | ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | 148 | ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); |
153 | ats.value = htonl (distance); | 149 | ats.value = htonl (distance); |
154 | 150 | session->active = GNUNET_YES; | |
155 | plugin->env->receive (plugin->env->cls, sender, | 151 | plugin->env->receive (plugin->env->cls, sender, |
156 | msg, | 152 | msg, |
157 | &ats, 1, | 153 | &ats, 1, |
158 | NULL, NULL, 0); | 154 | session, "", 0); |
155 | } | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Function called if DV starts to be able to talk to a peer. | ||
160 | * | ||
161 | * @param cls closure with 'struct Plugin' | ||
162 | * @param peer newly connected peer | ||
163 | * @param distance distance to the peer | ||
164 | */ | ||
165 | static void | ||
166 | handle_dv_connect (void *cls, | ||
167 | const struct GNUNET_PeerIdentity *peer, | ||
168 | uint32_t distance) | ||
169 | { | ||
170 | struct Plugin *plugin = cls; | ||
171 | struct Session *session; | ||
172 | |||
173 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
174 | &peer->hashPubKey); | ||
175 | if (NULL != session) | ||
176 | { | ||
177 | GNUNET_break (0); | ||
178 | session->distance = distance; | ||
179 | if (GNUNET_YES == session->active) | ||
180 | GNUNET_break (0); // FIXME: notify transport about distance change | ||
181 | return; /* nothing to do */ | ||
182 | } | ||
183 | session = GNUNET_malloc (sizeof (struct Session)); | ||
184 | session->sender = *peer; | ||
185 | session->distance = distance; | ||
186 | GNUNET_assert (GNUNET_YES == | ||
187 | GNUNET_CONTAINER_multihashmap_put (plugin->sessions, | ||
188 | &session->sender.hashPubKey, | ||
189 | session, | ||
190 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
159 | } | 191 | } |
160 | 192 | ||
161 | 193 | ||
162 | /* Question: how does the transport service learn of a newly connected (gossipped about) | 194 | /** |
163 | * DV peer? Should the plugin (here) create a HELLO for that peer and send it along, | 195 | * Function called if DV distance to a peer is changed. |
164 | * or should the DV service create a HELLO and send it to us via the other part? | 196 | * |
197 | * @param cls closure with 'struct Plugin' | ||
198 | * @param peer connected peer | ||
199 | * @param distance new distance to the peer | ||
165 | */ | 200 | */ |
201 | static void | ||
202 | handle_dv_distance_changed (void *cls, | ||
203 | const struct GNUNET_PeerIdentity *peer, | ||
204 | uint32_t distance) | ||
205 | { | ||
206 | struct Plugin *plugin = cls; | ||
207 | struct Session *session; | ||
208 | |||
209 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
210 | &peer->hashPubKey); | ||
211 | if (NULL == session) | ||
212 | { | ||
213 | GNUNET_break (0); | ||
214 | handle_dv_connect (plugin, peer, distance); | ||
215 | return; | ||
216 | } | ||
217 | session->distance = distance; | ||
218 | if (GNUNET_YES == session->active) | ||
219 | GNUNET_break (0); // FIXME: notify transport about distance change | ||
220 | } | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Function called if DV is no longer able to talk to a peer. | ||
225 | * | ||
226 | * @param cls closure with 'struct Plugin' | ||
227 | * @param peer peer that disconnected | ||
228 | */ | ||
229 | static void | ||
230 | handle_dv_disconnect (void *cls, | ||
231 | const struct GNUNET_PeerIdentity *peer) | ||
232 | { | ||
233 | struct Plugin *plugin = cls; | ||
234 | struct Session *session; | ||
235 | |||
236 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
237 | &peer->hashPubKey); | ||
238 | if (NULL == session) | ||
239 | return; /* nothing to do */ | ||
240 | GNUNET_break (0); // FIXME! | ||
241 | } | ||
242 | |||
166 | 243 | ||
167 | /** | 244 | /** |
168 | * Function that can be used by the transport service to transmit | 245 | * Function that can be used by the transport service to transmit |
@@ -192,11 +269,11 @@ dv_plugin_send (void *cls, | |||
192 | { | 269 | { |
193 | int ret = -1; | 270 | int ret = -1; |
194 | 271 | ||
272 | GNUNET_break (0); // FIXME! | ||
195 | return ret; | 273 | return ret; |
196 | } | 274 | } |
197 | 275 | ||
198 | 276 | ||
199 | |||
200 | /** | 277 | /** |
201 | * Function that can be used to force the plugin to disconnect | 278 | * Function that can be used to force the plugin to disconnect |
202 | * from the given peer and cancel all previous transmissions | 279 | * from the given peer and cancel all previous transmissions |
@@ -208,8 +285,16 @@ dv_plugin_send (void *cls, | |||
208 | static void | 285 | static void |
209 | dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 286 | dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) |
210 | { | 287 | { |
211 | // struct Plugin *plugin = cls; | 288 | struct Plugin *plugin = cls; |
212 | // TODO: Add message type to send to dv service to "disconnect" a peer | 289 | struct Session *session; |
290 | |||
291 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
292 | &target->hashPubKey); | ||
293 | if (NULL == session) | ||
294 | return; /* nothing to do */ | ||
295 | session->transmit_cont = NULL; | ||
296 | session->transmit_cont_cls = NULL; | ||
297 | session->active = GNUNET_NO; | ||
213 | } | 298 | } |
214 | 299 | ||
215 | 300 | ||
@@ -234,6 +319,9 @@ dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, | |||
234 | GNUNET_TRANSPORT_AddressStringCallback asc, | 319 | GNUNET_TRANSPORT_AddressStringCallback asc, |
235 | void *asc_cls) | 320 | void *asc_cls) |
236 | { | 321 | { |
322 | if ( (0 == addrlen) && | ||
323 | (0 == strcmp (type, "dv")) ) | ||
324 | asc (asc_cls, "dv"); | ||
237 | asc (asc_cls, NULL); | 325 | asc (asc_cls, NULL); |
238 | } | 326 | } |
239 | 327 | ||
@@ -248,9 +336,14 @@ dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, | |||
248 | * @return string representing the DV address | 336 | * @return string representing the DV address |
249 | */ | 337 | */ |
250 | static const char * | 338 | static const char * |
251 | address_to_string (void *cls, const void *addr, size_t addrlen) | 339 | dv_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) |
252 | { | 340 | { |
253 | return "<not implemented>"; | 341 | if (0 != addrlen) |
342 | { | ||
343 | GNUNET_break (0); /* malformed */ | ||
344 | return NULL; | ||
345 | } | ||
346 | return "dv"; | ||
254 | } | 347 | } |
255 | 348 | ||
256 | 349 | ||
@@ -273,11 +366,12 @@ address_to_string (void *cls, const void *addr, size_t addrlen) | |||
273 | static int | 366 | static int |
274 | dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) | 367 | dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) |
275 | { | 368 | { |
276 | return GNUNET_SYSERR; | 369 | if (0 != addrlen) |
370 | return GNUNET_SYSERR; | ||
371 | return GNUNET_OK; | ||
277 | } | 372 | } |
278 | 373 | ||
279 | 374 | ||
280 | |||
281 | /** | 375 | /** |
282 | * Create a new session to transmit data to the target | 376 | * Create a new session to transmit data to the target |
283 | * This session will used to send data to this peer and the plugin will | 377 | * This session will used to send data to this peer and the plugin will |
@@ -291,7 +385,46 @@ static struct Session * | |||
291 | dv_get_session (void *cls, | 385 | dv_get_session (void *cls, |
292 | const struct GNUNET_HELLO_Address *address) | 386 | const struct GNUNET_HELLO_Address *address) |
293 | { | 387 | { |
294 | return NULL; | 388 | struct Plugin *plugin = cls; |
389 | struct Session *session; | ||
390 | |||
391 | if (0 != address->address_length) | ||
392 | return NULL; | ||
393 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | ||
394 | &address->peer.hashPubKey); | ||
395 | if (NULL == session) | ||
396 | return NULL; /* not valid right now */ | ||
397 | session->active = GNUNET_YES; | ||
398 | return session; | ||
399 | } | ||
400 | |||
401 | |||
402 | /** | ||
403 | * Function called to convert a string address to | ||
404 | * a binary address. | ||
405 | * | ||
406 | * @param cls closure ('struct Plugin*') | ||
407 | * @param addr string address | ||
408 | * @param addrlen length of the address including \0 termination | ||
409 | * @param buf location to store the buffer | ||
410 | * If the function returns GNUNET_SYSERR, its contents are undefined. | ||
411 | * @param added length of created address | ||
412 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
413 | */ | ||
414 | static int | ||
415 | dv_plugin_string_to_address (void *cls, | ||
416 | const char *addr, | ||
417 | uint16_t addrlen, | ||
418 | void **buf, | ||
419 | size_t *added) | ||
420 | { | ||
421 | if ( (addrlen == 3) && | ||
422 | (0 == strcmp ("dv", addr)) ) | ||
423 | { | ||
424 | *added = 0; | ||
425 | return GNUNET_OK; | ||
426 | } | ||
427 | return GNUNET_SYSERR; | ||
295 | } | 428 | } |
296 | 429 | ||
297 | 430 | ||
@@ -307,24 +440,54 @@ libgnunet_plugin_transport_dv_init (void *cls) | |||
307 | 440 | ||
308 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 441 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
309 | plugin->env = env; | 442 | plugin->env = env; |
443 | plugin->sessions = GNUNET_CONTAINER_multihashmap_create (1024 * 8, GNUNET_YES); | ||
310 | plugin->dvh = GNUNET_DV_service_connect (env->cfg, | 444 | plugin->dvh = GNUNET_DV_service_connect (env->cfg, |
311 | plugin, | 445 | plugin, |
312 | NULL, NULL, NULL, /*FIXME! */ | 446 | &handle_dv_connect, |
447 | &handle_dv_distance_changed, | ||
448 | &handle_dv_disconnect, | ||
313 | &handle_dv_message_received); | 449 | &handle_dv_message_received); |
450 | if (NULL == plugin->dvh) | ||
451 | { | ||
452 | GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); | ||
453 | GNUNET_free (plugin); | ||
454 | return NULL; | ||
455 | } | ||
314 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 456 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
315 | api->cls = plugin; | 457 | api->cls = plugin; |
316 | api->send = &dv_plugin_send; | 458 | api->send = &dv_plugin_send; |
317 | api->disconnect = &dv_plugin_disconnect; | 459 | api->disconnect = &dv_plugin_disconnect; |
318 | api->address_pretty_printer = &dv_plugin_address_pretty_printer; | 460 | api->address_pretty_printer = &dv_plugin_address_pretty_printer; |
319 | api->check_address = &dv_plugin_check_address; | 461 | api->check_address = &dv_plugin_check_address; |
320 | api->address_to_string = &address_to_string; | 462 | api->address_to_string = &dv_plugin_address_to_string; |
321 | api->string_to_address = NULL; /* FIXME */ | 463 | api->string_to_address = &dv_plugin_string_to_address; |
322 | api->get_session = dv_get_session; | 464 | api->get_session = dv_get_session; |
323 | return api; | 465 | return api; |
324 | } | 466 | } |
325 | 467 | ||
326 | 468 | ||
327 | /** | 469 | /** |
470 | * Function called to free a session. | ||
471 | * | ||
472 | * @param cls NULL | ||
473 | * @param key unused | ||
474 | * @param value session to free | ||
475 | * @return GNUNET_OK (continue to iterate) | ||
476 | */ | ||
477 | static int | ||
478 | free_session_iterator (void *cls, | ||
479 | const struct GNUNET_HashCode *key, | ||
480 | void *value) | ||
481 | { | ||
482 | struct Session *session = value; | ||
483 | |||
484 | // FIXME: still call transmit_cont's here!? | ||
485 | GNUNET_free (session); | ||
486 | return GNUNET_OK; | ||
487 | } | ||
488 | |||
489 | |||
490 | /** | ||
328 | * Exit point from the plugin. | 491 | * Exit point from the plugin. |
329 | */ | 492 | */ |
330 | void * | 493 | void * |
@@ -334,6 +497,10 @@ libgnunet_plugin_transport_dv_done (void *cls) | |||
334 | struct Plugin *plugin = api->cls; | 497 | struct Plugin *plugin = api->cls; |
335 | 498 | ||
336 | GNUNET_DV_service_disconnect (plugin->dvh); | 499 | GNUNET_DV_service_disconnect (plugin->dvh); |
500 | GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, | ||
501 | &free_session_iterator, | ||
502 | NULL); | ||
503 | GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); | ||
337 | GNUNET_free (plugin); | 504 | GNUNET_free (plugin); |
338 | GNUNET_free (api); | 505 | GNUNET_free (api); |
339 | return NULL; | 506 | return NULL; |