aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-04-19 15:16:38 +0000
committerNathan S. Evans <evans@in.tum.de>2010-04-19 15:16:38 +0000
commitc5fee7d95eaa1695999c12d059b0aa4bc566d836 (patch)
tree062ba8d6e248ccb219d081bfcab6ed3790f95676 /src/dht/gnunet-service-dht.c
parentc268decf67ed3178b8f9beee5b6fff11ee0c0037 (diff)
downloadgnunet-c5fee7d95eaa1695999c12d059b0aa4bc566d836.tar.gz
gnunet-c5fee7d95eaa1695999c12d059b0aa4bc566d836.zip
dht api fixes, it works again (for me)
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c172
1 files changed, 74 insertions, 98 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index 8907c3642..27c431bd5 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -166,7 +166,7 @@ struct DHT_MessageContext
166 /** 166 /**
167 * The key this request was about 167 * The key this request was about
168 */ 168 */
169 GNUNET_HashCode *key; 169 const GNUNET_HashCode *key;
170 170
171 /** 171 /**
172 * The unique identifier of this request 172 * The unique identifier of this request
@@ -240,9 +240,6 @@ send_generic_reply (void *cls, size_t size, void *buf)
240 if (buf == NULL) 240 if (buf == NULL)
241 { 241 {
242 /* client disconnected */ 242 /* client disconnected */
243#if DEBUG_DHT
244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s': buffer was NULL\n", "DHT");
245#endif
246 return 0; 243 return 0;
247 } 244 }
248 off = 0; 245 off = 0;
@@ -256,10 +253,6 @@ send_generic_reply (void *cls, size_t size, void *buf)
256 GNUNET_free (reply); 253 GNUNET_free (reply);
257 off += msize; 254 off += msize;
258 } 255 }
259#if DEBUG_DHT
260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261 "`%s': Copying reply to buffer, REALLY SENT\n", "DHT");
262#endif
263 process_pending_messages (client); 256 process_pending_messages (client);
264 return off; 257 return off;
265} 258}
@@ -284,7 +277,7 @@ add_pending_message (struct ClientList *client,
284 277
285 278
286/** 279/**
287 * Called when a reply needs to be sent to a client, either as 280 * Called when a reply needs to be sent to a client, as
288 * a result it found to a GET or FIND PEER request. 281 * a result it found to a GET or FIND PEER request.
289 * 282 *
290 * @param client the client to send the reply to 283 * @param client the client to send the reply to
@@ -296,7 +289,7 @@ send_reply_to_client (struct ClientList *client,
296 const struct GNUNET_MessageHeader *message, 289 const struct GNUNET_MessageHeader *message,
297 unsigned long long uid) 290 unsigned long long uid)
298{ 291{
299 struct GNUNET_DHT_Message *reply; 292 struct GNUNET_DHT_RouteResultMessage *reply;
300 struct PendingMessage *pending_message; 293 struct PendingMessage *pending_message;
301 uint16_t msize; 294 uint16_t msize;
302 size_t tsize; 295 size_t tsize;
@@ -305,21 +298,21 @@ send_reply_to_client (struct ClientList *client,
305 "`%s': Sending reply to client.\n", "DHT"); 298 "`%s': Sending reply to client.\n", "DHT");
306#endif 299#endif
307 msize = ntohs (message->size); 300 msize = ntohs (message->size);
308 tsize = sizeof (struct GNUNET_DHT_Message) + msize; 301 tsize = sizeof (struct GNUNET_DHT_RouteResultMessage) + msize;
309 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 302 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
310 { 303 {
311 GNUNET_BREAK_op (0); 304 GNUNET_break_op (0);
312 return; 305 return;
313 } 306 }
314 reply = GNUNET_malloc (tsize); 307
308 pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + tsize);
309 pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
310 reply = (struct GNUNET_DHT_RouteResultMessage *)&pending_message[1];
315 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_ROUTE_RESULT); 311 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_ROUTE_RESULT);
316 reply->header.size = htons (tsize); 312 reply->header.size = htons (tsize);
317 if (uid != 0)
318 reply->unique = htonl (GNUNET_YES); // ????
319 reply->unique_id = GNUNET_htonll (uid); 313 reply->unique_id = GNUNET_htonll (uid);
320 memcpy (&reply[1], message, msize); 314 memcpy (&reply[1], message, msize);
321 pending_message = GNUNET_malloc (sizeof (struct PendingMessage)); // inline 315
322 pending_message->msg = &reply->header;
323 add_pending_message (client, pending_message); 316 add_pending_message (client, pending_message);
324} 317}
325 318
@@ -354,7 +347,6 @@ datacache_get_iterator (void *cls,
354 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT); 347 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT);
355 get_result->header.size = 348 get_result->header.size =
356 htons (sizeof (struct GNUNET_DHT_GetResultMessage) + size); 349 htons (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
357 get_result->data_size = htons (size);
358 get_result->expiration = exp; 350 get_result->expiration = exp;
359 memcpy (&get_result->key, key, sizeof (GNUNET_HashCode)); 351 memcpy (&get_result->key, key, sizeof (GNUNET_HashCode));
360 get_result->type = htons (type); 352 get_result->type = htons (type);
@@ -383,12 +375,13 @@ handle_dht_get (void *cls,
383 unsigned int results; 375 unsigned int results;
384 struct DatacacheGetContext datacache_get_context; 376 struct DatacacheGetContext datacache_get_context;
385 377
386 if (ntohs (msg->header.size) != sizeof (struct GNUNET_DHT_GetMessage)) 378 get_msg = (const struct GNUNET_DHT_GetMessage *) msg;
379 if (ntohs (get_msg->header.size) != sizeof (struct GNUNET_DHT_GetMessage))
387 { 380 {
388 GNUNET_break (0); 381 GNUNET_break (0);
389 return; 382 return;
390 } 383 }
391 get_msg = (const struct GNUNET_DHT_GetMessage *) msg; 384
392 get_type = ntohs (get_msg->type); 385 get_type = ntohs (get_msg->type);
393#if DEBUG_DHT 386#if DEBUG_DHT
394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 387 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -422,7 +415,7 @@ handle_dht_find_peer (void *cls,
422 const struct GNUNET_MessageHeader *find_msg, 415 const struct GNUNET_MessageHeader *find_msg,
423 struct DHT_MessageContext *message_context) 416 struct DHT_MessageContext *message_context)
424{ 417{
425 struct GNUNET_DHT_FindPeerResultMessage *find_peer_result; 418 struct GNUNET_MessageHeader *find_peer_result;
426 size_t hello_size; 419 size_t hello_size;
427 size_t tsize; 420 size_t tsize;
428 421
@@ -430,8 +423,8 @@ handle_dht_find_peer (void *cls,
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
431 "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n", 424 "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n",
432 "DHT", "FIND PEER", GNUNET_h2s (message_context->key), 425 "DHT", "FIND PEER", GNUNET_h2s (message_context->key),
433 ntohs (find_msg->header.size), 426 ntohs (find_msg->size),
434 sizeof (struct GNUNET_DHT_FindPeerMessage)); 427 sizeof (struct GNUNET_MessageHeader));
435#endif 428#endif
436 if (my_hello == NULL) 429 if (my_hello == NULL)
437 { 430 {
@@ -444,13 +437,18 @@ handle_dht_find_peer (void *cls,
444 } 437 }
445 /* Simplistic find_peer functionality, always return our hello */ 438 /* Simplistic find_peer functionality, always return our hello */
446 hello_size = ntohs(my_hello->size); 439 hello_size = ntohs(my_hello->size);
447 tsize = hello_size + sizeof (struct GNUNET_DHT_FindPeerResultMessage); 440 tsize = hello_size + sizeof (struct GNUNET_MessageHeader);
448 // check tsize < MAX 441 // check tsize < MAX
449 find_peer_result = GNUNET_malloc (tsize); 442 find_peer_result = GNUNET_malloc (tsize);
450 find_peer_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT); 443 find_peer_result->type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT);
451 find_peer_result->header.size = htons (tsize); 444 find_peer_result->size = htons (tsize);
452 memcpy (&find_peer_result[1], &my_hello, hello_size); 445 memcpy (&find_peer_result[1], my_hello, hello_size);
453 send_reply_to_client(message_context->client, &find_peer_result->header, message_context->unique_id); 446#if DEBUG_DHT_HELLO
447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
448 "`%s': Sending hello size %d to client.\n",
449 "DHT", hello_size);
450#endif
451 send_reply_to_client(message_context->client, find_peer_result, message_context->unique_id);
454 GNUNET_free(find_peer_result); 452 GNUNET_free(find_peer_result);
455} 453}
456 454
@@ -471,24 +469,24 @@ handle_dht_put (void *cls,
471 size_t put_type; 469 size_t put_type;
472 size_t data_size; 470 size_t data_size;
473 471
474 GNUNET_assert (ntohs (msg->header.size) >= 472 GNUNET_assert (ntohs (msg->size) >=
475 sizeof (struct GNUNET_DHT_PutMessage)); 473 sizeof (struct GNUNET_DHT_PutMessage));
476 put_msg = (struct GNUNET_DHT_PutMessage *)msg; 474 put_msg = (struct GNUNET_DHT_PutMessage *)msg;
477 put_type = ntohl (put_msg->type); 475 put_type = ntohs (put_msg->type);
478 data_size = ntohs (put_msg->header.size) - sizeof (struct GNUNET_DHT_PutMessage); 476 data_size = ntohs (put_msg->header.size) - sizeof (struct GNUNET_DHT_PutMessage);
479#if DEBUG_DHT 477#if DEBUG_DHT
480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
481 "`%s': %s msg total size is %d, data size %d, struct size %d\n",
482 "DHT", "PUT", ntohs (put_msg->header.size), data_size,
483 sizeof (struct GNUNET_DHT_PutMessage));
484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485 "`%s': Received `%s' request from client, message type %d, key %s\n", 479 "`%s': Received `%s' request from client, message type %d, key %s\n",
486 "DHT", "PUT", put_type, GNUNET_h2s (message_context->key)); 480 "DHT", "PUT", put_type, GNUNET_h2s (message_context->key));
487#endif 481#endif
488 if (datacache != NULL) 482 if (datacache != NULL)
489 GNUNET_DATACACHE_put (datacache, message_context->key, data_size, 483 GNUNET_DATACACHE_put (datacache, message_context->key, data_size,
490 (char *) &put_msg[1], put_type, 484 (char *) &put_msg[1], put_type,
491 put_msg->expiration); 485 GNUNET_TIME_absolute_ntoh(put_msg->expiration));
486 else
487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
488 "`%s': %s request received locally, but have no datacache!\n",
489 "DHT", "PUT");
492} 490}
493 491
494 492
@@ -520,41 +518,6 @@ find_active_client (struct GNUNET_SERVER_Client *client)
520} 518}
521 519
522/** 520/**
523 * Construct a message receipt confirmation for a particular uid.
524 * Receipt confirmations are used for any requests that don't expect
525 * a reply otherwise (i.e. put requests, stop requests).
526 *
527 * @param client the handle for the client
528 * @param uid the unique identifier of this message
529 */
530static void
531send_client_receipt_confirmation (struct GNUNET_SERVER_Client *client,
532 uint64_t uid)
533{
534 struct GNUNET_DHT_StopMessage *confirm_message;
535 struct ClientList *active_client;
536 struct PendingMessage *pending_message;
537
538#if DEBUG_DHT
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
540 "`%s': Sending receipt confirmation for uid %llu\n", "DHT",
541 uid);
542#endif
543 confirm_message = GNUNET_malloc (sizeof (struct GNUNET_DHT_StopMessage));
544 confirm_message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_STOP);
545 confirm_message->header.size =
546 htons (sizeof (struct GNUNET_DHT_StopMessage));
547 confirm_message->unique_id = GNUNET_htonll (uid);
548
549 active_client = find_active_client (client);
550 pending_message = GNUNET_malloc (sizeof (struct PendingMessage));
551 pending_message->msg = &confirm_message->header;
552
553 add_pending_message (active_client, pending_message);
554
555}
556
557/**
558 * Handler for any generic DHT messages, calls the appropriate handler 521 * Handler for any generic DHT messages, calls the appropriate handler
559 * depending on message type, sends confirmation if responses aren't otherwise 522 * depending on message type, sends confirmation if responses aren't otherwise
560 * expected. 523 * expected.
@@ -567,9 +530,10 @@ static void
567handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client, 530handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client,
568 const struct GNUNET_MessageHeader *message) 531 const struct GNUNET_MessageHeader *message)
569{ 532{
570 const struct GNUNET_DHT_Message *dht_msg = (const struct GNUNET_DHT_Message *) message; 533 const struct GNUNET_DHT_RouteMessage *dht_msg = (const struct GNUNET_DHT_RouteMessage *) message;
571 const struct GNUNET_MessageHeader *enc_msg; 534 const struct GNUNET_MessageHeader *enc_msg;
572 struct DHT_MessageContext *message_context; 535 struct DHT_MessageContext *message_context;
536 int handle_locally;
573 size_t enc_type; 537 size_t enc_type;
574 538
575 enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1]; 539 enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1];
@@ -590,28 +554,37 @@ handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client,
590 message_context->replication = ntohl (dht_msg->desired_replication_level); 554 message_context->replication = ntohl (dht_msg->desired_replication_level);
591 message_context->msg_options = ntohl (dht_msg->options); 555 message_context->msg_options = ntohl (dht_msg->options);
592 556
557 /* TODO: Steps to be added by students */
593 /* FIXME: Implement *remote* DHT operations here (forward request) */ 558 /* FIXME: Implement *remote* DHT operations here (forward request) */
559 /* Implement generic route function and call here. */
594 /* FIXME: *IF* handling should be local, then do this: */ 560 /* FIXME: *IF* handling should be local, then do this: */
595 switch (enc_type) 561 /* 1. find if this peer is closest based on whatever metric the DHT uses
562 * 2. if this peer is closest _OR_ the message options indicate it should
563 * be processed everywhere _AND_ we want it processed everywhere, then
564 * handle it locally.
565 */
566 handle_locally = GNUNET_YES;
567 if (handle_locally == GNUNET_YES)
596 { 568 {
597 case GNUNET_MESSAGE_TYPE_DHT_GET: 569 switch (enc_type)
598 handle_dht_get (cls, enc_msg, 570 {
599 message_context); 571 case GNUNET_MESSAGE_TYPE_DHT_GET:
600 break; 572 handle_dht_get (cls, enc_msg,
601 case GNUNET_MESSAGE_TYPE_DHT_PUT: 573 message_context);
602 handle_dht_put (cls, enc_msg, 574 break;
603 message_context); 575 case GNUNET_MESSAGE_TYPE_DHT_PUT:
604 send_client_receipt_confirmation (client, 576 handle_dht_put (cls, enc_msg,
605 GNUNET_ntohll (dht_msg->unique_id)); 577 message_context);
606 break; 578 break;
607 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: 579 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER:
608 handle_dht_find_peer (cls, 580 handle_dht_find_peer (cls,
609 enc_msg, 581 enc_msg,
610 message_context); 582 message_context);
611 break; 583 break;
612 default: 584 default:
613 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 585 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
614 "`%s': Message type (%d) not handled\n", "DHT", enc_type); 586 "`%s': Message type (%d) not handled\n", "DHT", enc_type);
587 }
615 } 588 }
616 GNUNET_free (message_context); 589 GNUNET_free (message_context);
617 GNUNET_SERVER_receive_done (client, GNUNET_OK); 590 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -620,14 +593,14 @@ handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client,
620 593
621/** 594/**
622 * Handler for any generic DHT stop messages, calls the appropriate handler 595 * Handler for any generic DHT stop messages, calls the appropriate handler
623 * depending on message type, sends confirmation by default (stop messages 596 * depending on message type (if processed locally)
624 * do not otherwise expect replies)
625 * 597 *
626 * @param cls closure for the service 598 * @param cls closure for the service
627 * @param client the client we received this message from 599 * @param client the client we received this message from
628 * @param message the actual message received 600 * @param message the actual message received
629 * 601 *
630 * TODO: add demultiplexing for stop message types. 602 * TODO: once message are remembered by unique id, add code to
603 * forget them here
631 */ 604 */
632static void 605static void
633handle_dht_stop_message (void *cls, struct GNUNET_SERVER_Client *client, 606handle_dht_stop_message (void *cls, struct GNUNET_SERVER_Client *client,
@@ -635,13 +608,17 @@ handle_dht_stop_message (void *cls, struct GNUNET_SERVER_Client *client,
635{ 608{
636 const struct GNUNET_DHT_StopMessage *dht_stop_msg = 609 const struct GNUNET_DHT_StopMessage *dht_stop_msg =
637 (const struct GNUNET_DHT_StopMessage *) message; 610 (const struct GNUNET_DHT_StopMessage *) message;
638 611 uint64_t uid;
639#if DEBUG_DHT 612#if DEBUG_DHT
640 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
641 "`%s': Received `%s' request from client, uid %llu\n", "DHT", 614 "`%s': Received `%s' request from client, uid %llu\n", "DHT",
642 "GENERIC STOP", GNUNET_ntohll (dht_stop_msg->unique_id)); 615 "GENERIC STOP", GNUNET_ntohll (dht_stop_msg->unique_id));
643#endif 616#endif
644 /* TODO: actually stop... */ 617
618 uid = GNUNET_ntohll(dht_stop_msg->unique_id);
619 /* TODO: actually stop... free associated resources for the request
620 * lookup request by uid and remove state. */
621
645 GNUNET_SERVER_receive_done (client, GNUNET_OK); 622 GNUNET_SERVER_receive_done (client, GNUNET_OK);
646} 623}
647 624
@@ -767,14 +744,14 @@ core_init (void *cls,
767 744
768 745
769static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { 746static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
770 {&handle_dht_start_message, NULL, GNUNET_MESSAGE_TYPE_DHT, 0}, 747 {&handle_dht_start_message, NULL, GNUNET_MESSAGE_TYPE_DHT_ROUTE, 0},
771 {&handle_dht_stop_message, NULL, GNUNET_MESSAGE_TYPE_DHT_STOP, 0}, 748 {&handle_dht_stop_message, NULL, GNUNET_MESSAGE_TYPE_DHT_STOP, 0},
772 {NULL, NULL, 0, 0} 749 {NULL, NULL, 0, 0}
773}; 750};
774 751
775 752
776static struct GNUNET_CORE_MessageHandler core_handlers[] = { 753static struct GNUNET_CORE_MessageHandler core_handlers[] = {
777 {&handle_dht_p2p_route_request, GNUNET_MESSAGE_TYPE_DHT_ROUTE_REQUEST, 0}, 754 {&handle_dht_p2p_route_request, GNUNET_MESSAGE_TYPE_DHT_ROUTE, 0},
778 {&handle_dht_p2p_route_result, GNUNET_MESSAGE_TYPE_DHT_ROUTE_RESULT, 0}, 755 {&handle_dht_p2p_route_result, GNUNET_MESSAGE_TYPE_DHT_ROUTE_RESULT, 0},
779 {NULL, 0, 0} 756 {NULL, 0, 0}
780}; 757};
@@ -803,7 +780,6 @@ run (void *cls,
803 GNUNET_TIME_UNIT_FOREVER_REL, 780 GNUNET_TIME_UNIT_FOREVER_REL,
804 NULL, /* FIXME: anything we want to pass around? */ 781 NULL, /* FIXME: anything we want to pass around? */
805 &core_init, /* Call core_init once connected */ 782 &core_init, /* Call core_init once connected */
806 NULL, /* Don't care about pre-connects */
807 NULL, /* Don't care about connects */ 783 NULL, /* Don't care about connects */
808 NULL, /* Don't care about disconnects */ 784 NULL, /* Don't care about disconnects */
809 NULL, /* Don't want notified about all incoming messages */ 785 NULL, /* Don't want notified about all incoming messages */