aboutsummaryrefslogtreecommitdiff
path: root/src/dv/dv_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dv/dv_api.c')
-rw-r--r--src/dv/dv_api.c157
1 files changed, 129 insertions, 28 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c
index a2d9f1762..29b6dcca3 100644
--- a/src/dv/dv_api.c
+++ b/src/dv/dv_api.c
@@ -36,6 +36,7 @@
36#include "gnunet_time_lib.h" 36#include "gnunet_time_lib.h"
37#include "gnunet_dv_service.h" 37#include "gnunet_dv_service.h"
38#include "dv.h" 38#include "dv.h"
39#include "../transport/plugin_transport.h"
39 40
40 41
41struct PendingMessages 42struct PendingMessages
@@ -109,12 +110,21 @@ struct GNUNET_DV_Handle
109 */ 110 */
110 void *receive_cls; 111 void *receive_cls;
111 112
113 /**
114 * Current unique ID
115 */
116 uint32_t uid_gen;
117
118 /**
119 * Hashmap containing outstanding send requests awaiting confirmation.
120 */
121 struct GNUNET_CONTAINER_MultiHashMap *send_callbacks;
122
112}; 123};
113 124
114 125
115struct StartContext 126struct StartContext
116{ 127{
117
118 /** 128 /**
119 * Start message 129 * Start message
120 */ 130 */
@@ -126,6 +136,37 @@ struct StartContext
126 struct GNUNET_DV_Handle *handle; 136 struct GNUNET_DV_Handle *handle;
127}; 137};
128 138
139struct SendCallbackContext
140{
141 /**
142 * The continuation to call once a message is confirmed sent (or failed)
143 */
144 GNUNET_TRANSPORT_TransmitContinuation cont;
145
146 /**
147 * Closure to call with send continuation.
148 */
149 void *cont_cls;
150
151 /**
152 * Target of the message.
153 */
154 struct GNUNET_PeerIdentity target;
155};
156
157/**
158 * Convert unique ID to hash code.
159 *
160 * @param uid unique ID to convert
161 * @param hash set to uid (extended with zeros)
162 */
163static void
164hash_from_uid (uint32_t uid,
165 GNUNET_HashCode *hash)
166{
167 memset (hash, 0, sizeof(GNUNET_HashCode));
168 *((uint32_t*)hash) = uid;
169}
129 170
130/** 171/**
131 * Try to (re)connect to the dv service. 172 * Try to (re)connect to the dv service.
@@ -283,58 +324,98 @@ static void add_pending(struct GNUNET_DV_Handle *handle, struct GNUNET_DV_SendMe
283 process_pending_message(handle); 324 process_pending_message(handle);
284} 325}
285 326
286 327/**
328 * Handles a message sent from the DV service to us.
329 * Parse it out and give it to the plugin.
330 *
331 * @param cls the handle to the DV API
332 * @param msg the message that was received
333 */
287void handle_message_receipt (void *cls, 334void handle_message_receipt (void *cls,
288 const struct GNUNET_MessageHeader * msg) 335 const struct GNUNET_MessageHeader * msg)
289{ 336{
290 struct GNUNET_DV_Handle *handle = cls; 337 struct GNUNET_DV_Handle *handle = cls;
291 struct GNUNET_DV_MessageReceived *received_msg; 338 struct GNUNET_DV_MessageReceived *received_msg;
339 struct GNUNET_DV_SendResultMessage *send_result_msg;
292 size_t packed_msg_len; 340 size_t packed_msg_len;
293 size_t sender_address_len; 341 size_t sender_address_len;
294 char *sender_address; 342 char *sender_address;
295 char *packed_msg; 343 char *packed_msg;
296 char *packed_msg_start; 344 char *packed_msg_start;
345 GNUNET_HashCode uidhash;
346 struct SendCallbackContext *send_ctx;
297 347
298 if (msg == NULL) 348 if (msg == NULL)
299 { 349 {
300 return; /* Connection closed? */ 350 return; /* Connection closed? */
301 } 351 }
302 352
303 GNUNET_assert(ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE); 353 GNUNET_assert((ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE) || (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT));
304 354
305 if (ntohs(msg->size) < sizeof(struct GNUNET_DV_MessageReceived)) 355 switch (ntohs(msg->type))
306 return; 356 {
357 case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE:
358 if (ntohs(msg->size) < sizeof(struct GNUNET_DV_MessageReceived))
359 return;
307 360
308 received_msg = (struct GNUNET_DV_MessageReceived *)msg; 361 received_msg = (struct GNUNET_DV_MessageReceived *)msg;
309 packed_msg_len = ntohl(received_msg->msg_len); 362 packed_msg_len = ntohl(received_msg->msg_len);
310 sender_address_len = ntohl(received_msg->sender_address_len); 363 sender_address_len = ntohl(received_msg->sender_address_len);
311 364
312 GNUNET_assert(ntohs(msg->size) == (sizeof(struct GNUNET_DV_MessageReceived) + packed_msg_len + sender_address_len)); 365 GNUNET_assert(ntohs(msg->size) == (sizeof(struct GNUNET_DV_MessageReceived) + packed_msg_len + sender_address_len));
313#if DEBUG_DV 366#if DEBUG_DV
314 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "dv api receives message, size checks out!\n"); 367 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "dv api receives message, size checks out!\n");
315#endif 368#endif
316 sender_address = GNUNET_malloc(sender_address_len); 369 sender_address = GNUNET_malloc(sender_address_len);
317 memcpy(sender_address, &received_msg[1], sender_address_len); 370 memcpy(sender_address, &received_msg[1], sender_address_len);
318 packed_msg_start = (char *)&received_msg[1]; 371 packed_msg_start = (char *)&received_msg[1];
319 packed_msg = GNUNET_malloc(packed_msg_len); 372 packed_msg = GNUNET_malloc(packed_msg_len);
320 memcpy(packed_msg, &packed_msg_start[sender_address_len], packed_msg_len); 373 memcpy(packed_msg, &packed_msg_start[sender_address_len], packed_msg_len);
321 374
322#if DEBUG_DV 375#if DEBUG_DV
323 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: packed message type: %d or %d\n", ntohs(((struct GNUNET_MessageHeader *)packed_msg)->type), ((struct GNUNET_MessageHeader *)packed_msg)->type); 376 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: packed message type: %d or %d\n", ntohs(((struct GNUNET_MessageHeader *)packed_msg)->type), ((struct GNUNET_MessageHeader *)packed_msg)->type);
324 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: message sender reported as %s\n", GNUNET_i2s(&received_msg->sender)); 377 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: message sender reported as %s\n", GNUNET_i2s(&received_msg->sender));
325 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: distance is %u\n", ntohl(received_msg->distance)); 378 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: distance is %u\n", ntohl(received_msg->distance));
326#endif 379#endif
327 380
328 handle->receive_handler(handle->receive_cls, 381 handle->receive_handler(handle->receive_cls,
329 &received_msg->sender, 382 &received_msg->sender,
330 packed_msg, 383 packed_msg,
331 packed_msg_len, 384 packed_msg_len,
332 ntohl(received_msg->distance), 385 ntohl(received_msg->distance),
333 sender_address, 386 sender_address,
334 sender_address_len); 387 sender_address_len);
388
389 GNUNET_free(sender_address);
390 break;
391 case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT:
392 if (ntohs(msg->size) < sizeof(struct GNUNET_DV_SendResultMessage))
393 return;
335 394
336 GNUNET_free(sender_address); 395 send_result_msg = (struct GNUNET_DV_SendResultMessage *)msg;
396 hash_from_uid(ntohl(send_result_msg->uid), &uidhash);
397 send_ctx = GNUNET_CONTAINER_multihashmap_get(handle->send_callbacks, &uidhash);
398 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "got uid of %u or %u, hash of %s !!!!\n", ntohl(send_result_msg->uid), send_result_msg->uid, GNUNET_h2s(&uidhash));
337 399
400 if ((send_ctx != NULL) && (send_ctx->cont != NULL))
401 {
402#if DEBUG_DV
403 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "dv api notifies transport of send result (%u)!\n", ntohl(send_result_msg->result));
404#endif
405 if (ntohl(send_result_msg->result) == 0)
406 {
407 send_ctx->cont(send_ctx->cont_cls, &send_ctx->target, GNUNET_OK);
408 }
409 else
410 {
411 send_ctx->cont(send_ctx->cont_cls, &send_ctx->target, GNUNET_SYSERR);
412 }
413 }
414 GNUNET_free_non_null(send_ctx);
415 break;
416 default:
417 break;
418 }
338 GNUNET_CLIENT_receive (handle->client, 419 GNUNET_CLIENT_receive (handle->client,
339 &handle_message_receipt, 420 &handle_message_receipt,
340 handle, GNUNET_TIME_UNIT_FOREVER_REL); 421 handle, GNUNET_TIME_UNIT_FOREVER_REL);
@@ -361,14 +442,18 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
361 unsigned int priority, 442 unsigned int priority,
362 struct GNUNET_TIME_Relative timeout, 443 struct GNUNET_TIME_Relative timeout,
363 const void *addr, 444 const void *addr,
364 size_t addrlen) 445 size_t addrlen,
446 GNUNET_TRANSPORT_TransmitContinuation
447 cont, void *cont_cls)
365{ 448{
366 struct GNUNET_DV_SendMessage *msg; 449 struct GNUNET_DV_SendMessage *msg;
450 struct SendCallbackContext *send_ctx;
367 char *end_of_message; 451 char *end_of_message;
368 /* FIXME: Copy message to end of thingy, can't just allocate dummy! */ 452 GNUNET_HashCode uidhash;
369#if DEBUG_DV 453#if DEBUG_DV
370 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SEND called with message of size %d, address size %d, total size to send is %d\n", msgbuf_size, addrlen, sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen); 454 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SEND called with message of size %d, address size %d, total size to send is %d\n", msgbuf_size, addrlen, sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen);
371#endif 455#endif
456 dv_handle->uid_gen++;
372 msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size); 457 msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size);
373 msg->header.size = htons(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size); 458 msg->header.size = htons(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size);
374 msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND); 459 msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND);
@@ -377,12 +462,26 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
377 msg->priority = htonl(priority); 462 msg->priority = htonl(priority);
378 msg->timeout = timeout; 463 msg->timeout = timeout;
379 msg->addrlen = htonl(addrlen); 464 msg->addrlen = htonl(addrlen);
465 msg->uid = htonl(dv_handle->uid_gen);
380 memcpy(&msg[1], addr, addrlen); 466 memcpy(&msg[1], addr, addrlen);
381 end_of_message = (char *)&msg[1]; 467 end_of_message = (char *)&msg[1];
382 end_of_message = &end_of_message[addrlen]; 468 end_of_message = &end_of_message[addrlen];
383 memcpy(end_of_message, msgbuf, msgbuf_size); 469 memcpy(end_of_message, msgbuf, msgbuf_size);
384 add_pending(dv_handle, msg); 470 add_pending(dv_handle, msg);
385 471
472 send_ctx = GNUNET_malloc(sizeof(struct SendCallbackContext));
473
474 send_ctx->cont = cont;
475 if (cont == NULL)
476 fprintf(stderr, "DV_SEND called with null continuation!\n");
477 send_ctx->cont_cls = cont_cls;
478 memcpy(&send_ctx->target, target, sizeof(struct GNUNET_PeerIdentity));
479
480 hash_from_uid(dv_handle->uid_gen, &uidhash);
481
482 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "set uid of %u or %u, hash of %s !!!!\n", dv_handle->uid_gen, htonl(dv_handle->uid_gen), GNUNET_h2s(&uidhash));
483 GNUNET_CONTAINER_multihashmap_put(dv_handle->send_callbacks, &uidhash, send_ctx, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
484
386 return GNUNET_OK; 485 return GNUNET_OK;
387} 486}
388 487
@@ -464,6 +563,8 @@ GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched,
464 GNUNET_YES, 563 GNUNET_YES,
465 &transmit_start, start_context); 564 &transmit_start, start_context);
466 565
566 handle->send_callbacks = GNUNET_CONTAINER_multihashmap_create(100);
567
467 GNUNET_CLIENT_receive (handle->client, 568 GNUNET_CLIENT_receive (handle->client,
468 &handle_message_receipt, 569 &handle_message_receipt,
469 handle, GNUNET_TIME_UNIT_FOREVER_REL); 570 handle, GNUNET_TIME_UNIT_FOREVER_REL);