diff options
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/Makefile.am | 4 | ||||
-rw-r--r-- | src/gns/gns.h | 44 | ||||
-rw-r--r-- | src/gns/gns_api.c | 203 | ||||
-rw-r--r-- | src/gns/gnunet-gns.c | 110 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 89 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_reverser.c | 244 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_reverser.h | 72 | ||||
-rw-r--r-- | src/gns/plugin_gnsrecord_gns.c | 319 |
8 files changed, 925 insertions, 160 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 33fd96d9d..0b65a3d17 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -184,6 +184,7 @@ w32nsp_resolve_LDADD = -lws2_32 | |||
184 | gnunet_service_gns_SOURCES = \ | 184 | gnunet_service_gns_SOURCES = \ |
185 | gnunet-service-gns.c \ | 185 | gnunet-service-gns.c \ |
186 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ | 186 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ |
187 | gnunet-service-gns_reverser.c gnunet-service-gns_reverser.h \ | ||
187 | gnunet-service-gns_shorten.c gnunet-service-gns_shorten.h \ | 188 | gnunet-service-gns_shorten.c gnunet-service-gns_shorten.h \ |
188 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h | 189 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h |
189 | gnunet_service_gns_LDADD = \ | 190 | gnunet_service_gns_LDADD = \ |
@@ -258,7 +259,8 @@ check_SCRIPTS = \ | |||
258 | test_gns_rel_expiration.sh\ | 259 | test_gns_rel_expiration.sh\ |
259 | test_gns_soa_lookup.sh\ | 260 | test_gns_soa_lookup.sh\ |
260 | test_gns_revocation.sh\ | 261 | test_gns_revocation.sh\ |
261 | test_gns_cname_lookup.sh | 262 | test_gns_cname_lookup.sh \ |
263 | test_gns_reverse_lookup.sh | ||
262 | 264 | ||
263 | if ENABLE_TEST_RUN | 265 | if ENABLE_TEST_RUN |
264 | if HAVE_SQLITE | 266 | if HAVE_SQLITE |
diff --git a/src/gns/gns.h b/src/gns/gns.h index 476cb0fd2..ca5525f80 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h | |||
@@ -91,6 +91,32 @@ struct LookupMessage | |||
91 | 91 | ||
92 | 92 | ||
93 | /** | 93 | /** |
94 | * Message from client to GNS service to lookup records. | ||
95 | */ | ||
96 | struct ReverseLookupMessage | ||
97 | { | ||
98 | /** | ||
99 | * Header of type #GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP | ||
100 | */ | ||
101 | struct GNUNET_MessageHeader header; | ||
102 | |||
103 | /** | ||
104 | * Unique identifier for this request (for key collisions). | ||
105 | */ | ||
106 | uint32_t id GNUNET_PACKED; | ||
107 | |||
108 | /** | ||
109 | * Zone that is target for reverse lookup | ||
110 | */ | ||
111 | struct GNUNET_CRYPTO_EcdsaPublicKey zone_pkey; | ||
112 | |||
113 | /** | ||
114 | * Root zone | ||
115 | */ | ||
116 | struct GNUNET_CRYPTO_EcdsaPublicKey root_pkey; | ||
117 | }; | ||
118 | |||
119 | /** | ||
94 | * Message from GNS service to client: new results. | 120 | * Message from GNS service to client: new results. |
95 | */ | 121 | */ |
96 | struct LookupResultMessage | 122 | struct LookupResultMessage |
@@ -114,6 +140,24 @@ struct LookupResultMessage | |||
114 | 140 | ||
115 | }; | 141 | }; |
116 | 142 | ||
143 | /** | ||
144 | * Message from GNS service to client: new results. | ||
145 | */ | ||
146 | struct ReverseLookupResultMessage | ||
147 | { | ||
148 | /** | ||
149 | * Header of type #GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT | ||
150 | */ | ||
151 | struct GNUNET_MessageHeader header; | ||
152 | |||
153 | /** | ||
154 | * Unique identifier for this request (for key collisions). | ||
155 | */ | ||
156 | uint32_t id GNUNET_PACKED; | ||
157 | |||
158 | /* followed by the resulting name of the reverse lookup */ | ||
159 | }; | ||
160 | |||
117 | 161 | ||
118 | GNUNET_NETWORK_STRUCT_END | 162 | GNUNET_NETWORK_STRUCT_END |
119 | 163 | ||
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index b9b95b7c2..3f6425b42 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -79,6 +79,49 @@ struct GNUNET_GNS_LookupRequest | |||
79 | 79 | ||
80 | }; | 80 | }; |
81 | 81 | ||
82 | /** | ||
83 | * Handle to a lookup request | ||
84 | */ | ||
85 | struct GNUNET_GNS_ReverseLookupRequest | ||
86 | { | ||
87 | |||
88 | /** | ||
89 | * DLL | ||
90 | */ | ||
91 | struct GNUNET_GNS_ReverseLookupRequest *next; | ||
92 | |||
93 | /** | ||
94 | * DLL | ||
95 | */ | ||
96 | struct GNUNET_GNS_ReverseLookupRequest *prev; | ||
97 | |||
98 | /** | ||
99 | * handle to gns | ||
100 | */ | ||
101 | struct GNUNET_GNS_Handle *gns_handle; | ||
102 | |||
103 | /** | ||
104 | * processor to call on lookup result | ||
105 | */ | ||
106 | GNUNET_GNS_ReverseLookupResultProcessor lookup_proc; | ||
107 | |||
108 | /** | ||
109 | * @e lookup_proc closure | ||
110 | */ | ||
111 | void *proc_cls; | ||
112 | |||
113 | /** | ||
114 | * Envelope with the message for this queue entry. | ||
115 | */ | ||
116 | struct GNUNET_MQ_Envelope *env; | ||
117 | |||
118 | /** | ||
119 | * request id | ||
120 | */ | ||
121 | uint32_t r_id; | ||
122 | |||
123 | }; | ||
124 | |||
82 | 125 | ||
83 | /** | 126 | /** |
84 | * Connection to the GNS service. | 127 | * Connection to the GNS service. |
@@ -107,6 +150,15 @@ struct GNUNET_GNS_Handle | |||
107 | struct GNUNET_GNS_LookupRequest *lookup_tail; | 150 | struct GNUNET_GNS_LookupRequest *lookup_tail; |
108 | 151 | ||
109 | /** | 152 | /** |
153 | * Head of linked list of active reverse lookup requests. | ||
154 | */ | ||
155 | struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_head; | ||
156 | |||
157 | /** | ||
158 | * Tail of linked list of active reverse lookup requests. | ||
159 | */ | ||
160 | struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_tail; | ||
161 | /** | ||
110 | * Reconnect task | 162 | * Reconnect task |
111 | */ | 163 | */ |
112 | struct GNUNET_SCHEDULER_Task *reconnect_task; | 164 | struct GNUNET_SCHEDULER_Task *reconnect_task; |
@@ -180,10 +232,71 @@ mq_error_handler (void *cls, | |||
180 | enum GNUNET_MQ_Error error) | 232 | enum GNUNET_MQ_Error error) |
181 | { | 233 | { |
182 | struct GNUNET_GNS_Handle *handle = cls; | 234 | struct GNUNET_GNS_Handle *handle = cls; |
183 | 235 | LOG (GNUNET_ERROR_TYPE_WARNING, "Problem with message queue. error: %i\n", | |
236 | error); | ||
184 | force_reconnect (handle); | 237 | force_reconnect (handle); |
185 | } | 238 | } |
186 | 239 | ||
240 | /** | ||
241 | * Check validity of message received from the GNS service | ||
242 | * | ||
243 | * @param cls the `struct GNUNET_GNS_Handle *` | ||
244 | * @param loookup_msg the incoming message | ||
245 | */ | ||
246 | static int | ||
247 | check_rev_result (void *cls, | ||
248 | const struct ReverseLookupResultMessage *lookup_msg) | ||
249 | { | ||
250 | size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); | ||
251 | char *name; | ||
252 | |||
253 | name = (char*) &lookup_msg[1]; | ||
254 | if ('\0' != name[mlen-1]) | ||
255 | { | ||
256 | GNUNET_break (0); | ||
257 | return GNUNET_SYSERR; | ||
258 | } | ||
259 | return GNUNET_OK; | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Handler for messages received from the GNS service | ||
265 | * | ||
266 | * @param cls the `struct GNUNET_GNS_Handle *` | ||
267 | * @param loookup_msg the incoming message | ||
268 | */ | ||
269 | static void | ||
270 | handle_rev_result (void *cls, | ||
271 | const struct ReverseLookupResultMessage *lookup_msg) | ||
272 | { | ||
273 | struct GNUNET_GNS_Handle *handle = cls; | ||
274 | char *name; | ||
275 | uint32_t r_id = ntohl (lookup_msg->id); | ||
276 | struct GNUNET_GNS_ReverseLookupRequest *rlr; | ||
277 | GNUNET_GNS_ReverseLookupResultProcessor proc; | ||
278 | void *proc_cls; | ||
279 | |||
280 | name = (char*)&lookup_msg[1]; | ||
281 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
282 | "Received reverse lookup reply from GNS service (%s)\n", | ||
283 | name); | ||
284 | for (rlr = handle->rev_lookup_head; NULL != rlr; rlr = rlr->next) | ||
285 | if (rlr->r_id == r_id) | ||
286 | break; | ||
287 | if (NULL == rlr) | ||
288 | return; | ||
289 | proc = rlr->lookup_proc; | ||
290 | proc_cls = rlr->proc_cls; | ||
291 | GNUNET_CONTAINER_DLL_remove (handle->rev_lookup_head, | ||
292 | handle->rev_lookup_tail, | ||
293 | rlr); | ||
294 | GNUNET_free (rlr); | ||
295 | proc (proc_cls, | ||
296 | name); | ||
297 | } | ||
298 | |||
299 | |||
187 | 300 | ||
188 | /** | 301 | /** |
189 | * Check validity of message received from the GNS service | 302 | * Check validity of message received from the GNS service |
@@ -269,9 +382,14 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
269 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT, | 382 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT, |
270 | struct LookupResultMessage, | 383 | struct LookupResultMessage, |
271 | handle), | 384 | handle), |
385 | GNUNET_MQ_hd_var_size (rev_result, | ||
386 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT, | ||
387 | struct ReverseLookupResultMessage, | ||
388 | handle), | ||
272 | GNUNET_MQ_handler_end () | 389 | GNUNET_MQ_handler_end () |
273 | }; | 390 | }; |
274 | struct GNUNET_GNS_LookupRequest *lh; | 391 | struct GNUNET_GNS_LookupRequest *lh; |
392 | struct GNUNET_GNS_ReverseLookupRequest *rlh; | ||
275 | 393 | ||
276 | GNUNET_assert (NULL == handle->mq); | 394 | GNUNET_assert (NULL == handle->mq); |
277 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 395 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -286,6 +404,9 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
286 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) | 404 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) |
287 | GNUNET_MQ_send_copy (handle->mq, | 405 | GNUNET_MQ_send_copy (handle->mq, |
288 | lh->env); | 406 | lh->env); |
407 | for (rlh = handle->rev_lookup_head; NULL != rlh; rlh = rlh->next) | ||
408 | GNUNET_MQ_send_copy (handle->mq, | ||
409 | rlh->env); | ||
289 | } | 410 | } |
290 | 411 | ||
291 | 412 | ||
@@ -331,6 +452,7 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) | |||
331 | handle->reconnect_task = NULL; | 452 | handle->reconnect_task = NULL; |
332 | } | 453 | } |
333 | GNUNET_assert (NULL == handle->lookup_head); | 454 | GNUNET_assert (NULL == handle->lookup_head); |
455 | GNUNET_assert (NULL == handle->rev_lookup_head); | ||
334 | GNUNET_free (handle); | 456 | GNUNET_free (handle); |
335 | } | 457 | } |
336 | 458 | ||
@@ -352,6 +474,22 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) | |||
352 | GNUNET_free (lr); | 474 | GNUNET_free (lr); |
353 | } | 475 | } |
354 | 476 | ||
477 | /** | ||
478 | * Cancel pending reverse lookup request | ||
479 | * | ||
480 | * @param lr the lookup request to cancel | ||
481 | */ | ||
482 | void | ||
483 | GNUNET_GNS_reverse_lookup_cancel (struct GNUNET_GNS_ReverseLookupRequest *lr) | ||
484 | { | ||
485 | struct GNUNET_GNS_Handle *handle = lr->gns_handle; | ||
486 | |||
487 | GNUNET_CONTAINER_DLL_remove (handle->rev_lookup_head, | ||
488 | handle->rev_lookup_tail, | ||
489 | lr); | ||
490 | GNUNET_MQ_discard (lr->env); | ||
491 | GNUNET_free (lr); | ||
492 | } | ||
355 | 493 | ||
356 | /** | 494 | /** |
357 | * Perform an asynchronous lookup operation on the GNS. | 495 | * Perform an asynchronous lookup operation on the GNS. |
@@ -368,13 +506,13 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) | |||
368 | */ | 506 | */ |
369 | struct GNUNET_GNS_LookupRequest* | 507 | struct GNUNET_GNS_LookupRequest* |
370 | GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | 508 | GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, |
371 | const char *name, | 509 | const char *name, |
372 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 510 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
373 | uint32_t type, | 511 | uint32_t type, |
374 | enum GNUNET_GNS_LocalOptions options, | 512 | enum GNUNET_GNS_LocalOptions options, |
375 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone_key, | 513 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone_key, |
376 | GNUNET_GNS_LookupResultProcessor proc, | 514 | GNUNET_GNS_LookupResultProcessor proc, |
377 | void *proc_cls) | 515 | void *proc_cls) |
378 | { | 516 | { |
379 | /* IPC to shorten gns names, return shorten_handle */ | 517 | /* IPC to shorten gns names, return shorten_handle */ |
380 | struct LookupMessage *lookup_msg; | 518 | struct LookupMessage *lookup_msg; |
@@ -413,8 +551,8 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
413 | lookup_msg->shorten_key = *shorten_zone_key; | 551 | lookup_msg->shorten_key = *shorten_zone_key; |
414 | } | 552 | } |
415 | GNUNET_memcpy (&lookup_msg[1], | 553 | GNUNET_memcpy (&lookup_msg[1], |
416 | name, | 554 | name, |
417 | nlen); | 555 | nlen); |
418 | GNUNET_CONTAINER_DLL_insert (handle->lookup_head, | 556 | GNUNET_CONTAINER_DLL_insert (handle->lookup_head, |
419 | handle->lookup_tail, | 557 | handle->lookup_tail, |
420 | lr); | 558 | lr); |
@@ -424,5 +562,50 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
424 | return lr; | 562 | return lr; |
425 | } | 563 | } |
426 | 564 | ||
565 | /** | ||
566 | * Perform an asynchronous reverse lookup operation on the GNS. | ||
567 | * | ||
568 | * @param handle handle to the GNS service | ||
569 | * @param zone_key zone to find a name for | ||
570 | * @param root_key our zone | ||
571 | * @param proc processor to call on result | ||
572 | * @param proc_cls closure for @a proc | ||
573 | * @return handle to the request | ||
574 | */ | ||
575 | struct GNUNET_GNS_ReverseLookupRequest* | ||
576 | GNUNET_GNS_reverse_lookup (struct GNUNET_GNS_Handle *handle, | ||
577 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | ||
578 | const struct GNUNET_CRYPTO_EcdsaPublicKey *root_key, | ||
579 | GNUNET_GNS_ReverseLookupResultProcessor proc, | ||
580 | void *proc_cls) | ||
581 | { | ||
582 | /* IPC to shorten gns names, return shorten_handle */ | ||
583 | struct ReverseLookupMessage *rev_lookup_msg; | ||
584 | struct GNUNET_GNS_ReverseLookupRequest *lr; | ||
427 | 585 | ||
586 | if ((NULL == zone_key) || (NULL == root_key)) | ||
587 | { | ||
588 | GNUNET_break (0); | ||
589 | return NULL; | ||
590 | } | ||
591 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
592 | "Trying to reverse lookup in GNS\n"); | ||
593 | lr = GNUNET_new (struct GNUNET_GNS_ReverseLookupRequest); | ||
594 | lr->gns_handle = handle; | ||
595 | lr->lookup_proc = proc; | ||
596 | lr->proc_cls = proc_cls; | ||
597 | lr->r_id = handle->r_id_gen++; | ||
598 | lr->env = GNUNET_MQ_msg (rev_lookup_msg, | ||
599 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP); | ||
600 | rev_lookup_msg->id = htonl (lr->r_id); | ||
601 | rev_lookup_msg->zone_pkey = *zone_key; | ||
602 | rev_lookup_msg->root_pkey = *root_key; | ||
603 | GNUNET_CONTAINER_DLL_insert (handle->rev_lookup_head, | ||
604 | handle->rev_lookup_tail, | ||
605 | lr); | ||
606 | if (NULL != handle->mq) | ||
607 | GNUNET_MQ_send_copy (handle->mq, | ||
608 | lr->env); | ||
609 | return lr; | ||
610 | } | ||
428 | /* end of gns_api.c */ | 611 | /* end of gns_api.c */ |
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index 62cec54cb..17fe4cbda 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c | |||
@@ -66,6 +66,16 @@ static char *zone_ego_name; | |||
66 | static char *public_key; | 66 | static char *public_key; |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Reverse key | ||
70 | */ | ||
71 | static char *reverse_key; | ||
72 | |||
73 | /** | ||
74 | * Reverse key | ||
75 | */ | ||
76 | static struct GNUNET_CRYPTO_EcdsaPublicKey rkey; | ||
77 | |||
78 | /** | ||
69 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. | 79 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. |
70 | */ | 80 | */ |
71 | static enum GNUNET_GNS_LocalOptions local_options; | 81 | static enum GNUNET_GNS_LocalOptions local_options; |
@@ -86,6 +96,11 @@ static int rtype; | |||
86 | static struct GNUNET_GNS_LookupRequest *lookup_request; | 96 | static struct GNUNET_GNS_LookupRequest *lookup_request; |
87 | 97 | ||
88 | /** | 98 | /** |
99 | * Handle to reverse lookup request | ||
100 | */ | ||
101 | static struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_request; | ||
102 | |||
103 | /** | ||
89 | * Lookup an ego with the identity service. | 104 | * Lookup an ego with the identity service. |
90 | */ | 105 | */ |
91 | static struct GNUNET_IDENTITY_EgoLookup *el; | 106 | static struct GNUNET_IDENTITY_EgoLookup *el; |
@@ -159,6 +174,24 @@ do_timeout (void *cls) | |||
159 | GNUNET_SCHEDULER_shutdown (); | 174 | GNUNET_SCHEDULER_shutdown (); |
160 | } | 175 | } |
161 | 176 | ||
177 | static void | ||
178 | process_reverse_result (void *cls, | ||
179 | const char *name) | ||
180 | { | ||
181 | rev_lookup_request = NULL; | ||
182 | if (NULL == name) | ||
183 | { | ||
184 | printf ("No name found.\n"); | ||
185 | return; | ||
186 | } | ||
187 | if (raw) | ||
188 | printf ("%s\n", name); | ||
189 | else | ||
190 | printf ("%s is known as %s\n", | ||
191 | reverse_key, | ||
192 | name); | ||
193 | GNUNET_SCHEDULER_shutdown (); | ||
194 | } | ||
162 | 195 | ||
163 | /** | 196 | /** |
164 | * Function called with the result of a GNS lookup. | 197 | * Function called with the result of a GNS lookup. |
@@ -248,6 +281,14 @@ lookup_with_keys (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | |||
248 | &process_lookup_result, | 281 | &process_lookup_result, |
249 | lookup_name); | 282 | lookup_name); |
250 | } | 283 | } |
284 | else if (NULL != reverse_key) | ||
285 | { | ||
286 | rev_lookup_request = GNUNET_GNS_reverse_lookup (gns, | ||
287 | &rkey, | ||
288 | pkey, | ||
289 | &process_reverse_result, | ||
290 | NULL); | ||
291 | } | ||
251 | else | 292 | else |
252 | { | 293 | { |
253 | fprintf (stderr, | 294 | fprintf (stderr, |
@@ -416,49 +457,77 @@ run (void *cls, | |||
416 | return; | 457 | return; |
417 | } | 458 | } |
418 | tt = GNUNET_SCHEDULER_add_delayed (timeout, | 459 | tt = GNUNET_SCHEDULER_add_delayed (timeout, |
419 | &do_timeout, NULL); | 460 | &do_timeout, NULL); |
420 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | 461 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); |
462 | if (NULL != reverse_key) | ||
463 | { | ||
464 | if (GNUNET_OK != | ||
465 | GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_key, | ||
466 | strlen (reverse_key), | ||
467 | &rkey)) | ||
468 | { | ||
469 | fprintf (stderr, | ||
470 | _("Reverse key `%s' is not well-formed\n"), | ||
471 | reverse_key); | ||
472 | GNUNET_SCHEDULER_shutdown (); | ||
473 | return; | ||
474 | } | ||
475 | } | ||
421 | if (NULL != public_key) | 476 | if (NULL != public_key) |
422 | { | 477 | { |
423 | if (GNUNET_OK != | 478 | if (GNUNET_OK != |
424 | GNUNET_CRYPTO_ecdsa_public_key_from_string (public_key, | 479 | GNUNET_CRYPTO_ecdsa_public_key_from_string (public_key, |
425 | strlen (public_key), | 480 | strlen (public_key), |
426 | &pkey)) | 481 | &pkey)) |
427 | { | 482 | { |
428 | fprintf (stderr, | 483 | fprintf (stderr, |
429 | _("Public key `%s' is not well-formed\n"), | 484 | _("Public key `%s' is not well-formed\n"), |
430 | public_key); | 485 | public_key); |
431 | GNUNET_SCHEDULER_shutdown (); | 486 | GNUNET_SCHEDULER_shutdown (); |
432 | return; | 487 | return; |
433 | } | 488 | } |
434 | lookup_with_public_key (&pkey); | 489 | lookup_with_public_key (&pkey); |
435 | return; | 490 | return; |
436 | } | 491 | } |
492 | if (NULL != reverse_key) | ||
493 | { | ||
494 | if (GNUNET_OK != | ||
495 | GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_key, | ||
496 | strlen (reverse_key), | ||
497 | &rkey)) | ||
498 | { | ||
499 | fprintf (stderr, | ||
500 | _("Reverse key `%s' is not well-formed\n"), | ||
501 | reverse_key); | ||
502 | GNUNET_SCHEDULER_shutdown (); | ||
503 | return; | ||
504 | } | ||
505 | } | ||
437 | if (NULL != zone_ego_name) | 506 | if (NULL != zone_ego_name) |
438 | { | 507 | { |
439 | el = GNUNET_IDENTITY_ego_lookup (cfg, | 508 | el = GNUNET_IDENTITY_ego_lookup (cfg, |
440 | zone_ego_name, | 509 | zone_ego_name, |
441 | &identity_zone_cb, | 510 | &identity_zone_cb, |
442 | NULL); | 511 | NULL); |
443 | return; | 512 | return; |
444 | } | 513 | } |
445 | if ( (NULL != lookup_name) && | 514 | if ( (NULL != lookup_name) && |
446 | (strlen (lookup_name) > 4) && | 515 | (strlen (lookup_name) > 4) && |
447 | (0 == strcmp (".zkey", | 516 | (0 == strcmp (".zkey", |
448 | &lookup_name[strlen (lookup_name) - 4])) ) | 517 | &lookup_name[strlen (lookup_name) - 4])) ) |
449 | { | 518 | { |
450 | /* no zone required, use 'anonymous' zone */ | 519 | /* no zone required, use 'anonymous' zone */ |
451 | GNUNET_CRYPTO_ecdsa_key_get_public (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), | 520 | GNUNET_CRYPTO_ecdsa_key_get_public (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), |
452 | &pkey); | 521 | &pkey); |
453 | lookup_with_public_key (&pkey); | 522 | lookup_with_public_key (&pkey); |
454 | } | 523 | } |
455 | else | 524 | else |
456 | { | 525 | { |
457 | GNUNET_break (NULL == id_op); | 526 | GNUNET_break (NULL == id_op); |
458 | id_op = GNUNET_IDENTITY_get (identity, | 527 | id_op = GNUNET_IDENTITY_get (identity, |
459 | "gns-master", | 528 | "gns-master", |
460 | &identity_master_cb, | 529 | &identity_master_cb, |
461 | NULL); | 530 | NULL); |
462 | GNUNET_assert (NULL != id_op); | 531 | GNUNET_assert (NULL != id_op); |
463 | } | 532 | } |
464 | } | 533 | } |
@@ -493,6 +562,9 @@ main (int argc, char *const *argv) | |||
493 | {'z', "zone", "NAME", | 562 | {'z', "zone", "NAME", |
494 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, | 563 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, |
495 | &GNUNET_GETOPT_set_string, &zone_ego_name}, | 564 | &GNUNET_GETOPT_set_string, &zone_ego_name}, |
565 | {'R', "reverse", "PKEY", | ||
566 | gettext_noop ("Specify the public key of the zone to reverse lookup a name for"), 1, | ||
567 | &GNUNET_GETOPT_set_string, &reverse_key}, | ||
496 | GNUNET_GETOPT_OPTION_END | 568 | GNUNET_GETOPT_OPTION_END |
497 | }; | 569 | }; |
498 | int ret; | 570 | int ret; |
@@ -503,11 +575,11 @@ main (int argc, char *const *argv) | |||
503 | 575 | ||
504 | GNUNET_log_setup ("gnunet-gns", "WARNING", NULL); | 576 | GNUNET_log_setup ("gnunet-gns", "WARNING", NULL); |
505 | ret = | 577 | ret = |
506 | (GNUNET_OK == | 578 | (GNUNET_OK == |
507 | GNUNET_PROGRAM_run (argc, argv, "gnunet-gns", | 579 | GNUNET_PROGRAM_run (argc, argv, "gnunet-gns", |
508 | _("GNUnet GNS resolver tool"), | 580 | _("GNUnet GNS resolver tool"), |
509 | options, | 581 | options, |
510 | &run, NULL)) ? 0 : 1; | 582 | &run, NULL)) ? 0 : 1; |
511 | GNUNET_free ((void*) argv); | 583 | GNUNET_free ((void*) argv); |
512 | return ret; | 584 | return ret; |
513 | } | 585 | } |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 386e6d744..221d75bba 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "gnunet_statistics_service.h" | 35 | #include "gnunet_statistics_service.h" |
36 | #include "gns.h" | 36 | #include "gns.h" |
37 | #include "gnunet-service-gns_resolver.h" | 37 | #include "gnunet-service-gns_resolver.h" |
38 | #include "gnunet-service-gns_reverser.h" | ||
38 | #include "gnunet-service-gns_shorten.h" | 39 | #include "gnunet-service-gns_shorten.h" |
39 | #include "gnunet-service-gns_interceptor.h" | 40 | #include "gnunet-service-gns_interceptor.h" |
40 | #include "gnunet_protocols.h" | 41 | #include "gnunet_protocols.h" |
@@ -109,6 +110,11 @@ struct ClientLookupHandle | |||
109 | struct GNS_ResolverHandle *lookup; | 110 | struct GNS_ResolverHandle *lookup; |
110 | 111 | ||
111 | /** | 112 | /** |
113 | * Active handle for a reverse lookup | ||
114 | */ | ||
115 | struct GNS_ReverserHandle *rev_lookup; | ||
116 | |||
117 | /** | ||
112 | * request id | 118 | * request id |
113 | */ | 119 | */ |
114 | uint32_t request_id; | 120 | uint32_t request_id; |
@@ -367,7 +373,10 @@ client_disconnect_cb (void *cls, | |||
367 | client); | 373 | client); |
368 | while (NULL != (clh = gc->clh_head)) | 374 | while (NULL != (clh = gc->clh_head)) |
369 | { | 375 | { |
370 | GNS_resolver_lookup_cancel (clh->lookup); | 376 | if (NULL != clh->lookup) |
377 | GNS_resolver_lookup_cancel (clh->lookup); | ||
378 | if (NULL != clh->rev_lookup) | ||
379 | GNS_reverse_lookup_cancel (clh->rev_lookup); | ||
371 | GNUNET_CONTAINER_DLL_remove (gc->clh_head, | 380 | GNUNET_CONTAINER_DLL_remove (gc->clh_head, |
372 | gc->clh_tail, | 381 | gc->clh_tail, |
373 | clh); | 382 | clh); |
@@ -846,6 +855,47 @@ send_lookup_response (void* cls, | |||
846 | GNUNET_NO); | 855 | GNUNET_NO); |
847 | } | 856 | } |
848 | 857 | ||
858 | /** | ||
859 | * Reply to client with the result from our reverse lookup. | ||
860 | * | ||
861 | * @param cls the closure (our client lookup handle) | ||
862 | * @param rd_count the number of records in @a rd | ||
863 | * @param rd the record data | ||
864 | */ | ||
865 | static void | ||
866 | send_reverse_lookup_response (void* cls, | ||
867 | const char *name) | ||
868 | { | ||
869 | struct ClientLookupHandle *clh = cls; | ||
870 | struct GNUNET_MQ_Envelope *env; | ||
871 | struct ReverseLookupResultMessage *rmsg; | ||
872 | size_t len; | ||
873 | |||
874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
875 | "Sending LOOKUP_RESULT message with %s\n", | ||
876 | name); | ||
877 | |||
878 | if (NULL == name) | ||
879 | len = 1; | ||
880 | else | ||
881 | len = strlen (name) + 1; | ||
882 | env = GNUNET_MQ_msg_extra (rmsg, | ||
883 | len, | ||
884 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT); | ||
885 | rmsg->id = clh->request_id; | ||
886 | if (1 < len) | ||
887 | GNUNET_memcpy ((char*) &rmsg[1], | ||
888 | name, | ||
889 | strlen (name)); | ||
890 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), | ||
891 | env); | ||
892 | GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, clh->gc->clh_tail, clh); | ||
893 | GNUNET_free (clh); | ||
894 | GNUNET_STATISTICS_update (statistics, | ||
895 | "Completed reverse lookups", 1, | ||
896 | GNUNET_NO); | ||
897 | } | ||
898 | |||
849 | 899 | ||
850 | /** | 900 | /** |
851 | * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message | 901 | * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message |
@@ -856,7 +906,7 @@ send_lookup_response (void* cls, | |||
856 | */ | 906 | */ |
857 | static int | 907 | static int |
858 | check_lookup (void *cls, | 908 | check_lookup (void *cls, |
859 | const struct LookupMessage *l_msg) | 909 | const struct LookupMessage *l_msg) |
860 | { | 910 | { |
861 | size_t msg_size; | 911 | size_t msg_size; |
862 | const char* name; | 912 | const char* name; |
@@ -936,6 +986,37 @@ handle_lookup (void *cls, | |||
936 | 1, GNUNET_NO); | 986 | 1, GNUNET_NO); |
937 | } | 987 | } |
938 | 988 | ||
989 | /** | ||
990 | * Handle reverse lookup requests from client | ||
991 | * | ||
992 | * @param cls the closure | ||
993 | * @param client the client | ||
994 | * @param message the message | ||
995 | */ | ||
996 | static void | ||
997 | handle_rev_lookup (void *cls, | ||
998 | const struct ReverseLookupMessage *sh_msg) | ||
999 | { | ||
1000 | struct GnsClient *gc = cls; | ||
1001 | struct ClientLookupHandle *clh; | ||
1002 | |||
1003 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1004 | "Received REVERSE_LOOKUP message\n"); | ||
1005 | GNUNET_SERVICE_client_continue (gc->client); | ||
1006 | |||
1007 | clh = GNUNET_new (struct ClientLookupHandle); | ||
1008 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, gc->clh_tail, clh); | ||
1009 | clh->gc = gc; | ||
1010 | clh->request_id = sh_msg->id; | ||
1011 | clh->rev_lookup = GNS_reverse_lookup (&sh_msg->zone_pkey, | ||
1012 | &sh_msg->root_pkey, | ||
1013 | &send_reverse_lookup_response, | ||
1014 | clh); | ||
1015 | GNUNET_STATISTICS_update (statistics, | ||
1016 | "Reverse lookup attempts", | ||
1017 | 1, GNUNET_NO); | ||
1018 | } | ||
1019 | |||
939 | 1020 | ||
940 | /** | 1021 | /** |
941 | * The zone monitor is now in SYNC with the current state of the | 1022 | * The zone monitor is now in SYNC with the current state of the |
@@ -1149,6 +1230,10 @@ GNUNET_SERVICE_MAIN | |||
1149 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP, | 1230 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP, |
1150 | struct LookupMessage, | 1231 | struct LookupMessage, |
1151 | NULL), | 1232 | NULL), |
1233 | GNUNET_MQ_hd_fixed_size (rev_lookup, | ||
1234 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP, | ||
1235 | struct ReverseLookupMessage, | ||
1236 | NULL), | ||
1152 | GNUNET_MQ_handler_end()); | 1237 | GNUNET_MQ_handler_end()); |
1153 | 1238 | ||
1154 | 1239 | ||
diff --git a/src/gns/gnunet-service-gns_reverser.c b/src/gns/gnunet-service-gns_reverser.c new file mode 100644 index 000000000..6bae20b61 --- /dev/null +++ b/src/gns/gnunet-service-gns_reverser.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_reverser.c | ||
22 | * @brief GNUnet GNS service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | |||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_gns_service.h" | ||
29 | #include "gnunet-service-gns_resolver.h" | ||
30 | #include "gnunet-service-gns_reverser.h" | ||
31 | |||
32 | struct ReverseTreeNode | ||
33 | { | ||
34 | /** | ||
35 | * DLL | ||
36 | */ | ||
37 | struct ReverseTreeNode *next; | ||
38 | |||
39 | /** | ||
40 | * DLL | ||
41 | */ | ||
42 | struct ReverseTreeNode *prev; | ||
43 | |||
44 | /** | ||
45 | * Resolved name until now | ||
46 | */ | ||
47 | char *name; | ||
48 | |||
49 | /** | ||
50 | * Depth of the resolution at this node | ||
51 | */ | ||
52 | uint8_t depth; | ||
53 | |||
54 | /** | ||
55 | * The pkey of the namespace | ||
56 | */ | ||
57 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | ||
58 | |||
59 | }; | ||
60 | |||
61 | |||
62 | struct GNS_ReverserHandle | ||
63 | { | ||
64 | /** | ||
65 | * GNS resolver handle | ||
66 | */ | ||
67 | struct GNS_ResolverHandle *rh; | ||
68 | |||
69 | /** | ||
70 | * The authority to look for | ||
71 | */ | ||
72 | struct GNUNET_CRYPTO_EcdsaPublicKey authority; | ||
73 | |||
74 | /** | ||
75 | * Resolution candidate queue | ||
76 | */ | ||
77 | struct ReverseTreeNode *node_queue_head; | ||
78 | |||
79 | /** | ||
80 | * Resolution candidate queue | ||
81 | */ | ||
82 | struct ReverseTreeNode *node_queue_tail; | ||
83 | |||
84 | /** | ||
85 | * Max depth for the resolution | ||
86 | */ | ||
87 | uint8_t max_depth; | ||
88 | |||
89 | /** | ||
90 | * Result callback | ||
91 | */ | ||
92 | GNS_ReverseResultProcessor proc; | ||
93 | |||
94 | /** | ||
95 | * Callback closure | ||
96 | */ | ||
97 | void *proc_cls; | ||
98 | }; | ||
99 | |||
100 | void | ||
101 | cleanup_handle (struct GNS_ReverserHandle *rh) | ||
102 | { | ||
103 | struct ReverseTreeNode *rtn; | ||
104 | |||
105 | for (rtn = rh->node_queue_head; NULL != rtn; rtn = rh->node_queue_head) | ||
106 | { | ||
107 | if (NULL != rtn->name) | ||
108 | GNUNET_free (rtn->name); | ||
109 | GNUNET_CONTAINER_DLL_remove (rh->node_queue_head, | ||
110 | rh->node_queue_tail, | ||
111 | rtn); | ||
112 | GNUNET_free (rtn); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void | ||
117 | handle_gns_result (void *cls, | ||
118 | uint32_t rd_count, | ||
119 | const struct GNUNET_GNSRECORD_Data *rd) | ||
120 | { | ||
121 | struct GNS_ReverserHandle *rh = cls; | ||
122 | const struct GNUNET_GNSRECORD_ReverseRecord *rr; | ||
123 | struct ReverseTreeNode *rtn; | ||
124 | char *result; | ||
125 | const char *name; | ||
126 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
127 | "Got result (%d)\n", rd_count); | ||
128 | |||
129 | for (int i = 0; i < rd_count; i++) | ||
130 | { | ||
131 | /** | ||
132 | * Check if we are in the delegation set | ||
133 | */ | ||
134 | if (GNUNET_GNSRECORD_TYPE_REVERSE != rd[i].record_type) | ||
135 | continue; | ||
136 | rr = rd[i].data; | ||
137 | name = (const char*) &rr[1]; | ||
138 | if (0 == memcmp (&rh->authority, | ||
139 | &rr->pkey, | ||
140 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
141 | { | ||
142 | //Found! | ||
143 | GNUNET_asprintf (&result, | ||
144 | "%s.%s.gnu", | ||
145 | rh->node_queue_head->name, | ||
146 | name); | ||
147 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
148 | "Found path from %s\n", result); | ||
149 | |||
150 | rh->proc (rh->proc_cls, result); | ||
151 | cleanup_handle (rh); | ||
152 | GNUNET_free (result); | ||
153 | return; | ||
154 | } else { | ||
155 | if (rh->node_queue_head->depth >= rh->max_depth) | ||
156 | break; | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
158 | "Found REVERSE from %s\n", name); | ||
159 | |||
160 | rtn = GNUNET_new (struct ReverseTreeNode); | ||
161 | if (NULL == rh->node_queue_head->name) | ||
162 | rtn->name = GNUNET_strdup (name); | ||
163 | else | ||
164 | GNUNET_asprintf (&rtn->name, | ||
165 | "%s.%s", | ||
166 | rh->node_queue_head->name, | ||
167 | name); | ||
168 | rtn->depth = rh->node_queue_head->depth + 1; | ||
169 | rtn->pkey = rr->pkey; | ||
170 | GNUNET_CONTAINER_DLL_insert_tail (rh->node_queue_head, | ||
171 | rh->node_queue_tail, | ||
172 | rtn); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Done here remove node from queue | ||
178 | */ | ||
179 | rtn = rh->node_queue_head; | ||
180 | GNUNET_CONTAINER_DLL_remove (rh->node_queue_head, | ||
181 | rh->node_queue_tail, | ||
182 | rtn); | ||
183 | if (NULL == rh->node_queue_head) | ||
184 | { | ||
185 | //No luck | ||
186 | rh->proc (rh->proc_cls, NULL); | ||
187 | cleanup_handle (rh); | ||
188 | return; | ||
189 | } | ||
190 | rh->rh = GNS_resolver_lookup (&rh->node_queue_head->pkey, | ||
191 | GNUNET_GNSRECORD_TYPE_REVERSE, | ||
192 | "+.gnu", | ||
193 | NULL, | ||
194 | GNUNET_GNS_LO_DEFAULT, | ||
195 | &handle_gns_result, | ||
196 | rh); | ||
197 | } | ||
198 | |||
199 | struct GNS_ReverserHandle * | ||
200 | GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target, | ||
201 | const struct GNUNET_CRYPTO_EcdsaPublicKey *authority, | ||
202 | GNS_ReverseResultProcessor proc, | ||
203 | void *proc_cls) | ||
204 | { | ||
205 | struct GNS_ReverserHandle *rh; | ||
206 | struct ReverseTreeNode *rtn; | ||
207 | |||
208 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
209 | "Starting reverse resolution\n"); | ||
210 | rh = GNUNET_new (struct GNS_ReverserHandle); | ||
211 | rh->proc = proc; | ||
212 | rh->proc_cls = proc_cls; | ||
213 | rtn = GNUNET_new (struct ReverseTreeNode); | ||
214 | rtn->name = NULL; | ||
215 | rtn->pkey = *target; | ||
216 | rtn->depth = 0; | ||
217 | GNUNET_CONTAINER_DLL_insert (rh->node_queue_head, | ||
218 | rh->node_queue_tail, | ||
219 | rtn); | ||
220 | rh->authority = *authority; | ||
221 | rh->max_depth = 3; //TODO make argument | ||
222 | rh->rh = GNS_resolver_lookup (target, | ||
223 | GNUNET_GNSRECORD_TYPE_REVERSE, | ||
224 | "+.gnu", | ||
225 | NULL, | ||
226 | GNUNET_GNS_LO_DEFAULT, | ||
227 | &handle_gns_result, | ||
228 | rh); | ||
229 | return rh; | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * Cancel active resolution (i.e. client disconnected). | ||
234 | * | ||
235 | * @param rh resolution to abort | ||
236 | */ | ||
237 | void | ||
238 | GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh) | ||
239 | { | ||
240 | cleanup_handle (rh); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | |||
diff --git a/src/gns/gnunet-service-gns_reverser.h b/src/gns/gnunet-service-gns_reverser.h new file mode 100644 index 000000000..ecec7d743 --- /dev/null +++ b/src/gns/gnunet-service-gns_reverser.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_reverser.h | ||
22 | * @brief GNUnet GNS service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #ifndef GNS_REVERSER_H | ||
26 | #define GNS_REVERSER_H | ||
27 | #include "gns.h" | ||
28 | #include "gnunet_gns_service.h" | ||
29 | |||
30 | /** | ||
31 | * Handle for an active request. | ||
32 | */ | ||
33 | struct GNS_ReverserHandle; | ||
34 | |||
35 | |||
36 | /** | ||
37 | * Function called with results for a GNS resolution. | ||
38 | * | ||
39 | * @param cls closure | ||
40 | * @param rd_count number of records in @a rd | ||
41 | * @param rd records returned for the lookup | ||
42 | */ | ||
43 | typedef void (*GNS_ReverseResultProcessor)(void *cls, | ||
44 | const char *name); | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Reverse lookup of a specific zone | ||
49 | * calls RecordLookupProcessor on result or timeout | ||
50 | * | ||
51 | * @param target the zone to perform the lookup in | ||
52 | * @param authority the authority | ||
53 | * @param proc the processor to call | ||
54 | * @param proc_cls the closure to pass to @a proc | ||
55 | * @return handle to cancel operation | ||
56 | */ | ||
57 | struct GNS_ReverserHandle * | ||
58 | GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target, | ||
59 | const struct GNUNET_CRYPTO_EcdsaPublicKey *authority, | ||
60 | GNS_ReverseResultProcessor proc, | ||
61 | void *proc_cls); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Cancel active resolution (i.e. client disconnected). | ||
66 | * | ||
67 | * @param rh resolution to abort | ||
68 | */ | ||
69 | void | ||
70 | GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh); | ||
71 | |||
72 | #endif | ||
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 360500af7..5faca4578 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "gnunet_gnsrecord_lib.h" | 31 | #include "gnunet_gnsrecord_lib.h" |
32 | #include "gnunet_dnsparser_lib.h" | 32 | #include "gnunet_dnsparser_lib.h" |
33 | #include "gnunet_gnsrecord_plugin.h" | 33 | #include "gnunet_gnsrecord_plugin.h" |
34 | #include <inttypes.h> | ||
34 | 35 | ||
35 | 36 | ||
36 | /** | 37 | /** |
@@ -139,6 +140,30 @@ gns_value_to_string (void *cls, | |||
139 | GNUNET_free (ival); | 140 | GNUNET_free (ival); |
140 | return box_str; | 141 | return box_str; |
141 | } | 142 | } |
143 | case GNUNET_GNSRECORD_TYPE_REVERSE: | ||
144 | { | ||
145 | struct GNUNET_GNSRECORD_ReverseRecord rev; | ||
146 | char *rev_str; | ||
147 | char *pkey_str; | ||
148 | |||
149 | if (data_size < sizeof (struct GNUNET_GNSRECORD_ReverseRecord)) | ||
150 | return NULL; /* malformed */ | ||
151 | |||
152 | memcpy (&rev, | ||
153 | data, | ||
154 | sizeof (rev)); | ||
155 | cdata = data; | ||
156 | pkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&rev.pkey); | ||
157 | |||
158 | GNUNET_asprintf (&rev_str, | ||
159 | "%s %s %"SCNu64, | ||
160 | &cdata[sizeof (rev)], | ||
161 | pkey_str, | ||
162 | rev.expiration.abs_value_us); | ||
163 | GNUNET_free (pkey_str); | ||
164 | return rev_str; | ||
165 | |||
166 | } | ||
142 | default: | 167 | default: |
143 | return NULL; | 168 | return NULL; |
144 | } | 169 | } |
@@ -170,147 +195,184 @@ gns_string_to_value (void *cls, | |||
170 | switch (type) | 195 | switch (type) |
171 | { | 196 | { |
172 | 197 | ||
173 | case GNUNET_GNSRECORD_TYPE_PKEY: | 198 | case GNUNET_GNSRECORD_TYPE_PKEY: |
174 | if (GNUNET_OK != | 199 | if (GNUNET_OK != |
175 | GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) | 200 | GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) |
176 | { | ||
177 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
178 | _("Unable to parse PKEY record `%s'\n"), | ||
179 | s); | ||
180 | return GNUNET_SYSERR; | ||
181 | } | ||
182 | *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
183 | GNUNET_memcpy (*data, &pkey, sizeof (pkey)); | ||
184 | *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
185 | return GNUNET_OK; | ||
186 | |||
187 | case GNUNET_GNSRECORD_TYPE_NICK: | ||
188 | *data = GNUNET_strdup (s); | ||
189 | *data_size = strlen (s); | ||
190 | return GNUNET_OK; | ||
191 | case GNUNET_GNSRECORD_TYPE_LEHO: | ||
192 | *data = GNUNET_strdup (s); | ||
193 | *data_size = strlen (s); | ||
194 | return GNUNET_OK; | ||
195 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | ||
196 | { | ||
197 | char nsbuf[514]; | ||
198 | char *cpy; | ||
199 | char *at; | ||
200 | size_t off; | ||
201 | |||
202 | cpy = GNUNET_strdup (s); | ||
203 | at = strchr (cpy, '@'); | ||
204 | if (NULL == at) | ||
205 | { | 201 | { |
206 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 202 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
207 | _("Unable to parse GNS2DNS record `%s'\n"), | 203 | _("Unable to parse PKEY record `%s'\n"), |
208 | s); | 204 | s); |
209 | GNUNET_free (cpy); | ||
210 | return GNUNET_SYSERR; | 205 | return GNUNET_SYSERR; |
211 | } | 206 | } |
212 | *at = '\0'; | 207 | *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); |
213 | at++; | 208 | GNUNET_memcpy (*data, &pkey, sizeof (pkey)); |
209 | *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
210 | return GNUNET_OK; | ||
214 | 211 | ||
215 | off = 0; | 212 | case GNUNET_GNSRECORD_TYPE_NICK: |
216 | if ( (GNUNET_OK != | 213 | *data = GNUNET_strdup (s); |
217 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | 214 | *data_size = strlen (s); |
218 | sizeof (nsbuf), | 215 | return GNUNET_OK; |
219 | &off, | 216 | case GNUNET_GNSRECORD_TYPE_LEHO: |
220 | cpy)) || | 217 | *data = GNUNET_strdup (s); |
221 | (GNUNET_OK != | 218 | *data_size = strlen (s); |
222 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | 219 | return GNUNET_OK; |
223 | sizeof (nsbuf), | 220 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: |
224 | &off, | ||
225 | at)) ) | ||
226 | { | 221 | { |
227 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 222 | char nsbuf[514]; |
228 | _("Failed to serialize GNS2DNS record with value `%s'\n"), | 223 | char *cpy; |
229 | s); | 224 | char *at; |
225 | size_t off; | ||
226 | |||
227 | cpy = GNUNET_strdup (s); | ||
228 | at = strchr (cpy, '@'); | ||
229 | if (NULL == at) | ||
230 | { | ||
231 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
232 | _("Unable to parse GNS2DNS record `%s'\n"), | ||
233 | s); | ||
234 | GNUNET_free (cpy); | ||
235 | return GNUNET_SYSERR; | ||
236 | } | ||
237 | *at = '\0'; | ||
238 | at++; | ||
239 | |||
240 | off = 0; | ||
241 | if ( (GNUNET_OK != | ||
242 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | ||
243 | sizeof (nsbuf), | ||
244 | &off, | ||
245 | cpy)) || | ||
246 | (GNUNET_OK != | ||
247 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | ||
248 | sizeof (nsbuf), | ||
249 | &off, | ||
250 | at)) ) | ||
251 | { | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
253 | _("Failed to serialize GNS2DNS record with value `%s'\n"), | ||
254 | s); | ||
255 | GNUNET_free (cpy); | ||
256 | return GNUNET_SYSERR; | ||
257 | } | ||
230 | GNUNET_free (cpy); | 258 | GNUNET_free (cpy); |
231 | return GNUNET_SYSERR; | 259 | *data_size = off; |
260 | *data = GNUNET_malloc (off); | ||
261 | GNUNET_memcpy (*data, nsbuf, off); | ||
262 | return GNUNET_OK; | ||
232 | } | 263 | } |
233 | GNUNET_free (cpy); | 264 | case GNUNET_GNSRECORD_TYPE_VPN: |
234 | *data_size = off; | ||
235 | *data = GNUNET_malloc (off); | ||
236 | GNUNET_memcpy (*data, nsbuf, off); | ||
237 | return GNUNET_OK; | ||
238 | } | ||
239 | case GNUNET_GNSRECORD_TYPE_VPN: | ||
240 | { | ||
241 | struct GNUNET_TUN_GnsVpnRecord *vpn; | ||
242 | char s_peer[103 + 1]; | ||
243 | char s_serv[253 + 1]; | ||
244 | unsigned int proto; | ||
245 | |||
246 | if (3 != SSCANF (s, | ||
247 | "%u %103s %253s", | ||
248 | &proto, s_peer, s_serv)) | ||
249 | { | 265 | { |
250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 266 | struct GNUNET_TUN_GnsVpnRecord *vpn; |
251 | _("Unable to parse VPN record string `%s'\n"), | 267 | char s_peer[103 + 1]; |
252 | s); | 268 | char s_serv[253 + 1]; |
253 | return GNUNET_SYSERR; | 269 | unsigned int proto; |
270 | |||
271 | if (3 != SSCANF (s, | ||
272 | "%u %103s %253s", | ||
273 | &proto, s_peer, s_serv)) | ||
274 | { | ||
275 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
276 | _("Unable to parse VPN record string `%s'\n"), | ||
277 | s); | ||
278 | return GNUNET_SYSERR; | ||
279 | } | ||
280 | *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; | ||
281 | *data = vpn = GNUNET_malloc (*data_size); | ||
282 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, | ||
283 | strlen (s_peer), | ||
284 | &vpn->peer.public_key)) | ||
285 | { | ||
286 | GNUNET_free (vpn); | ||
287 | *data_size = 0; | ||
288 | return GNUNET_SYSERR; | ||
289 | } | ||
290 | vpn->proto = htons ((uint16_t) proto); | ||
291 | strcpy ((char*)&vpn[1], s_serv); | ||
292 | return GNUNET_OK; | ||
254 | } | 293 | } |
255 | *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; | 294 | case GNUNET_GNSRECORD_TYPE_BOX: |
256 | *data = vpn = GNUNET_malloc (*data_size); | ||
257 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, | ||
258 | strlen (s_peer), | ||
259 | &vpn->peer.public_key)) | ||
260 | { | 295 | { |
261 | GNUNET_free (vpn); | 296 | struct GNUNET_GNSRECORD_BoxRecord *box; |
262 | *data_size = 0; | 297 | size_t rest; |
263 | return GNUNET_SYSERR; | 298 | unsigned int protocol; |
299 | unsigned int service; | ||
300 | unsigned int record_type; | ||
301 | void *bval; | ||
302 | size_t bval_size; | ||
303 | |||
304 | if (3 != SSCANF (s, | ||
305 | "%u %u %u ", | ||
306 | &protocol, | ||
307 | &service, | ||
308 | &record_type)) | ||
309 | { | ||
310 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
311 | _("Unable to parse BOX record string `%s'\n"), | ||
312 | s); | ||
313 | return GNUNET_SYSERR; | ||
314 | } | ||
315 | rest = snprintf (NULL, 0, | ||
316 | "%u %u %u ", | ||
317 | protocol, | ||
318 | service, | ||
319 | record_type); | ||
320 | if (GNUNET_OK != | ||
321 | GNUNET_GNSRECORD_string_to_value (record_type, | ||
322 | &s[rest], | ||
323 | &bval, | ||
324 | &bval_size)) | ||
325 | return GNUNET_SYSERR; | ||
326 | *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; | ||
327 | *data = box = GNUNET_malloc (*data_size); | ||
328 | box->protocol = htons (protocol); | ||
329 | box->service = htons (service); | ||
330 | box->record_type = htonl (record_type); | ||
331 | GNUNET_memcpy (&box[1], | ||
332 | bval, | ||
333 | bval_size); | ||
334 | GNUNET_free (bval); | ||
335 | return GNUNET_OK; | ||
264 | } | 336 | } |
265 | vpn->proto = htons ((uint16_t) proto); | 337 | case GNUNET_GNSRECORD_TYPE_REVERSE: |
266 | strcpy ((char*)&vpn[1], s_serv); | ||
267 | return GNUNET_OK; | ||
268 | } | ||
269 | case GNUNET_GNSRECORD_TYPE_BOX: | ||
270 | { | ||
271 | struct GNUNET_GNSRECORD_BoxRecord *box; | ||
272 | size_t rest; | ||
273 | unsigned int protocol; | ||
274 | unsigned int service; | ||
275 | unsigned int record_type; | ||
276 | void *bval; | ||
277 | size_t bval_size; | ||
278 | |||
279 | if (3 != SSCANF (s, | ||
280 | "%u %u %u ", | ||
281 | &protocol, | ||
282 | &service, | ||
283 | &record_type)) | ||
284 | { | 338 | { |
285 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 339 | struct GNUNET_GNSRECORD_ReverseRecord *rev; |
286 | _("Unable to parse BOX record string `%s'\n"), | 340 | char known_by[253 + 1]; |
287 | s); | 341 | struct GNUNET_TIME_Absolute expiration; |
288 | return GNUNET_SYSERR; | 342 | |
343 | /* TODO: From crypto_ecc.c | ||
344 | * Why is this not a constant??? | ||
345 | */ | ||
346 | size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | ||
347 | if (enclen % 5 > 0) | ||
348 | enclen += 5 - enclen % 5; | ||
349 | enclen /= 5; /* 260/5 = 52 */ | ||
350 | char pkey_str[enclen + 1]; | ||
351 | |||
352 | if (3 != SSCANF (s, | ||
353 | "%253s %52s %"SCNu64, | ||
354 | known_by, | ||
355 | pkey_str, | ||
356 | &expiration.abs_value_us)) | ||
357 | { | ||
358 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
359 | _("Unable to parse REVERSE record string `%s'\n"), | ||
360 | s); | ||
361 | return GNUNET_SYSERR; | ||
362 | } | ||
363 | *data_size = sizeof (struct GNUNET_GNSRECORD_ReverseRecord) + strlen (known_by) + 1; | ||
364 | *data = rev = GNUNET_malloc (*data_size); | ||
365 | GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey_str, | ||
366 | strlen (pkey_str), | ||
367 | &rev->pkey); | ||
368 | rev->expiration = expiration; | ||
369 | GNUNET_memcpy (&rev[1], | ||
370 | known_by, | ||
371 | strlen (known_by)); | ||
372 | return GNUNET_OK; | ||
289 | } | 373 | } |
290 | rest = snprintf (NULL, 0, | 374 | default: |
291 | "%u %u %u ", | 375 | return GNUNET_SYSERR; |
292 | protocol, | ||
293 | service, | ||
294 | record_type); | ||
295 | if (GNUNET_OK != | ||
296 | GNUNET_GNSRECORD_string_to_value (record_type, | ||
297 | &s[rest], | ||
298 | &bval, | ||
299 | &bval_size)) | ||
300 | return GNUNET_SYSERR; | ||
301 | *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; | ||
302 | *data = box = GNUNET_malloc (*data_size); | ||
303 | box->protocol = htons (protocol); | ||
304 | box->service = htons (service); | ||
305 | box->record_type = htonl (record_type); | ||
306 | GNUNET_memcpy (&box[1], | ||
307 | bval, | ||
308 | bval_size); | ||
309 | GNUNET_free (bval); | ||
310 | return GNUNET_OK; | ||
311 | } | ||
312 | default: | ||
313 | return GNUNET_SYSERR; | ||
314 | } | 376 | } |
315 | } | 377 | } |
316 | 378 | ||
@@ -329,6 +391,7 @@ static struct { | |||
329 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, | 391 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, |
330 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, | 392 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, |
331 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, | 393 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, |
394 | { "REVERSE", GNUNET_GNSRECORD_TYPE_REVERSE }, | ||
332 | { NULL, UINT32_MAX } | 395 | { NULL, UINT32_MAX } |
333 | }; | 396 | }; |
334 | 397 | ||
@@ -348,7 +411,7 @@ gns_typename_to_number (void *cls, | |||
348 | 411 | ||
349 | i=0; | 412 | i=0; |
350 | while ( (NULL != gns_name_map[i].name) && | 413 | while ( (NULL != gns_name_map[i].name) && |
351 | (0 != strcasecmp (gns_typename, | 414 | (0 != strcasecmp (gns_typename, |
352 | gns_name_map[i].name)) ) | 415 | gns_name_map[i].name)) ) |
353 | i++; | 416 | i++; |
354 | return gns_name_map[i].number; | 417 | return gns_name_map[i].number; |
@@ -370,7 +433,7 @@ gns_number_to_typename (void *cls, | |||
370 | 433 | ||
371 | i=0; | 434 | i=0; |
372 | while ( (NULL != gns_name_map[i].name) && | 435 | while ( (NULL != gns_name_map[i].name) && |
373 | (type != gns_name_map[i].number) ) | 436 | (type != gns_name_map[i].number) ) |
374 | i++; | 437 | i++; |
375 | return gns_name_map[i].name; | 438 | return gns_name_map[i].name; |
376 | } | 439 | } |