diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-15 12:57:54 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-15 12:57:54 +0000 |
commit | efb9b0d1a203a6381eacf6905a4ae43014d8804b (patch) | |
tree | 9092bf26ef67b016f7f2df193fb91da524cd58f1 /src/dv | |
parent | 7ff83d71f5a74b1c6c64dcdf02a6c339b09c4b7e (diff) | |
download | gnunet-efb9b0d1a203a6381eacf6905a4ae43014d8804b.tar.gz gnunet-efb9b0d1a203a6381eacf6905a4ae43014d8804b.zip |
-draft for DV plugin
Diffstat (limited to 'src/dv')
-rw-r--r-- | src/dv/plugin_transport_dv.c | 174 |
1 files changed, 156 insertions, 18 deletions
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 3b44d486d..1c03d4a5f 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c | |||
@@ -45,20 +45,20 @@ struct Plugin; | |||
45 | 45 | ||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Session handle for connections. | 48 | * An active request for transmission via DV. |
49 | */ | 49 | */ |
50 | struct Session | 50 | struct PendingRequest |
51 | { | 51 | { |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Mandatory session header. | 54 | * This is a DLL. |
55 | */ | 55 | */ |
56 | struct SessionHeader header; | 56 | struct PendingRequest *next; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Pointer to the global plugin struct. | 59 | * This is a DLL. |
60 | */ | 60 | */ |
61 | struct Plugin *plugin; | 61 | struct PendingRequest *prev; |
62 | 62 | ||
63 | /** | 63 | /** |
64 | * Continuation function to call once the transmission buffer | 64 | * Continuation function to call once the transmission buffer |
@@ -73,6 +73,45 @@ struct Session | |||
73 | void *transmit_cont_cls; | 73 | void *transmit_cont_cls; |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * Transmission handle from DV client library. | ||
77 | */ | ||
78 | struct GNUNET_DV_TransmitHandle *th; | ||
79 | |||
80 | /** | ||
81 | * Session of this request. | ||
82 | */ | ||
83 | struct Session *session; | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * Session handle for connections. | ||
90 | */ | ||
91 | struct Session | ||
92 | { | ||
93 | |||
94 | /** | ||
95 | * Mandatory session header. | ||
96 | */ | ||
97 | struct SessionHeader header; | ||
98 | |||
99 | /** | ||
100 | * Pointer to the global plugin struct. | ||
101 | */ | ||
102 | struct Plugin *plugin; | ||
103 | |||
104 | /** | ||
105 | * Head of pending requests. | ||
106 | */ | ||
107 | struct PendingRequest *pr_head; | ||
108 | |||
109 | /** | ||
110 | * Tail of pending requests. | ||
111 | */ | ||
112 | struct PendingRequest *pr_tail; | ||
113 | |||
114 | /** | ||
76 | * To whom are we talking to. | 115 | * To whom are we talking to. |
77 | */ | 116 | */ |
78 | struct GNUNET_PeerIdentity sender; | 117 | struct GNUNET_PeerIdentity sender; |
@@ -121,6 +160,18 @@ struct Plugin | |||
121 | 160 | ||
122 | 161 | ||
123 | /** | 162 | /** |
163 | * Notify transport service about the change in distance. | ||
164 | * | ||
165 | * @param session session where the distance changed | ||
166 | */ | ||
167 | static void | ||
168 | notify_distance_change (struct Session *session) | ||
169 | { | ||
170 | GNUNET_break (0); // FIXME: need extended plugin API! | ||
171 | } | ||
172 | |||
173 | |||
174 | /** | ||
124 | * Handler for messages received from the DV service. | 175 | * Handler for messages received from the DV service. |
125 | * | 176 | * |
126 | * @param cls closure with the plugin | 177 | * @param cls closure with the plugin |
@@ -177,7 +228,7 @@ handle_dv_connect (void *cls, | |||
177 | GNUNET_break (0); | 228 | GNUNET_break (0); |
178 | session->distance = distance; | 229 | session->distance = distance; |
179 | if (GNUNET_YES == session->active) | 230 | if (GNUNET_YES == session->active) |
180 | GNUNET_break (0); // FIXME: notify transport about distance change | 231 | notify_distance_change (session); |
181 | return; /* nothing to do */ | 232 | return; /* nothing to do */ |
182 | } | 233 | } |
183 | session = GNUNET_malloc (sizeof (struct Session)); | 234 | session = GNUNET_malloc (sizeof (struct Session)); |
@@ -216,7 +267,43 @@ handle_dv_distance_changed (void *cls, | |||
216 | } | 267 | } |
217 | session->distance = distance; | 268 | session->distance = distance; |
218 | if (GNUNET_YES == session->active) | 269 | if (GNUNET_YES == session->active) |
219 | GNUNET_break (0); // FIXME: notify transport about distance change | 270 | notify_distance_change (session); |
271 | } | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Release session object and clean up associated resources. | ||
276 | * | ||
277 | * @param session session to clean up | ||
278 | */ | ||
279 | static void | ||
280 | free_session (struct Session *session) | ||
281 | { | ||
282 | struct Plugin *plugin = session->plugin; | ||
283 | struct PendingRequest *pr; | ||
284 | |||
285 | GNUNET_assert (GNUNET_YES == | ||
286 | GNUNET_CONTAINER_multihashmap_remove (plugin->sessions, | ||
287 | &session->sender.hashPubKey, | ||
288 | session)); | ||
289 | if (GNUNET_YES == session->active) | ||
290 | plugin->env->session_end (plugin->env->cls, | ||
291 | &session->sender, | ||
292 | session); | ||
293 | while (NULL != (pr = session->pr_head)) | ||
294 | { | ||
295 | GNUNET_CONTAINER_DLL_remove (session->pr_head, | ||
296 | session->pr_tail, | ||
297 | pr); | ||
298 | GNUNET_DV_send_cancel (pr->th); | ||
299 | pr->th = NULL; | ||
300 | if (NULL != pr->transmit_cont) | ||
301 | pr->transmit_cont (pr->transmit_cont_cls, | ||
302 | &session->sender, | ||
303 | GNUNET_SYSERR, 0, 0); | ||
304 | GNUNET_free (pr); | ||
305 | } | ||
306 | GNUNET_free (session); | ||
220 | } | 307 | } |
221 | 308 | ||
222 | 309 | ||
@@ -236,8 +323,34 @@ handle_dv_disconnect (void *cls, | |||
236 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | 323 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, |
237 | &peer->hashPubKey); | 324 | &peer->hashPubKey); |
238 | if (NULL == session) | 325 | if (NULL == session) |
239 | return; /* nothing to do */ | 326 | return; /* nothing to do */ |
240 | GNUNET_break (0); // FIXME! | 327 | free_session (session); |
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Function called once the delivery of a message has been successful. | ||
333 | * Clean up the pending request, and call continuations. | ||
334 | * | ||
335 | * @param cls closure | ||
336 | * @param ok GNUNET_OK on success, GNUNET_SYSERR on error | ||
337 | */ | ||
338 | static void | ||
339 | send_finished (void *cls, | ||
340 | int ok) | ||
341 | { | ||
342 | struct PendingRequest *pr = cls; | ||
343 | struct Session *session = pr->session; | ||
344 | |||
345 | pr->th = NULL; | ||
346 | GNUNET_CONTAINER_DLL_remove (session->pr_head, | ||
347 | session->pr_tail, | ||
348 | pr); | ||
349 | if (NULL != pr->transmit_cont) | ||
350 | pr->transmit_cont (pr->transmit_cont_cls, | ||
351 | &session->sender, | ||
352 | ok, 0, 0); | ||
353 | GNUNET_free (pr); | ||
241 | } | 354 | } |
242 | 355 | ||
243 | 356 | ||
@@ -267,10 +380,24 @@ dv_plugin_send (void *cls, | |||
267 | struct GNUNET_TIME_Relative timeout, | 380 | struct GNUNET_TIME_Relative timeout, |
268 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | 381 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
269 | { | 382 | { |
270 | int ret = -1; | 383 | struct PendingRequest *pr; |
271 | 384 | const struct GNUNET_MessageHeader *msg; | |
272 | GNUNET_break (0); // FIXME! | 385 | |
273 | return ret; | 386 | msg = (const struct GNUNET_MessageHeader *) msgbuf; |
387 | GNUNET_assert (ntohs (msg->size) == msgbuf_size); // API will change... | ||
388 | pr = GNUNET_malloc (sizeof (struct PendingRequest)); | ||
389 | pr->transmit_cont = cont; | ||
390 | pr->transmit_cont_cls = cont_cls; | ||
391 | pr->session = session; | ||
392 | GNUNET_CONTAINER_DLL_insert_tail (session->pr_head, | ||
393 | session->pr_tail, | ||
394 | pr); | ||
395 | pr->th = GNUNET_DV_send (session->plugin->dvh, | ||
396 | &session->sender, | ||
397 | msg, | ||
398 | &send_finished, | ||
399 | pr); | ||
400 | return 0; /* DV */ | ||
274 | } | 401 | } |
275 | 402 | ||
276 | 403 | ||
@@ -287,13 +414,25 @@ dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | |||
287 | { | 414 | { |
288 | struct Plugin *plugin = cls; | 415 | struct Plugin *plugin = cls; |
289 | struct Session *session; | 416 | struct Session *session; |
417 | struct PendingRequest *pr; | ||
290 | 418 | ||
291 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | 419 | session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, |
292 | &target->hashPubKey); | 420 | &target->hashPubKey); |
293 | if (NULL == session) | 421 | if (NULL == session) |
294 | return; /* nothing to do */ | 422 | return; /* nothing to do */ |
295 | session->transmit_cont = NULL; | 423 | while (NULL != (pr = session->pr_head)) |
296 | session->transmit_cont_cls = NULL; | 424 | { |
425 | GNUNET_CONTAINER_DLL_remove (session->pr_head, | ||
426 | session->pr_tail, | ||
427 | pr); | ||
428 | GNUNET_DV_send_cancel (pr->th); | ||
429 | pr->th = NULL; | ||
430 | if (NULL != pr->transmit_cont) | ||
431 | pr->transmit_cont (pr->transmit_cont_cls, | ||
432 | &session->sender, | ||
433 | GNUNET_SYSERR, 0, 0); | ||
434 | GNUNET_free (pr); | ||
435 | } | ||
297 | session->active = GNUNET_NO; | 436 | session->active = GNUNET_NO; |
298 | } | 437 | } |
299 | 438 | ||
@@ -481,8 +620,7 @@ free_session_iterator (void *cls, | |||
481 | { | 620 | { |
482 | struct Session *session = value; | 621 | struct Session *session = value; |
483 | 622 | ||
484 | // FIXME: still call transmit_cont's here!? | 623 | free_session (session); |
485 | GNUNET_free (session); | ||
486 | return GNUNET_OK; | 624 | return GNUNET_OK; |
487 | } | 625 | } |
488 | 626 | ||