aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-03-12 10:18:53 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-03-12 10:18:53 +0000
commitf178ee5c79255d00eec5ed421d2e503b8d176fd0 (patch)
tree763cd0fda3c59d96216257d2b5487fe17a7d091f /src
parentfe61feeb1cdced8020f352289a86f61e3f02d1ad (diff)
downloadgnunet-f178ee5c79255d00eec5ed421d2e503b8d176fd0.tar.gz
gnunet-f178ee5c79255d00eec5ed421d2e503b8d176fd0.zip
-fixes, added get_authority api
Diffstat (limited to 'src')
-rw-r--r--src/gns/gns.h40
-rw-r--r--src/gns/gns_api.c131
-rw-r--r--src/gns/gnunet-service-gns.c240
-rw-r--r--src/gns/plugin_block_gns.c21
-rw-r--r--src/include/gnunet_gns_service.h37
5 files changed, 451 insertions, 18 deletions
diff --git a/src/gns/gns.h b/src/gns/gns.h
index e0cb0fd29..aad36ebfe 100644
--- a/src/gns/gns.h
+++ b/src/gns/gns.h
@@ -81,7 +81,7 @@ struct GNUNET_GNS_ClientLookupResultMessage
81}; 81};
82 82
83/** 83/**
84 * Message from client to GNS service to lookup records. 84 * Message from client to GNS service to shorten names.
85 */ 85 */
86struct GNUNET_GNS_ClientShortenMessage 86struct GNUNET_GNS_ClientShortenMessage
87{ 87{
@@ -117,6 +117,44 @@ struct GNUNET_GNS_ClientShortenResultMessage
117 /* followed by the shortened name or '\0' for no result*/ 117 /* followed by the shortened name or '\0' for no result*/
118 118
119}; 119};
120
121/**
122 * Message from client to GNS service to lookup an authority of a name.
123 */
124struct GNUNET_GNS_ClientGetAuthMessage
125{
126 /**
127 * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_GET_AUTH
128 */
129 struct GNUNET_MessageHeader header;
130
131 /**
132 * Unique identifier for this request
133 */
134 uint32_t id GNUNET_PACKED;
135
136 /* Followed by the name to get authority for */
137};
138
139
140/**
141 * Message from GNS service to client: authority result.
142 */
143struct GNUNET_GNS_ClientGetAuthResultMessage
144{
145 /**
146 * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_GET_AUTH_RESULT
147 */
148 struct GNUNET_MessageHeader header;
149
150 /**
151 * Unique identifier for this request (for key collisions).
152 */
153 uint32_t id GNUNET_PACKED;
154
155 /* followed by the authority part of the name or '\0' for no result*/
156
157};
120GNUNET_NETWORK_STRUCT_END 158GNUNET_NETWORK_STRUCT_END
121 159
122#endif 160#endif
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c
index f9aa63335..be1ba58f7 100644
--- a/src/gns/gns_api.c
+++ b/src/gns/gns_api.c
@@ -40,6 +40,8 @@
40#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24 40#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24
41#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25 41#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25
42#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 42#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26
43#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27
44#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28
43 45
44/** 46/**
45 * A QueueEntry. 47 * A QueueEntry.
@@ -67,6 +69,9 @@ struct GNUNET_GNS_QueueEntry
67 69
68 /* processor to call on lookup result */ 70 /* processor to call on lookup result */
69 GNUNET_GNS_LookupResultProcessor lookup_proc; 71 GNUNET_GNS_LookupResultProcessor lookup_proc;
72
73 /* processor to call on authority lookup result */
74 GNUNET_GNS_GetAuthResultProcessor auth_proc;
70 75
71 /* processor closure */ 76 /* processor closure */
72 void *proc_cls; 77 void *proc_cls;
@@ -151,6 +156,16 @@ struct GNUNET_GNS_Handle
151 struct GNUNET_GNS_QueueEntry *lookup_tail; 156 struct GNUNET_GNS_QueueEntry *lookup_tail;
152 157
153 /** 158 /**
159 * Head of linked list of authority lookup messages we would like to transmit.
160 */
161 struct GNUNET_GNS_QueueEntry *get_auth_head;
162
163 /**
164 * Tail of linked list of authority lookup messages we would like to transmit.
165 */
166 struct GNUNET_GNS_QueueEntry *get_auth_tail;
167
168 /**
154 * Reconnect task 169 * Reconnect task
155 */ 170 */
156 GNUNET_SCHEDULER_TaskIdentifier reconnect_task; 171 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
@@ -360,6 +375,39 @@ process_shorten_reply (struct GNUNET_GNS_QueueEntry *qe,
360 375
361 376
362/** 377/**
378 * Process a given reply that might match the given
379 * request.
380 *
381 * @param qe the handle to the request
382 * @param msg the message to process
383 */
384static void
385process_get_auth_reply (struct GNUNET_GNS_QueueEntry *qe,
386 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
387{
388 struct GNUNET_GNS_Handle *h = qe->gns_handle;
389 const char *auth_name;
390
391 GNUNET_CONTAINER_DLL_remove(h->get_auth_head, h->get_auth_tail, qe);
392
393 auth_name = (char*)(&msg[1]);
394
395 if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) <
396 sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
397 {
398 GNUNET_break (0);
399 force_reconnect (h);
400 return;
401 }
402
403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
404 "Received GET_AUTH reply `%s' from GNS service\n",
405 auth_name);
406
407 qe->auth_proc(qe->proc_cls, auth_name);
408
409}
410/**
363 * Process a given reply to the lookup request 411 * Process a given reply to the lookup request
364 * 412 *
365 * @param cls the 'struct GNUNET_GNS_ClientResultMessage' 413 * @param cls the 'struct GNUNET_GNS_ClientResultMessage'
@@ -412,6 +460,7 @@ process_message (void *cls, const struct GNUNET_MessageHeader *msg)
412 struct GNUNET_GNS_QueueEntry *qe; 460 struct GNUNET_GNS_QueueEntry *qe;
413 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; 461 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
414 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; 462 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
463 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
415 uint16_t size; 464 uint16_t size;
416 uint16_t type; 465 uint16_t type;
417 uint32_t r_id; 466 uint32_t r_id;
@@ -457,7 +506,7 @@ process_message (void *cls, const struct GNUNET_MessageHeader *msg)
457 else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) 506 else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT)
458 { 507 {
459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
460 "Got shorten msg\n"); 509 "Got SHORTEN_RESULT msg\n");
461 shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg; 510 shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg;
462 511
463 r_id = ntohl (shorten_msg->id); 512 r_id = ntohl (shorten_msg->id);
@@ -478,6 +527,30 @@ process_message (void *cls, const struct GNUNET_MessageHeader *msg)
478 if (qe) 527 if (qe)
479 process_shorten_reply(qe, shorten_msg); 528 process_shorten_reply(qe, shorten_msg);
480 } 529 }
530 else if (type == GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT)
531 {
532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
533 "Got GET_AUTH_RESULT msg\n");
534 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
535
536 r_id = ntohl (get_auth_msg->id);
537
538 if (r_id > handle->r_id)
539 {
540 /** no request found */
541 GNUNET_break_op (0);
542 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
543 GNUNET_TIME_UNIT_FOREVER_REL);
544 }
545
546 for (qe = handle->get_auth_head; qe != NULL; qe = qe->next)
547 {
548 if (qe->r_id == r_id)
549 break;
550 }
551 if (qe)
552 process_get_auth_reply(qe, get_auth_msg);
553 }
481 554
482 GNUNET_CLIENT_receive (handle->client, &process_message, handle, 555 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
483 GNUNET_TIME_UNIT_FOREVER_REL); 556 GNUNET_TIME_UNIT_FOREVER_REL);
@@ -651,5 +724,61 @@ GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
651} 724}
652 725
653 726
727/**
728 * Perform an authority lookup for a given name.
729 *
730 * @param handle handle to the GNS service
731 * @param name the name to look up authority for
732 * @param proc function to call on result
733 * @param proc_cls closure for processor
734 * @return handle to the operation
735 */
736struct GNUNET_GNS_QueueEntry *
737GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
738 const char * name,
739 GNUNET_GNS_GetAuthResultProcessor proc,
740 void *proc_cls)
741{
742 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
743 struct GNUNET_GNS_QueueEntry *qe;
744 size_t msize;
745 struct PendingMessage *pending;
746
747 if (NULL == name)
748 {
749 return NULL;
750 }
751
752 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen(name) + 1;
753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
754 "Trying to look up authority for %s in GNS\n", name);
755
756 qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry));
757 qe->gns_handle = handle;
758 qe->shorten_proc = proc;
759 qe->proc_cls = proc_cls;
760 qe->r_id = get_request_id(handle);
761 GNUNET_CONTAINER_DLL_insert_tail(handle->get_auth_head,
762 handle->get_auth_tail, qe);
763
764 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
765 memset(pending, 0, (sizeof (struct PendingMessage) + msize));
766
767 pending->size = msize;
768
769 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
770 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
771 get_auth_msg->header.size = htons (msize);
772 get_auth_msg->id = htonl(qe->r_id);
773
774 memcpy(&get_auth_msg[1], name, strlen(name));
775
776 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
777 pending);
778
779 process_pending_messages (handle);
780 return qe;
781}
782
654 783
655/* end of gns_api.c */ 784/* end of gns_api.c */
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index 072c349da..8d9932ead 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -44,11 +44,13 @@
44#define DHT_GNS_REPLICATION_LEVEL 5 44#define DHT_GNS_REPLICATION_LEVEL 5
45#define MAX_DNS_LABEL_LENGTH 63 45#define MAX_DNS_LABEL_LENGTH 63
46 46
47/* Ignore for now not used anyway and probably never will */ 47/* FIXME move to proper header in include */
48#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23 48#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23
49#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24 49#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24
50#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25 50#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25
51#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 51#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26
52#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27
53#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28
52 54
53 55
54struct AuthorityChain 56struct AuthorityChain
@@ -177,6 +179,24 @@ struct ClientShortenHandle
177 179
178}; 180};
179 181
182
183/**
184 * Handle to a get auhtority operation from api
185 */
186struct ClientGetAuthHandle
187{
188 /* the requesting client that */
189 struct GNUNET_SERVER_Client *client;
190
191 /* request id */
192 uint64_t unique_id;
193
194 /* name to lookup authority */
195 char* name;
196
197};
198
199
180/** 200/**
181 * Handle to a lookup operation from api 201 * Handle to a lookup operation from api
182 */ 202 */
@@ -2097,10 +2117,8 @@ handle_shorten_delegation_result(void* cls,
2097 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2117 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2098 "Our zone: Sending name as shorten result %s\n", rh->name); 2118 "Our zone: Sending name as shorten result %s\n", rh->name);
2099 2119
2100 send_shorten_response(rh->name, csh); //FIXME +.gnunet! 2120 send_shorten_response(result, csh); //FIXME +.gnunet!
2101 free_resolver_handle(rh); 2121 free_resolver_handle(rh);
2102 GNUNET_free(csh->name);
2103 GNUNET_free(csh);
2104 GNUNET_free(result); 2122 GNUNET_free(result);
2105 return; 2123 return;
2106 } 2124 }
@@ -2145,9 +2163,9 @@ shorten_name(char* name, struct ClientShortenHandle* csh)
2145 2163
2146 csh->name = GNUNET_malloc(strlen(name) 2164 csh->name = GNUNET_malloc(strlen(name)
2147 - strlen(gnunet_tld) + 1); 2165 - strlen(gnunet_tld) + 1);
2148 memset(rh->name, 0, 2166 memset(csh->name, 0,
2149 strlen(name)-strlen(gnunet_tld) + 1); 2167 strlen(name)-strlen(gnunet_tld) + 1);
2150 memcpy(rh->name, name, 2168 memcpy(csh->name, name,
2151 strlen(name)-strlen(gnunet_tld)); 2169 strlen(name)-strlen(gnunet_tld));
2152 2170
2153 rh->authority_name = GNUNET_malloc(sizeof(char)*MAX_DNS_LABEL_LENGTH); 2171 rh->authority_name = GNUNET_malloc(sizeof(char)*MAX_DNS_LABEL_LENGTH);
@@ -2248,6 +2266,211 @@ static void handle_shorten(void *cls,
2248 2266
2249} 2267}
2250 2268
2269
2270/**
2271 * Send get authority response back to client
2272 *
2273 * @param name the shortened name result or NULL if cannot be shortened
2274 * @param cah the handle to the get authority request
2275 */
2276static void
2277send_get_auth_response(const char* name, struct ClientGetAuthHandle *cah)
2278{
2279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n",
2280 "GET_AUTH_RESULT", name);
2281 struct GNUNET_GNS_ClientGetAuthResultMessage *rmsg;
2282
2283 if (name == NULL)
2284 {
2285 name = "";
2286 }
2287
2288 rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage)
2289 + strlen(name) + 1);
2290
2291 rmsg->id = cah->unique_id;
2292 rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT);
2293 rmsg->header.size =
2294 htons(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) +
2295 strlen(name) + 1);
2296
2297 strcpy((char*)&rmsg[1], name);
2298
2299 GNUNET_SERVER_notification_context_unicast (nc, cah->client,
2300 (const struct GNUNET_MessageHeader *) rmsg,
2301 GNUNET_NO);
2302 GNUNET_SERVER_receive_done (cah->client, GNUNET_OK);
2303
2304 GNUNET_free(rmsg);
2305 GNUNET_free(cah->name);
2306 GNUNET_free(cah);
2307
2308}
2309
2310/**
2311 * Process result from namestore delegation lookup
2312 * for get authority operation
2313 *
2314 * @param cls the client get auth handle
2315 * @param rh the resolver handle
2316 * @param rd_count number of results (0)
2317 * @param rd data (NULL)
2318 */
2319void
2320handle_get_auth_delegation_result(void* cls,
2321 struct GNUNET_GNS_ResolverHandle *rh,
2322 uint32_t rd_count,
2323 const struct GNUNET_NAMESTORE_RecordData *rd)
2324{
2325 struct ClientGetAuthHandle* cah = (struct ClientGetAuthHandle*) cls;
2326 struct AuthorityChain *auth_chain;
2327 char* result;
2328 size_t answer_len;
2329
2330 /**
2331 * At this point rh->name contains the part of the name
2332 * that we do not have a PKEY in our namestore to resolve.
2333 * The authority chain in the resolver handle is now
2334 * useful to backtrack if needed
2335 */
2336
2337 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2338 "PKEY resolved as far as possible in ns up to %s!\n", rh->name);
2339
2340 if (is_canonical(rh->name))
2341 {
2342 /**
2343 * We successfully resolved the authority in the ns
2344 * FIXME for our purposes this is fine
2345 * but maybe we want to have an api that also looks
2346 * into the dht (i.e. option in message)
2347 **/
2348 if (strlen(rh->name) > strlen(cah->name))
2349 {
2350 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2351 "Record name longer than original lookup name... odd!\n");
2352 //FIXME to sth here
2353 }
2354
2355
2356 answer_len = strlen(cah->name) - strlen(rh->name);
2357 result = GNUNET_malloc(answer_len);
2358 memset(result, 0, answer_len);
2359 strcpy(result, cah->name + strlen(rh->name) + 1);
2360
2361 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2362 "Our zone: Sending authority result %s\n", result);
2363
2364 send_get_auth_response(result, cah);
2365 free_resolver_handle(rh);
2366 GNUNET_free(result);
2367 return;
2368 }
2369
2370 auth_chain = rh->authority_chain_head;
2371 /* backtrack authorities for pseu */
2372 GNUNET_NAMESTORE_zone_to_name (namestore_handle,
2373 &zone_hash, //ours
2374 &auth_chain->zone,
2375 &handle_shorten_zone_to_name,
2376 rh);
2377
2378}
2379
2380
2381/**
2382 * Get authority for a given name
2383 *
2384 * @param name the name to shorten
2385 * @param csh the shorten handle of the request
2386 */
2387static void
2388get_authority(char* name, struct ClientGetAuthHandle* cah)
2389{
2390
2391 struct GNUNET_GNS_ResolverHandle *rh;
2392
2393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2394 "Starting authority resolution for %s (type=%d)!\n",
2395 name, GNUNET_GNS_RECORD_PKEY);
2396
2397 rh = GNUNET_malloc(sizeof (struct GNUNET_GNS_ResolverHandle));
2398 rh->authority = zone_hash;
2399
2400 rh->name = GNUNET_malloc(strlen(name)
2401 - strlen(gnunet_tld) + 1);
2402 memset(rh->name, 0,
2403 strlen(name)-strlen(gnunet_tld) + 1);
2404 memcpy(rh->name, name,
2405 strlen(name)-strlen(gnunet_tld));
2406
2407 cah->name = GNUNET_malloc(strlen(name)
2408 - strlen(gnunet_tld) + 1);
2409 memset(cah->name, 0,
2410 strlen(name)-strlen(gnunet_tld) + 1);
2411 memcpy(cah->name, name,
2412 strlen(name)-strlen(gnunet_tld));
2413
2414 rh->authority_name = GNUNET_malloc(sizeof(char)*MAX_DNS_LABEL_LENGTH);
2415
2416 rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain));
2417 rh->authority_chain_tail = rh->authority_chain_head;
2418 rh->authority_chain_head->zone = zone_hash;
2419 rh->proc = &handle_get_auth_delegation_result;
2420 rh->proc_cls = (void*)cah;
2421
2422 /* Start delegation resolution in our namestore */
2423 resolve_delegation_ns(rh);
2424
2425}
2426
2427
2428/**
2429 * Handle a get authority message from the api
2430 *
2431 * @param cls the closure
2432 * @param client the client
2433 * @param message the message
2434 */
2435static void handle_get_authority(void *cls,
2436 struct GNUNET_SERVER_Client * client,
2437 const struct GNUNET_MessageHeader * message)
2438{
2439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "GET_AUTH");
2440
2441 size_t msg_size = 0;
2442 struct ClientGetAuthHandle *cah;
2443
2444 if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientGetAuthMessage))
2445 {
2446 GNUNET_break_op (0);
2447 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2448 return;
2449 }
2450
2451 GNUNET_SERVER_notification_context_add (nc, client);
2452
2453 struct GNUNET_GNS_ClientGetAuthMessage *sh_msg =
2454 (struct GNUNET_GNS_ClientGetAuthMessage *) message;
2455
2456 msg_size = ntohs(message->size);
2457
2458 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
2459 {
2460 GNUNET_break_op (0);
2461 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2462 return;
2463 }
2464
2465 cah = GNUNET_malloc(sizeof(struct ClientGetAuthHandle));
2466 cah->client = client;
2467 cah->unique_id = sh_msg->id;
2468
2469 get_authority((char*)&sh_msg[1], cah);
2470
2471}
2472
2473
2251/** 2474/**
2252 * Reply to client with the result from our lookup. 2475 * Reply to client with the result from our lookup.
2253 * 2476 *
@@ -2390,6 +2613,8 @@ handle_lookup(void *cls,
2390 lookup_name((char*)&sh_msg[1], clh); 2613 lookup_name((char*)&sh_msg[1], clh);
2391} 2614}
2392 2615
2616
2617
2393/** 2618/**
2394 * Process GNS requests. 2619 * Process GNS requests.
2395 * 2620 *
@@ -2409,7 +2634,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
2409 2634
2410 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 2635 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
2411 {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0}, 2636 {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0},
2412 {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0} 2637 {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0},
2638 {&handle_get_authority, NULL, GNUNET_MESSAGE_TYPE_GNS_GET_AUTH, 0}
2413 }; 2639 };
2414 2640
2415 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "gns", 2641 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "gns",
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c
index fd6fcc250..4c8ab3eb9 100644
--- a/src/gns/plugin_block_gns.c
+++ b/src/gns/plugin_block_gns.c
@@ -72,6 +72,7 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
72 uint32_t rd_count; 72 uint32_t rd_count;
73 char* rd_data = NULL; 73 char* rd_data = NULL;
74 int rd_len; 74 int rd_len;
75 uint32_t record_xquery;
75 unsigned int record_match; 76 unsigned int record_match;
76 77
77 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) 78 if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD)
@@ -102,7 +103,7 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
102 { 103 {
103 struct GNUNET_NAMESTORE_RecordData rd[rd_count]; 104 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
104 unsigned int i; 105 unsigned int i;
105 uint32_t record_xquery = ntohl(*((uint32_t*)xquery)); 106 struct GNUNET_TIME_Absolute exp = GNUNET_TIME_absolute_get_forever();
106 107
107 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_len, 108 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_len,
108 rd_data, 109 rd_data,
@@ -113,18 +114,26 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
113 "Data invalid (%d bytes, %d records)\n", rd_len, rd_count); 114 "Data invalid (%d bytes, %d records)\n", rd_len, rd_count);
114 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; 115 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
115 } 116 }
117
118 if (xquery_size < sizeof(uint32_t))
119 record_xquery = 0;
120 else
121 record_xquery = ntohl(*((uint32_t*)xquery));
116 122
117 for (i=0; i<rd_count; i++) 123 for (i=0; i<rd_count; i++)
118 { 124 {
119 if (xquery_size < sizeof(uint32_t))
120 continue;
121 125
122 if (rd[i].record_type == record_xquery) 126 exp = GNUNET_TIME_absolute_min (exp, rd[i].expiration);
127
128 if ((record_xquery != 0)
129 && (rd[i].record_type == record_xquery))
130 {
123 record_match++; 131 record_match++;
132 }
124 } 133 }
125 134
126 if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature (&nrb->public_key, 135 if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature (&nrb->public_key,
127 GNUNET_TIME_absolute_get_forever(), 136 exp,
128 name, 137 name,
129 rd_count, 138 rd_count,
130 rd, 139 rd,
@@ -136,7 +145,7 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
136 } 145 }
137 146
138 //No record matches query 147 //No record matches query
139 if ((xquery_size > 0) && (record_match == 0)) 148 if ((record_xquery != 0) && (record_match == 0))
140 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 149 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
141 150
142 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Records match\n"); 151 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Records match\n");
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h
index 5ae7fbefe..66cbab820 100644
--- a/src/include/gnunet_gns_service.h
+++ b/src/include/gnunet_gns_service.h
@@ -145,7 +145,6 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
145 * called only once 145 * called only once
146 * 146 *
147 * @param cls closure 147 * @param cls closure
148 * @param name "name" of the original lookup
149 * @param short_name the shortened name or NULL if no result 148 * @param short_name the shortened name or NULL if no result
150 */ 149 */
151typedef void (*GNUNET_GNS_ShortenResultProcessor) (void *cls, 150typedef void (*GNUNET_GNS_ShortenResultProcessor) (void *cls,
@@ -158,7 +157,7 @@ typedef void (*GNUNET_GNS_ShortenResultProcessor) (void *cls,
158 * @param handle handle to the GNS service 157 * @param handle handle to the GNS service
159 * @param name the name to shorten 158 * @param name the name to shorten
160 * @param proc processor to call on result 159 * @param proc processor to call on result
161 * @param iter_cls closure for processor 160 * @param cls closure for processor
162 * 161 *
163 * @return handle to the shorten operation 162 * @return handle to the shorten operation
164 */ 163 */
@@ -166,7 +165,39 @@ struct GNUNET_GNS_QueueEntry *
166GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, 165GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
167 const char * name, 166 const char * name,
168 GNUNET_GNS_ShortenResultProcessor proc, 167 GNUNET_GNS_ShortenResultProcessor proc,
169 void *iter_cls); 168 void *cls);
169
170
171/* *************** Standard API: get authority ******************* */
172
173
174/**
175 * Processor called on for a name shortening result
176 * called only once
177 *
178 * @param cls closure
179 * @param auth_name the name of the auhtority or NULL
180 */
181typedef void (*GNUNET_GNS_GetAuthResultProcessor) (void *cls,
182 const char* short_name);
183
184
185/**
186 * Perform a shorten operation on name using the GNS.
187 *
188 * @param handle handle to the GNS service
189 * @param name the name to look up authority for
190 * @param proc processor to call on result
191 * @param cls closure for processor
192 *
193 * @return handle to the get authority operation
194 */
195struct GNUNET_GNS_QueueEntry *
196GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
197 const char * name,
198 GNUNET_GNS_GetAuthResultProcessor proc,
199 void *cls);
200
170#if 0 /* keep Emacsens' auto-indent happy */ 201#if 0 /* keep Emacsens' auto-indent happy */
171{ 202{
172#endif 203#endif