diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-03-05 21:49:42 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-03-05 21:49:42 +0000 |
commit | 9b187e018ab2565f4ce119eda94f916ec053cc7e (patch) | |
tree | dc212a097dc9f6a9e2c0dd4f2b10bd577b834bff /src/gns/gns_api.c | |
parent | 3ed2943313b62b41fa92b90eb92d5bd9bbce7843 (diff) | |
download | gnunet-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.c | 371 |
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 | */ | ||
144 | struct 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 | */ |
236 | static int | 270 | static int |
237 | add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) | 271 | add_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 | */ | ||
299 | static int | ||
300 | add_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 | */ |
427 | static int | 494 | static int |
428 | process_reply (void *cls, const GNUNET_HashCode * key, void *value) | 495 | process_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 | */ | ||
546 | static int | ||
547 | process_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 | |||
477 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 597 | message_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 | */ |
569 | struct GNUNET_GNS_LookupHandle * | 688 | struct GNUNET_GNS_LookupHandle * |
570 | GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, | 689 | GNUNET_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, | |||
628 | void | 745 | void |
629 | GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) | 746 | GNUNET_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 | */ | ||
761 | struct GNUNET_GNS_ShortenHandle * | ||
762 | GNUNET_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 */ |