aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-15 12:57:54 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-15 12:57:54 +0000
commitefb9b0d1a203a6381eacf6905a4ae43014d8804b (patch)
tree9092bf26ef67b016f7f2df193fb91da524cd58f1 /src/dv
parent7ff83d71f5a74b1c6c64dcdf02a6c339b09c4b7e (diff)
downloadgnunet-efb9b0d1a203a6381eacf6905a4ae43014d8804b.tar.gz
gnunet-efb9b0d1a203a6381eacf6905a4ae43014d8804b.zip
-draft for DV plugin
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/plugin_transport_dv.c174
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 */
50struct Session 50struct 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 */
91struct 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 */
167static void
168notify_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 */
279static void
280free_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 */
338static void
339send_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