summaryrefslogtreecommitdiff
path: root/src/gns/gns_api.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-03-05 21:49:42 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-03-05 21:49:42 +0000
commit9b187e018ab2565f4ce119eda94f916ec053cc7e (patch)
treedc212a097dc9f6a9e2c0dd4f2b10bd577b834bff /src/gns/gns_api.c
parent3ed2943313b62b41fa92b90eb92d5bd9bbce7843 (diff)
downloadgnunet-9b187e018ab2565f4ce119eda94f916ec053cc7e.tar.gz
gnunet-9b187e018ab2565f4ce119eda94f916ec053cc7e.zip
-started some gns service api
Diffstat (limited to 'src/gns/gns_api.c')
-rw-r--r--src/gns/gns_api.c371
1 files changed, 272 insertions, 99 deletions
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c
index ec9c15979..521ddce87 100644
--- a/src/gns/gns_api.c
+++ b/src/gns/gns_api.c
@@ -19,7 +19,6 @@
19*/ 19*/
20 20
21/** 21/**
22 * TODO: Do we really need a client API?
23 * 22 *
24 * @file gns/gns_api.c 23 * @file gns/gns_api.c
25 * @brief library to access the GNS service 24 * @brief library to access the GNS service
@@ -42,7 +41,9 @@
42 41
43/* TODO into gnunet_protocols */ 42/* TODO into gnunet_protocols */
44#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP 23 43#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP 23
45#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT 24 44#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP_RESULT 24
45#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN 25
46#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT 26
46 47
47/** 48/**
48 * Entry in our list of messages to be (re-)transmitted. 49 * Entry in our list of messages to be (re-)transmitted.
@@ -82,11 +83,6 @@ struct PendingMessage
82 void *cont_cls; 83 void *cont_cls;
83 84
84 /** 85 /**
85 * Timeout task for this message
86 */
87 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
88
89 /**
90 * Unique ID for this request 86 * Unique ID for this request
91 */ 87 */
92 uint64_t unique_id; 88 uint64_t unique_id;
@@ -141,6 +137,43 @@ struct GNUNET_GNS_LookupHandle
141 137
142}; 138};
143 139
140
141/**
142 * Handle to a shorten request
143 */
144struct GNUNET_GNS_ShortenHandle
145{
146
147 /**
148 * Processor to call on data receipt
149 */
150 GNUNET_GNS_ShortenResultProcessor proc;
151
152 /**
153 * Closure for the processor
154 */
155 void *proc_cls;
156
157 /**
158 * Main handle to this GNS api
159 */
160 struct GNUNET_GNS_Handle *gns_handle;
161
162 /**
163 * Key that this get request is for
164 */
165 GNUNET_HashCode key;
166
167 /**
168 * Unique identifier for this request (for key collisions).
169 */
170 uint64_t unique_id;
171
172 struct PendingMessage *message;
173
174};
175
176
144/** 177/**
145 * Connection to the GNS service. 178 * Connection to the GNS service.
146 */ 179 */
@@ -173,9 +206,10 @@ struct GNUNET_GNS_Handle
173 struct PendingMessage *pending_tail; 206 struct PendingMessage *pending_tail;
174 207
175 /** 208 /**
176 * Hash map containing the current outstanding unique requests. 209 * Hash maps containing the current outstanding unique requests.
177 */ 210 */
178 struct GNUNET_CONTAINER_MultiHashMap *active_requests; 211 struct GNUNET_CONTAINER_MultiHashMap *active_lookup_requests;
212 struct GNUNET_CONTAINER_MultiHashMap *active_shorten_requests;
179 213
180 GNUNET_SCHEDULER_TaskIdentifier reconnect_task; 214 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
181 215
@@ -234,25 +268,55 @@ try_connect (struct GNUNET_GNS_Handle *handle)
234 * @return GNUNET_YES (always) 268 * @return GNUNET_YES (always)
235 */ 269 */
236static int 270static int
237add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) 271add_lookup_request_to_pending (void *cls, const GNUNET_HashCode * key,
272 void *value)
238{ 273{
239 struct GNUNET_GNS_Handle *handle = cls; 274 struct GNUNET_GNS_Handle *handle = cls;
240 struct GNUNET_GNS_LookupHandle *rh = value; 275 struct GNUNET_GNS_LookupHandle *lh = value;
241 276
242 if (GNUNET_NO == rh->message->in_pending_queue) 277 if (GNUNET_NO == lh->message->in_pending_queue)
243 { 278 {
244#if DEBUG_DHT 279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
245 LOG (GNUNET_ERROR_TYPE_DEBUG,
246 "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key), 280 "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key),
247 handle); 281 handle);
248#endif
249 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, 282 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
250 rh->message); 283 lh->message);
251 rh->message->in_pending_queue = GNUNET_YES; 284 lh->message->in_pending_queue = GNUNET_YES;
252 } 285 }
253 return GNUNET_YES; 286 return GNUNET_YES;
254} 287}
255 288
289
290/**
291 * Add the request corresponding to the given handle
292 * to the pending queue (if it is not already in there).
293 *
294 * @param cls the 'struct GNUNET_GNS_Handle*'
295 * @param key key for the request (not used)
296 * @param value the 'struct GNUNET_GNS_ShortenHandle*'
297 * @return GNUNET_YES (always)
298 */
299static int
300add_shorten_request_to_pending (void *cls, const GNUNET_HashCode * key,
301 void *value)
302{
303 struct GNUNET_GNS_Handle *handle = cls;
304 struct GNUNET_GNS_ShortenHandle *sh = value;
305
306 if (GNUNET_NO == sh->message->in_pending_queue)
307 {
308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
309 "Retransmitting shorten request related to %s to GNS %p\n",
310 GNUNET_h2s(key),
311 handle);
312 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
313 sh->message);
314 sh->message->in_pending_queue = GNUNET_YES;
315 }
316 return GNUNET_YES;
317}
318
319
256/** 320/**
257 * Try reconnecting to the GNS service. 321 * Try reconnecting to the GNS service.
258 * 322 *
@@ -264,9 +328,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
264{ 328{
265 struct GNUNET_GNS_Handle *handle = cls; 329 struct GNUNET_GNS_Handle *handle = cls;
266 330
267#if DEBUG_GNS 331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle);
268 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle);
269#endif
270 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 332 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
271 if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value) 333 if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value)
272 handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY; 334 handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY;
@@ -277,13 +339,13 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
277 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 339 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
278 if (GNUNET_YES != try_connect (handle)) 340 if (GNUNET_YES != try_connect (handle))
279 { 341 {
280#if DEBUG_GNS 342 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n");
281 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n");
282#endif
283 return; 343 return;
284 } 344 }
285 GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, 345 GNUNET_CONTAINER_multihashmap_iterate (handle->active_lookup_requests,
286 &add_request_to_pending, handle); 346 &add_lookup_request_to_pending, handle);
347 GNUNET_CONTAINER_multihashmap_iterate (handle->active_shorten_requests,
348 &add_shorten_request_to_pending, handle);
287 process_pending_messages (handle); 349 process_pending_messages (handle);
288} 350}
289 351
@@ -337,14 +399,17 @@ process_pending_messages (struct GNUNET_GNS_Handle *handle)
337 if (handle->client == NULL) 399 if (handle->client == NULL)
338 { 400 {
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
340 "process_pending_messages called, but client is null, reconnecting\n"); 402 "process_pending_messages called, but client is null, reconnecting\n");
341 do_disconnect (handle); 403 do_disconnect (handle);
342 return; 404 return;
343 } 405 }
406
344 if (handle->th != NULL) 407 if (handle->th != NULL)
345 return; 408 return;
409
346 if (NULL == (head = handle->pending_head)) 410 if (NULL == (head = handle->pending_head))
347 return; 411 return;
412
348 handle->th = 413 handle->th =
349 GNUNET_CLIENT_notify_transmit_ready (handle->client, 414 GNUNET_CLIENT_notify_transmit_ready (handle->client,
350 ntohs (head->msg->size), 415 ntohs (head->msg->size),
@@ -370,6 +435,7 @@ transmit_pending (void *cls, size_t size, void *buf)
370 size_t tsize; 435 size_t tsize;
371 436
372 handle->th = NULL; 437 handle->th = NULL;
438
373 if (buf == NULL) 439 if (buf == NULL)
374 { 440 {
375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -377,36 +443,37 @@ transmit_pending (void *cls, size_t size, void *buf)
377 do_disconnect (handle); 443 do_disconnect (handle);
378 return 0; 444 return 0;
379 } 445 }
446
380 if (NULL == (head = handle->pending_head)) 447 if (NULL == (head = handle->pending_head))
381 return 0; 448 return 0;
382 449
383 tsize = ntohs (head->msg->size); 450 tsize = ntohs (head->msg->size);
451
384 if (size < tsize) 452 if (size < tsize)
385 { 453 {
386 process_pending_messages (handle); 454 process_pending_messages (handle);
387 return 0; 455 return 0;
388 } 456 }
457
389 memcpy (buf, head->msg, tsize); 458 memcpy (buf, head->msg, tsize);
459
390 GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, 460 GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail,
391 head); 461 head);
462
392 head->in_pending_queue = GNUNET_NO; 463 head->in_pending_queue = GNUNET_NO;
393 if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) 464
394 {
395 GNUNET_SCHEDULER_cancel (head->timeout_task);
396 head->timeout_task = GNUNET_SCHEDULER_NO_TASK;
397 }
398 if (GNUNET_YES == head->free_on_send) 465 if (GNUNET_YES == head->free_on_send)
399 GNUNET_free (head); 466 GNUNET_free (head);
467
400 process_pending_messages (handle); 468 process_pending_messages (handle);
401#if DEBUG_GNS 469
402 LOG (GNUNET_ERROR_TYPE_DEBUG, 470 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
403 "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize); 471 "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize);
404#endif 472
405 if (GNUNET_NO == handle->in_receive) 473 if (GNUNET_NO == handle->in_receive)
406 { 474 {
407#if DEBUG_GNS 475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
408 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from GNS\n"); 476 "Starting to process replies from GNS\n");
409#endif
410 handle->in_receive = GNUNET_YES; 477 handle->in_receive = GNUNET_YES;
411 GNUNET_CLIENT_receive (handle->client, &message_handler, handle, 478 GNUNET_CLIENT_receive (handle->client, &message_handler, handle,
412 GNUNET_TIME_UNIT_FOREVER_REL); 479 GNUNET_TIME_UNIT_FOREVER_REL);
@@ -425,48 +492,101 @@ transmit_pending (void *cls, size_t size, void *buf)
425 * GNUNET_NO if the reply is malformed 492 * GNUNET_NO if the reply is malformed
426 */ 493 */
427static int 494static int
428process_reply (void *cls, const GNUNET_HashCode * key, void *value) 495process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value)
429{ 496{
430 const struct GNUNET_GNS_ClientResultMessage *gns_msg = cls; 497 const struct GNUNET_GNS_ClientShortenResultMessage *gns_msg = cls;
431 struct GNUNET_GNS_LookupHandle *lookup_handle = value; 498 struct GNUNET_GNS_ShortenHandle *shorten_handle = value;
432 const char *name = (const char*) &lookup_handle[1]; 499 const char *name = (const char*) &shorten_handle[1];
433 const struct GNUNET_NAMESTORE_RecordData *records; 500 const char *short_name;
434 uint32_t num_records;
435 size_t meta_length;
436 size_t msize;
437 501
438 if (gns_msg->unique_id != lookup_handle->unique_id) 502 if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) <
503 sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
504 {
505 GNUNET_break (0);
506 do_disconnect (shorten_handle->gns_handle);
507 return GNUNET_NO;
508 }
509
510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
511 "Received reply for `%s' from GNS service %p\n",
512 name, shorten_handle->gns_handle);
513
514 if (gns_msg->unique_id != shorten_handle->unique_id)
439 { 515 {
440 /* UID mismatch */ 516 /* UID mismatch */
441#if DEBUG_GNS 517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
442 LOG (GNUNET_ERROR_TYPE_DEBUG,
443 "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), 518 "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
444 gns_msg->unique_id, lookup_handle->unique_id); 519 gns_msg->unique_id, shorten_handle->unique_id);
445#endif
446 return GNUNET_YES; 520 return GNUNET_YES;
447 } 521 }
448 msize = ntohs (gns_msg->header.size); 522 short_name = (char*)&gns_msg[1];
449 num_records = ntohl (gns_msg->num_records); 523
450 meta_length = 524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
451 sizeof (struct GNUNET_GNS_ClientResultMessage) + 525 "Giving shorten reply %s for %s to application\n",
452 sizeof (struct GNUNET_NAMESTORE_RecordData) * (num_records); 526 short_name, name);
453 if ((msize < meta_length) || 527
454 (num_records > 528 shorten_handle->proc (shorten_handle->proc_cls, name, short_name);
455 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_NAMESTORE_RecordData))) 529
530 GNUNET_CLIENT_receive (shorten_handle->gns_handle->client,
531 &message_handler, shorten_handle->gns_handle,
532 GNUNET_TIME_UNIT_FOREVER_REL);
533 return GNUNET_YES;
534}
535
536
537/**
538 * Process a given reply to the lookup request
539 *
540 * @param cls the 'struct GNUNET_GNS_ClientResultMessage'
541 * @param key query of the request
542 * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key
543 * @return GNUNET_YES to continue to iterate over all results,
544 * GNUNET_NO if the reply is malformed
545 */
546static int
547process_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value)
548{
549 const struct GNUNET_GNS_ClientLookupResultMessage *gns_msg = cls;
550 struct GNUNET_GNS_LookupHandle *lookup_handle = value;
551 const char *name = (const char*) &lookup_handle[1];
552 struct GNUNET_NAMESTORE_RecordData *rd;
553 uint32_t rd_count;
554
555 if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) <
556 sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
456 { 557 {
457 GNUNET_break (0); 558 GNUNET_break (0);
559 do_disconnect (lookup_handle->gns_handle);
458 return GNUNET_NO; 560 return GNUNET_NO;
459 } 561 }
460#if DEBUG_GNS 562
461 LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n", 563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
462 (unsigned int) (msize - meta_length), GNUNET_h2s (key)); 564 "Received lookup reply for `%s' from GNS service %p\n",
463#endif 565 name, lookup_handle->gns_handle);
464 records = (const struct GNUNET_NAMESTORE_RecordData *) &gns_msg[1]; 566
465 lookup_handle->iter (lookup_handle->iter_cls, name, records, num_records); 567 if (gns_msg->unique_id != lookup_handle->unique_id)
568 {
569 /* UID mismatch */
570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
571 "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
572 gns_msg->unique_id, lookup_handle->unique_id);
573 return GNUNET_YES;
574 }
575
576 rd_count = ntohl(gns_msg->rd_count);
577 rd = (struct GNUNET_NAMESTORE_RecordData*)&gns_msg[1];
578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
579 "Giving lookup reply for %s to application\n",
580 name);
581
582 lookup_handle->iter (lookup_handle->iter_cls, name, rd_count, rd);
583
584 GNUNET_CLIENT_receive (lookup_handle->gns_handle->client, &message_handler,
585 lookup_handle->gns_handle,
586 GNUNET_TIME_UNIT_FOREVER_REL);
466 return GNUNET_YES; 587 return GNUNET_YES;
467} 588}
468 589
469
470/** 590/**
471 * Handler for messages received from the GNS service 591 * Handler for messages received from the GNS service
472 * 592 *
@@ -477,40 +597,40 @@ static void
477message_handler (void *cls, const struct GNUNET_MessageHeader *msg) 597message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
478{ 598{
479 struct GNUNET_GNS_Handle *handle = cls; 599 struct GNUNET_GNS_Handle *handle = cls;
480 const struct GNUNET_GNS_ClientResultMessage *gns_msg; 600 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
601 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
481 602
482 if (msg == NULL) 603 if (msg == NULL)
483 { 604 {
484#if DEBUG_GNS 605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485 LOG (GNUNET_ERROR_TYPE_DEBUG,
486 "Error receiving data from GNS service, reconnecting\n"); 606 "Error receiving data from GNS service, reconnecting\n");
487#endif
488 do_disconnect (handle); 607 do_disconnect (handle);
489 return; 608 return;
490 } 609 }
491 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT) 610
611 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP_RESULT)
492 { 612 {
493 GNUNET_break (0); 613 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
494 do_disconnect (handle); 614 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_lookup_requests,
495 return; 615 &lookup_msg->key,
616 &process_lookup_reply,
617 (void *) lookup_msg);
496 } 618 }
497 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientResultMessage)) 619 else if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT)
620 {
621 shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg;
622 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_shorten_requests,
623 &shorten_msg->key,
624 &process_shorten_reply,
625 (void *) shorten_msg);
626 }
627 else
498 { 628 {
499 GNUNET_break (0); 629 GNUNET_break (0);
500 do_disconnect (handle); 630 do_disconnect (handle);
501 return; 631 return;
502 } 632 }
503 gns_msg = (const struct GNUNET_GNS_ClientResultMessage *) msg; 633
504#if DEBUG_GNS
505 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from GNS service %p\n",
506 &gns_msg->name, handle);
507#endif
508 /* TODO uniquely identify requests... maybe hash(name) or uid */
509 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests,
510 &gns_msg->key, &process_reply,
511 (void *) gns_msg);
512 GNUNET_CLIENT_receive (handle->client, &message_handler, handle,
513 GNUNET_TIME_UNIT_FOREVER_REL);
514} 634}
515 635
516 636
@@ -531,7 +651,10 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
531 handle->cfg = cfg; 651 handle->cfg = cfg;
532 handle->uid_gen = 652 handle->uid_gen =
533 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 653 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
534 handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); 654 handle->active_lookup_requests =
655 GNUNET_CONTAINER_multihashmap_create (ht_len);
656 handle->active_shorten_requests =
657 GNUNET_CONTAINER_multihashmap_create (ht_len);
535 if (GNUNET_NO == try_connect (handle)) 658 if (GNUNET_NO == try_connect (handle))
536 { 659 {
537 GNUNET_GNS_disconnect (handle); 660 GNUNET_GNS_disconnect (handle);
@@ -555,12 +678,8 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
555 678
556/** 679/**
557 * Perform an asynchronous Lookup operation on the GNS. 680 * Perform an asynchronous Lookup operation on the GNS.
558 * TODO:
559 * - Still not sure what we query for... "names" it is for now
560 * - Do we need such sophisticated message queueing like dht? simplify?
561 * 681 *
562 * @param handle handle to the GNS service 682 * @param handle handle to the GNS service
563 * @param timeout how long to wait for transmission of this request to the service
564 * @param name the name to look up 683 * @param name the name to look up
565 * @param iter function to call on each result 684 * @param iter function to call on each result
566 * @param iter_cls closure for iter 685 * @param iter_cls closure for iter
@@ -568,7 +687,6 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
568 */ 687 */
569struct GNUNET_GNS_LookupHandle * 688struct GNUNET_GNS_LookupHandle *
570GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, 689GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
571 struct GNUNET_TIME_Relative timeout,
572 const char * name, 690 const char * name,
573 enum GNUNET_GNS_RecordType type, 691 enum GNUNET_GNS_RecordType type,
574 GNUNET_GNS_LookupIterator iter, 692 GNUNET_GNS_LookupIterator iter,
@@ -589,10 +707,8 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
589 GNUNET_CRYPTO_hash (name, strlen(name), &key); 707 GNUNET_CRYPTO_hash (name, strlen(name), &key);
590 708
591 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name); 709 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name);
592#if DEBUG_GNS 710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n",
593 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n", 711 name, handle);
594 name, handle);
595#endif
596 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); 712 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
597 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; 713 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
598 pending->msg = &lookup_msg->header; 714 pending->msg = &lookup_msg->header;
@@ -612,9 +728,10 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
612 lookup_handle->iter_cls = iter_cls; 728 lookup_handle->iter_cls = iter_cls;
613 lookup_handle->message = pending; 729 lookup_handle->message = pending;
614 lookup_handle->unique_id = lookup_msg->unique_id; 730 lookup_handle->unique_id = lookup_msg->unique_id;
615 GNUNET_CONTAINER_multihashmap_put (handle->active_requests, &lookup_msg->key, 731 GNUNET_CONTAINER_multihashmap_put (handle->active_lookup_requests,
616 lookup_handle, 732 &lookup_msg->key,
617 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 733 lookup_handle,
734 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
618 process_pending_messages (handle); 735 process_pending_messages (handle);
619 return lookup_handle; 736 return lookup_handle;
620} 737}
@@ -628,8 +745,64 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
628void 745void
629GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) 746GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle)
630{ 747{
631 /* TODO Stop dht lookups */ 748 /* TODO Stop gns lookups */
749}
750
751
752/**
753 * Perform a name shortening operation on the GNS.
754 *
755 * @param handle handle to the GNS service
756 * @param name the name to look up
757 * @param proc function to call on result
758 * @param proc_cls closure for processor
759 * @return handle to the operation
760 */
761struct GNUNET_GNS_ShortenHandle *
762GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
763 const char * name,
764 GNUNET_GNS_ShortenResultProcessor proc,
765 void *proc_cls)
766{
767 /* IPC to shorten gns names, return shorten_handle */
768 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
769 struct GNUNET_GNS_ShortenHandle *shorten_handle;
770 size_t msize;
771 struct PendingMessage *pending;
772
773 if (NULL == name)
774 {
775 return NULL;
776 }
777
778 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name);
779 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name);
780 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
781 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
782 pending->msg = &shorten_msg->header;
783 pending->handle = handle;
784 pending->free_on_send = GNUNET_NO;
785 shorten_msg->header.size = htons (msize);
786 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN);
787 memcpy(&shorten_msg[1], name, strlen(name));
788 handle->uid_gen++;
789 shorten_msg->unique_id = handle->uid_gen;
790 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
791 pending);
792 pending->in_pending_queue = GNUNET_YES;
793 shorten_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupHandle));
794 shorten_handle->proc = proc;
795 shorten_handle->proc_cls = proc_cls;
796 shorten_handle->message = pending;
797 shorten_handle->unique_id = shorten_msg->unique_id;
798 GNUNET_CONTAINER_multihashmap_put (handle->active_shorten_requests,
799 &shorten_msg->key,
800 shorten_handle,
801 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
802 process_pending_messages (handle);
803 return shorten_handle;
632} 804}
633 805
634 806
807
635/* end of gns_api.c */ 808/* end of gns_api.c */