diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-13 14:23:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-13 14:23:23 +0000 |
commit | d7fde87aac5d2d9842f167a40f793ca798cf06e0 (patch) | |
tree | 833b55186d2ec0cf4a65a339c77a06dde19139d6 /src/dv | |
parent | 7e036f66817a92099eef2414847c87eb8816cf1e (diff) | |
download | gnunet-d7fde87aac5d2d9842f167a40f793ca798cf06e0.tar.gz gnunet-d7fde87aac5d2d9842f167a40f793ca798cf06e0.zip |
-finishing DV API
Diffstat (limited to 'src/dv')
-rw-r--r-- | src/dv/dv_api.c | 95 |
1 files changed, 79 insertions, 16 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c index 3f9f11423..4b6cc1a5c 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c | |||
@@ -164,6 +164,8 @@ static size_t | |||
164 | transmit_pending (void *cls, size_t size, void *buf) | 164 | transmit_pending (void *cls, size_t size, void *buf) |
165 | { | 165 | { |
166 | struct GNUNET_DV_ServiceHandle *sh = cls; | 166 | struct GNUNET_DV_ServiceHandle *sh = cls; |
167 | char *cbuf = buf; | ||
168 | struct GNUNET_DV_TransmitHandle *th; | ||
167 | size_t ret; | 169 | size_t ret; |
168 | size_t tsize; | 170 | size_t tsize; |
169 | 171 | ||
@@ -174,15 +176,18 @@ transmit_pending (void *cls, size_t size, void *buf) | |||
174 | return 0; | 176 | return 0; |
175 | } | 177 | } |
176 | ret = 0; | 178 | ret = 0; |
177 | // FIXME: yuck! -- copy multiple, remove from DLL, and add to hash map! | 179 | while ( (NULL != (th = sh->th_head)) && |
178 | if (NULL != sh->th_head) | 180 | (size - ret >= (tsize = ntohs (th->msg->size)) )) |
179 | { | 181 | { |
180 | tsize = ntohs (sh->th_head->msg->size); | 182 | GNUNET_CONTAINER_DLL_remove (sh->th_head, |
181 | if (size >= tsize) | 183 | sh->th_tail, |
182 | { | 184 | th); |
183 | memcpy (buf, sh->th_head->msg, tsize); | 185 | memcpy (&cbuf[ret], th->msg, tsize); |
184 | return tsize; | 186 | ret += tsize; |
185 | } | 187 | (void) GNUNET_CONTAINER_multihashmap_put (sh->send_callbacks, |
188 | &th->target.hashPubKey, | ||
189 | th, | ||
190 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
186 | } | 191 | } |
187 | return ret; | 192 | return ret; |
188 | } | 193 | } |
@@ -224,6 +229,7 @@ handle_message_receipt (void *cls, | |||
224 | const struct GNUNET_DV_ConnectMessage *cm; | 229 | const struct GNUNET_DV_ConnectMessage *cm; |
225 | const struct GNUNET_DV_DisconnectMessage *dm; | 230 | const struct GNUNET_DV_DisconnectMessage *dm; |
226 | const struct GNUNET_DV_ReceivedMessage *rm; | 231 | const struct GNUNET_DV_ReceivedMessage *rm; |
232 | const struct GNUNET_MessageHeader *payload; | ||
227 | 233 | ||
228 | if (NULL == msg) | 234 | if (NULL == msg) |
229 | { | 235 | { |
@@ -241,7 +247,9 @@ handle_message_receipt (void *cls, | |||
241 | return; | 247 | return; |
242 | } | 248 | } |
243 | cm = (const struct GNUNET_DV_ConnectMessage *) msg; | 249 | cm = (const struct GNUNET_DV_ConnectMessage *) msg; |
244 | // FIXME | 250 | sh->connect_cb (sh->cls, |
251 | &cm->peer, | ||
252 | ntohl (cm->distance)); | ||
245 | break; | 253 | break; |
246 | case GNUNET_MESSAGE_TYPE_DV_DISCONNECT: | 254 | case GNUNET_MESSAGE_TYPE_DV_DISCONNECT: |
247 | if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage)) | 255 | if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage)) |
@@ -251,17 +259,28 @@ handle_message_receipt (void *cls, | |||
251 | return; | 259 | return; |
252 | } | 260 | } |
253 | dm = (const struct GNUNET_DV_DisconnectMessage *) msg; | 261 | dm = (const struct GNUNET_DV_DisconnectMessage *) msg; |
254 | // FIXME | 262 | sh->disconnect_cb (sh->cls, |
263 | &dm->peer); | ||
255 | break; | 264 | break; |
256 | case GNUNET_MESSAGE_TYPE_DV_RECV: | 265 | case GNUNET_MESSAGE_TYPE_DV_RECV: |
257 | if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage)) | 266 | if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage) + sizeof (struct GNUNET_MessageHeader)) |
258 | { | 267 | { |
259 | GNUNET_break (0); | 268 | GNUNET_break (0); |
260 | reconnect (sh); | 269 | reconnect (sh); |
261 | return; | 270 | return; |
262 | } | 271 | } |
263 | rm = (const struct GNUNET_DV_ReceivedMessage *) msg; | 272 | rm = (const struct GNUNET_DV_ReceivedMessage *) msg; |
264 | // FIXME | 273 | payload = (const struct GNUNET_MessageHeader *) &rm[1]; |
274 | if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ReceivedMessage) + ntohs (payload->size)) | ||
275 | { | ||
276 | GNUNET_break (0); | ||
277 | reconnect (sh); | ||
278 | return; | ||
279 | } | ||
280 | sh->message_cb (sh->cls, | ||
281 | &rm->sender, | ||
282 | ntohl (rm->distance), | ||
283 | payload); | ||
265 | break; | 284 | break; |
266 | default: | 285 | default: |
267 | reconnect (sh); | 286 | reconnect (sh); |
@@ -309,13 +328,40 @@ transmit_start (void *cls, | |||
309 | 328 | ||
310 | 329 | ||
311 | /** | 330 | /** |
331 | * We got disconnected from the service and thus all of the | ||
332 | * pending send callbacks will never be confirmed. Clean up. | ||
333 | * | ||
334 | * @param cls the 'struct GNUNET_DV_ServiceHandle' | ||
335 | * @param key a peer identity | ||
336 | * @param value a 'struct GNUNET_DV_TransmitHandle' to clean up | ||
337 | * @return GNUNET_OK (continue to iterate) | ||
338 | */ | ||
339 | static int | ||
340 | cleanup_send_cb (void *cls, | ||
341 | const struct GNUNET_HashCode *key, | ||
342 | void *value) | ||
343 | { | ||
344 | struct GNUNET_DV_ServiceHandle *sh = cls; | ||
345 | struct GNUNET_DV_TransmitHandle *th = value; | ||
346 | |||
347 | GNUNET_assert (GNUNET_YES == | ||
348 | GNUNET_CONTAINER_multihashmap_remove (sh->send_callbacks, | ||
349 | key, | ||
350 | th)); | ||
351 | th->cb (th->cb_cls, GNUNET_SYSERR); | ||
352 | GNUNET_free (th); | ||
353 | return GNUNET_OK; | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
312 | * Disconnect and then reconnect to the DV service. | 358 | * Disconnect and then reconnect to the DV service. |
313 | * | 359 | * |
314 | * @param sh service handle | 360 | * @param sh service handle |
315 | */ | 361 | */ |
316 | static void | 362 | static void |
317 | reconnect (struct GNUNET_DV_ServiceHandle *sh) | 363 | reconnect (struct GNUNET_DV_ServiceHandle *sh) |
318 | { | 364 | { |
319 | if (NULL != sh->th) | 365 | if (NULL != sh->th) |
320 | { | 366 | { |
321 | GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); | 367 | GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); |
@@ -326,6 +372,9 @@ reconnect (struct GNUNET_DV_ServiceHandle *sh) | |||
326 | GNUNET_CLIENT_disconnect (sh->client); | 372 | GNUNET_CLIENT_disconnect (sh->client); |
327 | sh->client = NULL; | 373 | sh->client = NULL; |
328 | } | 374 | } |
375 | GNUNET_CONTAINER_multihashmap_iterate (sh->send_callbacks, | ||
376 | &cleanup_send_cb, | ||
377 | sh); | ||
329 | sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg); | 378 | sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg); |
330 | if (NULL == sh->client) | 379 | if (NULL == sh->client) |
331 | { | 380 | { |
@@ -401,7 +450,9 @@ GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh) | |||
401 | GNUNET_CLIENT_disconnect (sh->client); | 450 | GNUNET_CLIENT_disconnect (sh->client); |
402 | sh->client = NULL; | 451 | sh->client = NULL; |
403 | } | 452 | } |
404 | // FIXME: handle and/or free entries in 'send_callbacks'! | 453 | GNUNET_CONTAINER_multihashmap_iterate (sh->send_callbacks, |
454 | &cleanup_send_cb, | ||
455 | sh); | ||
405 | GNUNET_CONTAINER_multihashmap_destroy (sh->send_callbacks); | 456 | GNUNET_CONTAINER_multihashmap_destroy (sh->send_callbacks); |
406 | GNUNET_free (sh); | 457 | GNUNET_free (sh); |
407 | } | 458 | } |
@@ -425,16 +476,28 @@ GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh, | |||
425 | void *cb_cls) | 476 | void *cb_cls) |
426 | { | 477 | { |
427 | struct GNUNET_DV_TransmitHandle *th; | 478 | struct GNUNET_DV_TransmitHandle *th; |
479 | struct GNUNET_DV_SendMessage *sm; | ||
428 | 480 | ||
481 | if (ntohs (msg->size) + sizeof (struct GNUNET_DV_SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
482 | { | ||
483 | GNUNET_break (0); | ||
484 | return NULL; | ||
485 | } | ||
429 | th = GNUNET_malloc (sizeof (struct GNUNET_DV_TransmitHandle) + | 486 | th = GNUNET_malloc (sizeof (struct GNUNET_DV_TransmitHandle) + |
487 | sizeof (struct GNUNET_DV_SendMessage) + | ||
430 | ntohs (msg->size)); | 488 | ntohs (msg->size)); |
431 | th->sh = sh; | 489 | th->sh = sh; |
432 | th->target = *target; | 490 | th->target = *target; |
433 | th->cb = cb; | 491 | th->cb = cb; |
434 | th->cb_cls = cb_cls; | 492 | th->cb_cls = cb_cls; |
435 | // FIXME: wrong, need to box 'msg' AND generate UID! | ||
436 | th->msg = (const struct GNUNET_MessageHeader *) &th[1]; | 493 | th->msg = (const struct GNUNET_MessageHeader *) &th[1]; |
437 | memcpy (&th[1], msg, ntohs (msg->size)); | 494 | sm = (struct GNUNET_DV_SendMessage *) &th[1]; |
495 | sm->header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND); | ||
496 | sm->header.size = htons (sizeof (struct GNUNET_DV_SendMessage) + | ||
497 | ntohs (msg->size)); | ||
498 | /* use memcpy here as 'target' may not be sufficiently aligned */ | ||
499 | memcpy (&sm->target, target, sizeof (struct GNUNET_PeerIdentity)); | ||
500 | memcpy (&sm[1], msg, ntohs (msg->size)); | ||
438 | GNUNET_CONTAINER_DLL_insert (sh->th_head, | 501 | GNUNET_CONTAINER_DLL_insert (sh->th_head, |
439 | sh->th_tail, | 502 | sh->th_tail, |
440 | th); | 503 | th); |