aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-25 15:23:43 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-25 15:23:43 +0000
commitbc09b870c221f1d9c3c61b8ee251fa0f25c7aa22 (patch)
tree5a6a42c23c602fbd0ecd8c40f713b34f5e38fb11 /src/namestore
parentcdb31e2722288aa9a9b61c548edd498145cadf6e (diff)
downloadgnunet-bc09b870c221f1d9c3c61b8ee251fa0f25c7aa22.tar.gz
gnunet-bc09b870c221f1d9c3c61b8ee251fa0f25c7aa22.zip
convert namestore_api to MQ
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/namestore_api.c1156
1 files changed, 548 insertions, 608 deletions
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index f65c45e85..c0aa79e3f 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 GNUnet e.V. 3 Copyright (C) 2010-2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -61,7 +61,7 @@ struct GNUNET_NAMESTORE_QueueEntry
61 /** 61 /**
62 * Main handle to access the namestore. 62 * Main handle to access the namestore.
63 */ 63 */
64 struct GNUNET_NAMESTORE_Handle *nsh; 64 struct GNUNET_NAMESTORE_Handle *h;
65 65
66 /** 66 /**
67 * Continuation to call 67 * Continuation to call
@@ -69,7 +69,7 @@ struct GNUNET_NAMESTORE_QueueEntry
69 GNUNET_NAMESTORE_ContinuationWithStatus cont; 69 GNUNET_NAMESTORE_ContinuationWithStatus cont;
70 70
71 /** 71 /**
72 * Closure for 'cont'. 72 * Closure for @e cont.
73 */ 73 */
74 void *cont_cls; 74 void *cont_cls;
75 75
@@ -84,6 +84,12 @@ struct GNUNET_NAMESTORE_QueueEntry
84 void *proc_cls; 84 void *proc_cls;
85 85
86 /** 86 /**
87 * Envelope of the message to send to the service, if not yet
88 * sent.
89 */
90 struct GNUNET_MQ_Envelope *env;
91
92 /**
87 * The operation id this zone iteration operation has 93 * The operation id this zone iteration operation has
88 */ 94 */
89 uint32_t op_id; 95 uint32_t op_id;
@@ -120,7 +126,13 @@ struct GNUNET_NAMESTORE_ZoneIterator
120 /** 126 /**
121 * Closure for @e proc. 127 * Closure for @e proc.
122 */ 128 */
123 void* proc_cls; 129 void *proc_cls;
130
131 /**
132 * Envelope of the message to send to the service, if not yet
133 * sent.
134 */
135 struct GNUNET_MQ_Envelope *env;
124 136
125 /** 137 /**
126 * Private key of the zone. 138 * Private key of the zone.
@@ -136,31 +148,6 @@ struct GNUNET_NAMESTORE_ZoneIterator
136 148
137 149
138/** 150/**
139 * Message in linked list we should send to the service. The
140 * actual binary message follows this struct.
141 */
142struct PendingMessage
143{
144
145 /**
146 * Kept in a DLL.
147 */
148 struct PendingMessage *next;
149
150 /**
151 * Kept in a DLL.
152 */
153 struct PendingMessage *prev;
154
155 /**
156 * Size of the message.
157 */
158 size_t size;
159
160};
161
162
163/**
164 * Connection to the NAMESTORE service. 151 * Connection to the NAMESTORE service.
165 */ 152 */
166struct GNUNET_NAMESTORE_Handle 153struct GNUNET_NAMESTORE_Handle
@@ -172,24 +159,9 @@ struct GNUNET_NAMESTORE_Handle
172 const struct GNUNET_CONFIGURATION_Handle *cfg; 159 const struct GNUNET_CONFIGURATION_Handle *cfg;
173 160
174 /** 161 /**
175 * Socket (if available). 162 * Connection to the service (if available).
176 */ 163 */
177 struct GNUNET_CLIENT_Connection *client; 164 struct GNUNET_MQ_Handle *mq;
178
179 /**
180 * Currently pending transmission request (or NULL).
181 */
182 struct GNUNET_CLIENT_TransmitHandle *th;
183
184 /**
185 * Head of linked list of pending messages to send to the service
186 */
187 struct PendingMessage *pending_head;
188
189 /**
190 * Tail of linked list of pending messages to send to the service
191 */
192 struct PendingMessage *pending_tail;
193 165
194 /** 166 /**
195 * Head of pending namestore queue entries 167 * Head of pending namestore queue entries
@@ -214,7 +186,7 @@ struct GNUNET_NAMESTORE_Handle
214 /** 186 /**
215 * Reconnect task 187 * Reconnect task
216 */ 188 */
217 struct GNUNET_SCHEDULER_Task * reconnect_task; 189 struct GNUNET_SCHEDULER_Task *reconnect_task;
218 190
219 /** 191 /**
220 * Delay introduced before we reconnect. 192 * Delay introduced before we reconnect.
@@ -227,11 +199,6 @@ struct GNUNET_NAMESTORE_Handle
227 int reconnect; 199 int reconnect;
228 200
229 /** 201 /**
230 * Did we start to receive yet?
231 */
232 int is_receiving;
233
234 /**
235 * The last operation id used for a NAMESTORE operation 202 * The last operation id used for a NAMESTORE operation
236 */ 203 */
237 uint32_t last_op_id_used; 204 uint32_t last_op_id_used;
@@ -249,51 +216,129 @@ force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
249 216
250 217
251/** 218/**
219 * Find the queue entry that matches the @a rid
220 *
221 * @param h namestore handle
222 * @param rid id to look up
223 * @return NULL if @a rid was not found
224 */
225static struct GNUNET_NAMESTORE_QueueEntry *
226find_qe (struct GNUNET_NAMESTORE_Handle *h,
227 uint32_t rid)
228{
229 struct GNUNET_NAMESTORE_QueueEntry *qe;
230
231 for (qe = h->op_head; qe != NULL; qe = qe->next)
232 if (qe->op_id == rid)
233 return qe;
234 return NULL;
235}
236
237
238/**
239 * Find the zone iteration entry that matches the @a rid
240 *
241 * @param h namestore handle
242 * @param rid id to look up
243 * @return NULL if @a rid was not found
244 */
245static struct GNUNET_NAMESTORE_ZoneIterator *
246find_zi (struct GNUNET_NAMESTORE_Handle *h,
247 uint32_t rid)
248{
249 struct GNUNET_NAMESTORE_ZoneIterator *ze;
250
251 for (ze = h->z_head; ze != NULL; ze = ze->next)
252 if (ze->op_id == rid)
253 return ze;
254 return NULL;
255}
256
257
258/**
259 * Free @a qe.
260 *
261 * @param qe entry to free
262 */
263static void
264free_qe (struct GNUNET_NAMESTORE_QueueEntry *qe)
265{
266 struct GNUNET_NAMESTORE_Handle *h = qe->h;
267
268 GNUNET_CONTAINER_DLL_remove (h->op_head,
269 h->op_tail,
270 qe);
271 if (NULL != qe->env)
272 GNUNET_MQ_discard (qe->env);
273 GNUNET_free (qe);
274}
275
276
277/**
278 * Free @a ze.
279 *
280 * @param ze entry to free
281 */
282static void
283free_ze (struct GNUNET_NAMESTORE_ZoneIterator *ze)
284{
285 struct GNUNET_NAMESTORE_Handle *h = ze->h;
286
287 GNUNET_CONTAINER_DLL_remove (h->z_head,
288 h->z_tail,
289 ze);
290 if (NULL != ze->env)
291 GNUNET_MQ_discard (ze->env);
292 GNUNET_free (ze);
293}
294
295
296/**
252 * Handle an incoming message of type 297 * Handle an incoming message of type
253 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE 298 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
254 * 299 *
255 * @param qe the respective entry in the message queue 300 * @param cls
256 * @param msg the message we received 301 * @param msg the message we received
257 * @param size the message size
258 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
259 */ 302 */
260static int 303static void
261handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 304handle_record_store_response (void *cls,
262 const struct RecordStoreResponseMessage* msg, 305 const struct RecordStoreResponseMessage *msg)
263 size_t size)
264{ 306{
307 struct GNUNET_NAMESTORE_Handle *h = cls;
308 struct GNUNET_NAMESTORE_QueueEntry *qe;
265 int res; 309 int res;
266 const char *emsg; 310 const char *emsg;
267 311
312 qe = find_qe (h,
313 ntohl (msg->gns_header.r_id));
314 res = ntohl (msg->op_result);
268 LOG (GNUNET_ERROR_TYPE_DEBUG, 315 LOG (GNUNET_ERROR_TYPE_DEBUG,
269 "Received `%s' with result %i\n", 316 "Received RECORD_STORE_RESPONSE with result %d\n",
270 "RECORD_STORE_RESPONSE", 317 res);
271 ntohl (msg->op_result));
272 /* TODO: add actual error message from namestore to response... */ 318 /* TODO: add actual error message from namestore to response... */
273 res = ntohl (msg->op_result);
274 if (GNUNET_SYSERR == res) 319 if (GNUNET_SYSERR == res)
275 emsg = _("Namestore failed to store record\n"); 320 emsg = _("Namestore failed to store record\n");
276 else 321 else
277 emsg = NULL; 322 emsg = NULL;
278 if (NULL != qe->cont) 323 if (NULL != qe->cont)
279 qe->cont (qe->cont_cls, res, emsg); 324 qe->cont (qe->cont_cls,
280 return GNUNET_OK; 325 res,
326 emsg);
327 free_qe (qe);
281} 328}
282 329
283 330
284/** 331/**
285 * Handle an incoming message of type 332 * Check validity of an incoming message of type
286 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE 333 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
287 * 334 *
288 * @param qe the respective entry in the message queue 335 * @param cls
289 * @param msg the message we received 336 * @param msg the message we received
290 * @param size the message size 337 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
291 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
292 */ 338 */
293static int 339static int
294handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe, 340check_lookup_result (void *cls,
295 const struct LabelLookupResponseMessage *msg, 341 const struct LabelLookupResponseMessage *msg)
296 size_t size)
297{ 342{
298 const char *name; 343 const char *name;
299 const char *rd_tmp; 344 const char *rd_tmp;
@@ -302,18 +347,12 @@ handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
302 size_t name_len; 347 size_t name_len;
303 size_t rd_len; 348 size_t rd_len;
304 unsigned int rd_count; 349 unsigned int rd_count;
305 int found;
306
307 LOG (GNUNET_ERROR_TYPE_DEBUG,
308 "Received `%s'\n",
309 "RECORD_LOOKUP_RESULT");
310 350
311 rd_len = ntohs (msg->rd_len); 351 rd_len = ntohs (msg->rd_len);
312 rd_count = ntohs (msg->rd_count); 352 rd_count = ntohs (msg->rd_count);
313 msg_len = ntohs (msg->gns_header.header.size); 353 msg_len = ntohs (msg->gns_header.header.size);
314 name_len = ntohs (msg->name_len); 354 name_len = ntohs (msg->name_len);
315 found = ntohs (msg->found); 355 exp_msg_len = sizeof (*msg) + name_len + rd_len;
316 exp_msg_len = sizeof (struct LabelLookupResponseMessage) + name_len + rd_len;
317 if (msg_len != exp_msg_len) 356 if (msg_len != exp_msg_len)
318 { 357 {
319 GNUNET_break (0); 358 GNUNET_break (0);
@@ -326,26 +365,84 @@ handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
326 GNUNET_break (0); 365 GNUNET_break (0);
327 return GNUNET_SYSERR; 366 return GNUNET_SYSERR;
328 } 367 }
329 if (GNUNET_NO == found) 368 if (GNUNET_NO == ntohs (msg->found))
369 {
370 if (0 != rd_count)
371 {
372 GNUNET_break (0);
373 return GNUNET_SYSERR;
374 }
375 return GNUNET_OK;
376 }
377 rd_tmp = &name[name_len];
378 {
379 struct GNUNET_GNSRECORD_Data rd[rd_count];
380
381 if (GNUNET_OK !=
382 GNUNET_GNSRECORD_records_deserialize (rd_len,
383 rd_tmp,
384 rd_count,
385 rd))
386 {
387 GNUNET_break (0);
388 return GNUNET_SYSERR;
389 }
390 }
391 return GNUNET_OK;
392}
393
394
395/**
396 * Handle an incoming message of type
397 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
398 *
399 * @param cls
400 * @param msg the message we received
401 */
402static void
403handle_lookup_result (void *cls,
404 const struct LabelLookupResponseMessage *msg)
405{
406 struct GNUNET_NAMESTORE_Handle *h = cls;
407 struct GNUNET_NAMESTORE_QueueEntry *qe;
408 const char *name;
409 const char *rd_tmp;
410 size_t name_len;
411 size_t rd_len;
412 unsigned int rd_count;
413
414 LOG (GNUNET_ERROR_TYPE_DEBUG,
415 "Received RECORD_LOOKUP_RESULT\n");
416 qe = find_qe (h,
417 ntohl (msg->gns_header.r_id));
418 if (NULL == qe)
419 return;
420 rd_len = ntohs (msg->rd_len);
421 rd_count = ntohs (msg->rd_count);
422 name_len = ntohs (msg->name_len);
423 name = (const char *) &msg[1];
424 if (GNUNET_NO == ntohs (msg->found))
330 { 425 {
331 /* label was not in namestore */ 426 /* label was not in namestore */
332 if (NULL != qe->proc) 427 if (NULL != qe->proc)
333 qe->proc (qe->proc_cls, 428 qe->proc (qe->proc_cls,
334 &msg->private_key, 429 &msg->private_key,
335 name, 430 name,
336 0, NULL); 431 0,
337 return GNUNET_OK; 432 NULL);
433 free_qe (qe);
434 return;
338 } 435 }
339 436
340 rd_tmp = &name[name_len]; 437 rd_tmp = &name[name_len];
341 { 438 {
342 struct GNUNET_GNSRECORD_Data rd[rd_count]; 439 struct GNUNET_GNSRECORD_Data rd[rd_count];
343 440
344 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize(rd_len, rd_tmp, rd_count, rd)) 441 GNUNET_assert (GNUNET_OK ==
345 { 442 GNUNET_GNSRECORD_records_deserialize (rd_len,
346 GNUNET_break (0); 443 rd_tmp,
347 return GNUNET_SYSERR; 444 rd_count,
348 } 445 rd));
349 if (0 == name_len) 446 if (0 == name_len)
350 name = NULL; 447 name = NULL;
351 if (NULL != qe->proc) 448 if (NULL != qe->proc)
@@ -355,7 +452,7 @@ handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
355 rd_count, 452 rd_count,
356 (rd_count > 0) ? rd : NULL); 453 (rd_count > 0) ? rd : NULL);
357 } 454 }
358 return GNUNET_OK; 455 free_qe (qe);
359} 456}
360 457
361 458
@@ -363,15 +460,13 @@ handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
363 * Handle an incoming message of type 460 * Handle an incoming message of type
364 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT 461 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
365 * 462 *
366 * @param qe the respective entry in the message queue 463 * @param cls
367 * @param msg the message we received 464 * @param msg the message we received
368 * @param size the message size 465 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
369 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
370 */ 466 */
371static int 467static int
372handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe, 468check_record_result (void *cls,
373 const struct RecordResultMessage *msg, 469 const struct RecordResultMessage *msg)
374 size_t size)
375{ 470{
376 const char *name; 471 const char *name;
377 const char *rd_tmp; 472 const char *rd_tmp;
@@ -381,14 +476,15 @@ handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
381 size_t rd_len; 476 size_t rd_len;
382 unsigned int rd_count; 477 unsigned int rd_count;
383 478
384 LOG (GNUNET_ERROR_TYPE_DEBUG,
385 "Received `%s'\n",
386 "RECORD_RESULT");
387 rd_len = ntohs (msg->rd_len); 479 rd_len = ntohs (msg->rd_len);
388 rd_count = ntohs (msg->rd_count); 480 rd_count = ntohs (msg->rd_count);
389 msg_len = ntohs (msg->gns_header.header.size); 481 msg_len = ntohs (msg->gns_header.header.size);
390 name_len = ntohs (msg->name_len); 482 name_len = ntohs (msg->name_len);
391 GNUNET_break (0 == ntohs (msg->reserved)); 483 if (0 != ntohs (msg->reserved))
484 {
485 GNUNET_break (0);
486 return GNUNET_SYSERR;
487 }
392 exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len; 488 exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
393 if (msg_len != exp_msg_len) 489 if (msg_len != exp_msg_len)
394 { 490 {
@@ -406,19 +502,15 @@ handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
406 { 502 {
407 struct GNUNET_GNSRECORD_Data rd[rd_count]; 503 struct GNUNET_GNSRECORD_Data rd[rd_count];
408 504
409 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize(rd_len, rd_tmp, rd_count, rd)) 505 if (GNUNET_OK !=
506 GNUNET_GNSRECORD_records_deserialize(rd_len,
507 rd_tmp,
508 rd_count,
509 rd))
410 { 510 {
411 GNUNET_break (0); 511 GNUNET_break (0);
412 return GNUNET_SYSERR; 512 return GNUNET_SYSERR;
413 } 513 }
414 if (0 == name_len)
415 name = NULL;
416 if (NULL != qe->proc)
417 qe->proc (qe->proc_cls,
418 &msg->private_key,
419 name,
420 rd_count,
421 (rd_count > 0) ? rd : NULL);
422 } 514 }
423 return GNUNET_OK; 515 return GNUNET_OK;
424} 516}
@@ -426,424 +518,240 @@ handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
426 518
427/** 519/**
428 * Handle an incoming message of type 520 * Handle an incoming message of type
429 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE. 521 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
430 * 522 *
431 * @param qe the respective entry in the message queue 523 * @param cls
432 * @param msg the message we received 524 * @param msg the message we received
433 * @param size the message size
434 * @return #GNUNET_OK on success, #GNUNET_NO if we notified the client about
435 * the error, #GNUNET_SYSERR on error and we did NOT notify the client
436 */ 525 */
437static int 526static void
438handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 527handle_record_result (void *cls,
439 const struct ZoneToNameResponseMessage *msg, 528 const struct RecordResultMessage *msg)
440 size_t size)
441{ 529{
442 int res; 530 static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy;
531 struct GNUNET_NAMESTORE_Handle *h = cls;
532 struct GNUNET_NAMESTORE_QueueEntry *qe;
533 struct GNUNET_NAMESTORE_ZoneIterator *ze;
534 const char *name;
535 const char *rd_tmp;
443 size_t name_len; 536 size_t name_len;
444 size_t rd_ser_len; 537 size_t rd_len;
445 unsigned int rd_count; 538 unsigned int rd_count;
446 const char *name_tmp;
447 const char *rd_tmp;
448 539
449 LOG (GNUNET_ERROR_TYPE_DEBUG, 540 LOG (GNUNET_ERROR_TYPE_DEBUG,
450 "Received `%s'\n", 541 "Received RECORD_RESULT\n");
451 "ZONE_TO_NAME_RESPONSE"); 542 rd_len = ntohs (msg->rd_len);
452 res = ntohs (msg->res); 543 rd_count = ntohs (msg->rd_count);
453 switch (res) 544 name_len = ntohs (msg->name_len);
545 ze = find_zi (h,
546 ntohl (msg->gns_header.r_id));
547 qe = find_qe (h,
548 ntohl (msg->gns_header.r_id));
549 if ( (NULL == ze) && (NULL == qe) )
550 return; /* rid not found */
551 if ( (NULL != ze) && (NULL != qe) )
552 {
553 GNUNET_break (0); /* rid ambigous */
554 force_reconnect (h);
555 return;
556 }
557 if ( (0 == name_len) &&
558 (0 == (memcmp (&msg->private_key,
559 &priv_dummy,
560 sizeof (priv_dummy)))) )
454 { 561 {
455 case GNUNET_SYSERR:
456 LOG (GNUNET_ERROR_TYPE_DEBUG,
457 "An error occured during zone to name operation\n");
458 break;
459 case GNUNET_NO:
460 LOG (GNUNET_ERROR_TYPE_DEBUG,
461 "Namestore has no result for zone to name mapping \n");
462 if (NULL != qe->proc)
463 qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
464 return GNUNET_NO;
465 case GNUNET_YES:
466 LOG (GNUNET_ERROR_TYPE_DEBUG, 562 LOG (GNUNET_ERROR_TYPE_DEBUG,
467 "Namestore has result for zone to name mapping \n"); 563 "Zone iteration completed!\n");
468 name_len = ntohs (msg->name_len); 564 if (NULL == ze)
469 rd_count = ntohs (msg->rd_count);
470 rd_ser_len = ntohs (msg->rd_len);
471 name_tmp = (const char *) &msg[1];
472 if ( (name_len > 0) &&
473 ('\0' != name_tmp[name_len -1]) )
474 { 565 {
475 GNUNET_break (0); 566 GNUNET_break (0);
476 return GNUNET_SYSERR; 567 force_reconnect (h);
477 } 568 return;
478 rd_tmp = &name_tmp[name_len];
479 {
480 struct GNUNET_GNSRECORD_Data rd[rd_count];
481
482 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd))
483 {
484 GNUNET_break (0);
485 return GNUNET_SYSERR;
486 }
487 /* normal end, call continuation with result */
488 if (NULL != qe->proc)
489 qe->proc (qe->proc_cls,
490 &msg->zone,
491 name_tmp,
492 rd_count, rd);
493 /* return is important here: break would call continuation with error! */
494 return GNUNET_OK;
495 } 569 }
496 default: 570 if (NULL != ze->proc)
497 GNUNET_break (0); 571 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
498 return GNUNET_SYSERR; 572 free_ze (ze);
573 return;
499 } 574 }
500 /* error case, call continuation with error */
501 if (NULL != qe->proc)
502 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
503 return GNUNET_NO;
504}
505 575
506 576 name = (const char *) &msg[1];
507/** 577 rd_tmp = &name[name_len];
508 * Handle incoming messages for record operations
509 *
510 * @param qe the respective zone iteration handle
511 * @param msg the message we received
512 * @param type the message type in host byte order
513 * @param size the message size
514 * @return #GNUNET_OK on success, #GNUNET_NO if we notified the client about
515 * the error, #GNUNET_SYSERR on error and we did NOT notify the client
516 */
517static int
518manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
519 const struct GNUNET_MessageHeader *msg,
520 uint16_t type,
521 size_t size)
522{
523 /* handle different message type */
524 switch (type)
525 { 578 {
526 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE: 579 struct GNUNET_GNSRECORD_Data rd[rd_count];
527 if (size != sizeof (struct RecordStoreResponseMessage)) 580
528 { 581 GNUNET_assert (GNUNET_OK ==
529 GNUNET_break (0); 582 GNUNET_GNSRECORD_records_deserialize(rd_len,
530 return GNUNET_SYSERR; 583 rd_tmp,
531 } 584 rd_count,
532 return handle_record_store_response (qe, (const struct RecordStoreResponseMessage *) msg, size); 585 rd));
533 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE: 586 if (0 == name_len)
534 if (size < sizeof (struct ZoneToNameResponseMessage)) 587 name = NULL;
535 { 588 if (NULL != qe)
536 GNUNET_break (0);
537 return GNUNET_SYSERR;
538 }
539 return handle_zone_to_name_response (qe, (const struct ZoneToNameResponseMessage *) msg, size);
540 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
541 if (size < sizeof (struct RecordResultMessage))
542 { 589 {
543 GNUNET_break (0); 590 if (NULL != qe->proc)
544 return GNUNET_SYSERR; 591 qe->proc (qe->proc_cls,
592 &msg->private_key,
593 name,
594 rd_count,
595 (rd_count > 0) ? rd : NULL);
596 free_qe (qe);
597 return;
545 } 598 }
546 return handle_record_result (qe, (const struct RecordResultMessage *) msg, size); 599 if (NULL != ze)
547 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE:
548 if (size < sizeof (struct LabelLookupResponseMessage))
549 { 600 {
550 GNUNET_break (0); 601 if (NULL != ze->proc)
551 return GNUNET_SYSERR; 602 ze->proc (ze->proc_cls,
603 &msg->private_key,
604 name,
605 rd_count,
606 rd);
607 return;
552 } 608 }
553 return handle_lookup_result (qe, (const struct LabelLookupResponseMessage *) msg, size);
554 default:
555 GNUNET_break (0);
556 return GNUNET_SYSERR;
557 } 609 }
610 GNUNET_assert (0);
558} 611}
559 612
560 613
561/** 614/**
562 * Handle a response from NAMESTORE service for a zone iteration request 615 * Handle an incoming message of type
616 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
563 * 617 *
564 * @param ze the respective iterator for this operation 618 * @param qe the respective entry in the message queue
565 * @param msg the message containing the respoonse 619 * @param msg the message we received
566 * @param size the message size 620 * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
567 * @return #GNUNET_YES on success, @a ze should be kept, #GNUNET_NO on success if @a ze should
568 * not be kept any longer, #GNUNET_SYSERR on error (disconnect) and @a ze should be kept
569 */ 621 */
570static int 622static int
571handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze, 623check_zone_to_name_response (void *cls,
572 const struct RecordResultMessage *msg, 624 const struct ZoneToNameResponseMessage *msg)
573 size_t size)
574{ 625{
575 static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy;
576 size_t msg_len;
577 size_t exp_msg_len;
578 size_t name_len; 626 size_t name_len;
579 size_t rd_len; 627 size_t rd_ser_len;
580 unsigned rd_count; 628 unsigned int rd_count;
581 const char *name_tmp; 629 const char *name_tmp;
582 const char *rd_ser_tmp; 630 const char *rd_tmp;
631
632 if (GNUNET_OK != ntohs (msg->res))
633 return GNUNET_OK;
583 634
584 LOG (GNUNET_ERROR_TYPE_DEBUG,
585 "Received `%s'\n",
586 "ZONE_ITERATION_RESPONSE");
587 msg_len = ntohs (msg->gns_header.header.size);
588 rd_len = ntohs (msg->rd_len);
589 rd_count = ntohs (msg->rd_count);
590 name_len = ntohs (msg->name_len); 635 name_len = ntohs (msg->name_len);
591 exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len; 636 rd_count = ntohs (msg->rd_count);
592 if (msg_len != exp_msg_len) 637 rd_ser_len = ntohs (msg->rd_len);
593 {
594 GNUNET_break (0);
595 return GNUNET_SYSERR;
596 }
597 if ( (0 == name_len) &&
598 (0 == (memcmp (&msg->private_key,
599 &priv_dummy,
600 sizeof (priv_dummy)))) )
601 {
602 LOG (GNUNET_ERROR_TYPE_DEBUG,
603 "Zone iteration completed!\n");
604 if (NULL != ze->proc)
605 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
606 return GNUNET_NO;
607 }
608 name_tmp = (const char *) &msg[1]; 638 name_tmp = (const char *) &msg[1];
609 if ((name_tmp[name_len -1] != '\0') || (name_len > MAX_NAME_LEN)) 639 if ( (name_len > 0) &&
640 ('\0' != name_tmp[name_len -1]) )
610 { 641 {
611 GNUNET_break (0); 642 GNUNET_break (0);
612 return GNUNET_SYSERR; 643 return GNUNET_SYSERR;
613 } 644 }
614 rd_ser_tmp = (const char *) &name_tmp[name_len]; 645 rd_tmp = &name_tmp[name_len];
615 { 646 {
616 struct GNUNET_GNSRECORD_Data rd[rd_count]; 647 struct GNUNET_GNSRECORD_Data rd[rd_count];
617 648
618 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (rd_len, 649 if (GNUNET_OK !=
619 rd_ser_tmp, 650 GNUNET_GNSRECORD_records_deserialize (rd_ser_len,
620 rd_count, 651 rd_tmp,
621 rd)) 652 rd_count,
653 rd))
622 { 654 {
623 GNUNET_break (0); 655 GNUNET_break (0);
624 return GNUNET_SYSERR; 656 return GNUNET_SYSERR;
625 } 657 }
626 if (NULL != ze->proc)
627 ze->proc (ze->proc_cls,
628 &msg->private_key,
629 name_tmp,
630 rd_count, rd);
631 return GNUNET_YES;
632 } 658 }
659 return GNUNET_OK;
633} 660}
634 661
635 662
636/** 663/**
637 * Handle incoming messages for zone iterations 664 * Handle an incoming message of type
665 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
638 * 666 *
639 * @param ze the respective zone iteration handle 667 * @param cls
640 * @param msg the message we received 668 * @param msg the message we received
641 * @param type the message type in HBO
642 * @param size the message size
643 * @return #GNUNET_YES on success, @a ze should be kept, #GNUNET_NO on success if @a ze should
644 * not be kept any longer, #GNUNET_SYSERR on error (disconnect) and @a ze should be kept
645 */
646static int
647manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
648 const struct GNUNET_MessageHeader *msg,
649 int type, size_t size)
650{
651 /* handle different message type */
652 switch (type)
653 {
654 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
655 if (size < sizeof (struct RecordResultMessage))
656 {
657 GNUNET_break (0);
658 return GNUNET_SYSERR;
659 }
660 return handle_zone_iteration_response (ze,
661 (const struct RecordResultMessage *) msg,
662 size);
663 default:
664 GNUNET_break (0);
665 return GNUNET_SYSERR;
666 }
667}
668
669
670/**
671 * Type of a function to call when we receive a message
672 * from the service.
673 *
674 * @param cls the `struct GNUNET_NAMESTORE_SchedulingHandle`
675 * @param msg message received, NULL on timeout or fatal error
676 */ 669 */
677static void 670static void
678process_namestore_message (void *cls, 671handle_zone_to_name_response (void *cls,
679 const struct GNUNET_MessageHeader *msg) 672 const struct ZoneToNameResponseMessage *msg)
680{ 673{
681 struct GNUNET_NAMESTORE_Handle *h = cls; 674 struct GNUNET_NAMESTORE_Handle *h = cls;
682 const struct GNUNET_NAMESTORE_Header *gm;
683 struct GNUNET_NAMESTORE_QueueEntry *qe; 675 struct GNUNET_NAMESTORE_QueueEntry *qe;
684 struct GNUNET_NAMESTORE_ZoneIterator *ze; 676 int res;
685 uint16_t size; 677 size_t name_len;
686 uint16_t type; 678 size_t rd_ser_len;
687 uint32_t r_id; 679 unsigned int rd_count;
688 int ret; 680 const char *name_tmp;
689 681 const char *rd_tmp;
690 if (NULL == msg)
691 {
692 force_reconnect (h);
693 return;
694 }
695 size = ntohs (msg->size);
696 type = ntohs (msg->type);
697 if (size < sizeof (struct GNUNET_NAMESTORE_Header))
698 {
699 GNUNET_break_op (0);
700 GNUNET_CLIENT_receive (h->client,
701 &process_namestore_message, h,
702 GNUNET_TIME_UNIT_FOREVER_REL);
703 return;
704 }
705 gm = (const struct GNUNET_NAMESTORE_Header *) msg;
706 r_id = ntohl (gm->r_id);
707 682
708 LOG (GNUNET_ERROR_TYPE_DEBUG, 683 LOG (GNUNET_ERROR_TYPE_DEBUG,
709 "Received message type %u size %u op %u\n", 684 "Received ZONE_TO_NAME_RESPONSE\n");
710 (unsigned int) type, 685 qe = find_qe (h,
711 (unsigned int) size, 686 ntohl (msg->gns_header.r_id));
712 (unsigned int) r_id); 687 res = ntohs (msg->res);
713 688 switch (res)
714 /* Is it a record related operation ? */
715 for (qe = h->op_head; qe != NULL; qe = qe->next)
716 if (qe->op_id == r_id)
717 break;
718 if (NULL != qe)
719 {
720 ret = manage_record_operations (qe, msg, type, size);
721 if (GNUNET_SYSERR == ret)
722 {
723 /* protocol error, need to reconnect */
724 h->reconnect = GNUNET_YES;
725 }
726 else
727 {
728 /* client was notified about success or failure, clean up 'qe' */
729 GNUNET_CONTAINER_DLL_remove (h->op_head,
730 h->op_tail,
731 qe);
732 GNUNET_free (qe);
733 }
734 }
735 /* Is it a zone iteration operation? */
736 for (ze = h->z_head; ze != NULL; ze = ze->next)
737 if (ze->op_id == r_id)
738 break;
739 if (NULL != ze)
740 { 689 {
741 ret = manage_zone_operations (ze, msg, type, size); 690 case GNUNET_SYSERR:
742 if (GNUNET_NO == ret) 691 LOG (GNUNET_ERROR_TYPE_DEBUG,
743 { 692 "An error occured during zone to name operation\n");
744 /* end of iteration, clean up 'ze' */ 693 break;
745 GNUNET_CONTAINER_DLL_remove (h->z_head, 694 case GNUNET_NO:
746 h->z_tail, 695 LOG (GNUNET_ERROR_TYPE_DEBUG,
747 ze); 696 "Namestore has no result for zone to name mapping \n");
748 GNUNET_free (ze); 697 if (NULL != qe->proc)
749 } 698 qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
750 if (GNUNET_SYSERR == ret) 699 free_qe (qe);
700 return;
701 case GNUNET_YES:
702 LOG (GNUNET_ERROR_TYPE_DEBUG,
703 "Namestore has result for zone to name mapping \n");
704 name_len = ntohs (msg->name_len);
705 rd_count = ntohs (msg->rd_count);
706 rd_ser_len = ntohs (msg->rd_len);
707 name_tmp = (const char *) &msg[1];
708 rd_tmp = &name_tmp[name_len];
751 { 709 {
752 /* protocol error, need to reconnect */ 710 struct GNUNET_GNSRECORD_Data rd[rd_count];
753 h->reconnect = GNUNET_YES; 711
712 GNUNET_assert (GNUNET_OK ==
713 GNUNET_GNSRECORD_records_deserialize (rd_ser_len,
714 rd_tmp,
715 rd_count,
716 rd));
717 /* normal end, call continuation with result */
718 if (NULL != qe->proc)
719 qe->proc (qe->proc_cls,
720 &msg->zone,
721 name_tmp,
722 rd_count, rd);
723 /* return is important here: break would call continuation with error! */
724 free_qe (qe);
725 return;
754 } 726 }
755 } 727 default:
756 if (GNUNET_YES == h->reconnect) 728 GNUNET_break (0);
757 {
758 force_reconnect (h); 729 force_reconnect (h);
759 return; 730 return;
760 } 731 }
761 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h, 732 /* error case, call continuation with error */
762 GNUNET_TIME_UNIT_FOREVER_REL); 733 if (NULL != qe->proc)
734 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
735 free_qe (qe);
763} 736}
764 737
765 738
766/**
767 * Transmit messages from the message queue to the service
768 * (if there are any, and if we are not already trying).
769 *
770 * @param h handle to use
771 */
772static void
773do_transmit (struct GNUNET_NAMESTORE_Handle *h);
774
775 739
776/** 740/**
777 * We can now transmit a message to NAMESTORE. Do it. 741 * Generic error handler, called with the appropriate error code and
742 * the same closure specified at the creation of the message queue.
743 * Not every message queue implementation supports an error handler.
778 * 744 *
779 * @param cls the `struct GNUNET_NAMESTORE_Handle` 745 * @param cls closure with the `struct GNUNET_NAMESTORE_Handle *`
780 * @param size number of bytes we can transmit 746 * @param error error code
781 * @param buf where to copy the messages
782 * @return number of bytes copied into @a buf
783 */ 747 */
784static size_t 748static void
785transmit_message_to_namestore (void *cls, 749mq_error_handler (void *cls,
786 size_t size, 750 enum GNUNET_MQ_Error error)
787 void *buf)
788{ 751{
789 struct GNUNET_NAMESTORE_Handle *h = cls; 752 struct GNUNET_NAMESTORE_Handle *h = cls;
790 struct PendingMessage *p;
791 size_t ret;
792 char *cbuf;
793 753
794 h->th = NULL; 754 force_reconnect (h);
795 if ((0 == size) || (NULL == buf))
796 {
797 force_reconnect (h);
798 return 0;
799 }
800 ret = 0;
801 cbuf = buf;
802 while ( (NULL != (p = h->pending_head)) &&
803 (p->size <= size) )
804 {
805 memcpy (&cbuf[ret], &p[1], p->size);
806 ret += p->size;
807 size -= p->size;
808 GNUNET_CONTAINER_DLL_remove (h->pending_head,
809 h->pending_tail,
810 p);
811 if (GNUNET_NO == h->is_receiving)
812 {
813 h->is_receiving = GNUNET_YES;
814 GNUNET_CLIENT_receive (h->client,
815 &process_namestore_message, h,
816 GNUNET_TIME_UNIT_FOREVER_REL);
817 }
818 GNUNET_free (p);
819 }
820 do_transmit (h);
821 return ret;
822}
823
824
825/**
826 * Transmit messages from the message queue to the service
827 * (if there are any, and if we are not already trying).
828 *
829 * @param h handle to use
830 */
831static void
832do_transmit (struct GNUNET_NAMESTORE_Handle *h)
833{
834 struct PendingMessage *p;
835
836 if (NULL != h->th)
837 return; /* transmission request already pending */
838 if (NULL == (p = h->pending_head))
839 return; /* transmission queue empty */
840 if (NULL == h->client)
841 return; /* currently reconnecting */
842 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, p->size,
843 GNUNET_TIME_UNIT_FOREVER_REL,
844 GNUNET_NO, &transmit_message_to_namestore,
845 h);
846 GNUNET_break (NULL != h->th);
847} 755}
848 756
849 757
@@ -855,10 +763,49 @@ do_transmit (struct GNUNET_NAMESTORE_Handle *h)
855static void 763static void
856reconnect (struct GNUNET_NAMESTORE_Handle *h) 764reconnect (struct GNUNET_NAMESTORE_Handle *h)
857{ 765{
858 GNUNET_assert (NULL == h->client); 766 GNUNET_MQ_hd_fixed_size (record_store_response,
859 h->client = GNUNET_CLIENT_connect ("namestore", h->cfg); 767 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE,
860 GNUNET_assert (NULL != h->client); 768 struct RecordStoreResponseMessage);
861 do_transmit (h); 769 GNUNET_MQ_hd_var_size (zone_to_name_response,
770 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE,
771 struct ZoneToNameResponseMessage);
772 GNUNET_MQ_hd_var_size (record_result,
773 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT,
774 struct RecordResultMessage);
775 GNUNET_MQ_hd_var_size (lookup_result,
776 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
777 struct LabelLookupResponseMessage);
778 struct GNUNET_MQ_MessageHandler handlers[] = {
779 make_record_store_response_handler (h),
780 make_zone_to_name_response_handler (h),
781 make_record_result_handler (h),
782 make_lookup_result_handler (h),
783 GNUNET_MQ_handler_end ()
784 };
785 struct GNUNET_NAMESTORE_ZoneIterator *it;
786 struct GNUNET_NAMESTORE_QueueEntry *qe;
787
788 GNUNET_assert (NULL == h->mq);
789 h->mq = GNUNET_CLIENT_connecT (h->cfg,
790 "namestore",
791 handlers,
792 &mq_error_handler,
793 h);
794 if (NULL == h->mq)
795 return;
796 /* re-transmit pending requests that waited for a reconnect... */
797 for (it = h->z_head; NULL != it; it = it->next)
798 {
799 GNUNET_MQ_send (h->mq,
800 it->env);
801 it->env = NULL;
802 }
803 for (qe = h->op_head; NULL != qe; qe = qe->next)
804 {
805 GNUNET_MQ_send (h->mq,
806 qe->env);
807 qe->env = NULL;
808 }
862} 809}
863 810
864 811
@@ -885,17 +832,30 @@ reconnect_task (void *cls)
885static void 832static void
886force_reconnect (struct GNUNET_NAMESTORE_Handle *h) 833force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
887{ 834{
888 if (NULL != h->th) 835 struct GNUNET_NAMESTORE_ZoneIterator *ze;
836 struct GNUNET_NAMESTORE_QueueEntry *qe;
837
838 GNUNET_MQ_destroy (h->mq);
839 h->mq = NULL;
840 for (ze = h->z_head; NULL != ze; ze = ze->next)
889 { 841 {
890 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 842 /* FIXME: This does not allow clients to distinguish
891 h->th = NULL; 843 iteration error from successful termination! */
844 if (NULL != ze->proc)
845 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
846 free_ze (ze);
892 } 847 }
893 h->reconnect = GNUNET_NO; 848 for (qe = h->op_head; NULL != qe; qe = qe->next)
894 GNUNET_CLIENT_disconnect (h->client); 849 {
850 /* FIXME: This does not allow clients to distinguish
851 iteration error from successful termination! */
852 if (NULL != qe->proc)
853 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
854 free_qe (qe);
855 }
856
895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
896 "Reconnecting to namestore\n"); 858 "Reconnecting to namestore\n");
897 h->is_receiving = GNUNET_NO;
898 h->client = NULL;
899 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); 859 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
900 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, 860 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
901 &reconnect_task, 861 &reconnect_task,
@@ -929,8 +889,12 @@ GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
929 889
930 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle); 890 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
931 h->cfg = cfg; 891 h->cfg = cfg;
932 h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h); 892 reconnect (h);
933 h->last_op_id_used = 0; 893 if (NULL == h->mq)
894 {
895 GNUNET_free (h);
896 return NULL;
897 }
934 return h; 898 return h;
935} 899}
936 900
@@ -944,38 +908,31 @@ GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
944void 908void
945GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h) 909GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
946{ 910{
947 struct PendingMessage *p;
948 struct GNUNET_NAMESTORE_QueueEntry *q; 911 struct GNUNET_NAMESTORE_QueueEntry *q;
949 struct GNUNET_NAMESTORE_ZoneIterator *z; 912 struct GNUNET_NAMESTORE_ZoneIterator *z;
950 913
951 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 914 LOG (GNUNET_ERROR_TYPE_DEBUG,
952 GNUNET_assert (NULL != h); 915 "Cleaning up\n");
953 if (NULL != h->th)
954 {
955 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
956 h->th = NULL;
957 }
958 while (NULL != (p = h->pending_head))
959 {
960 GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
961 GNUNET_free (p);
962 }
963 GNUNET_break (NULL == h->op_head); 916 GNUNET_break (NULL == h->op_head);
964 while (NULL != (q = h->op_head)) 917 while (NULL != (q = h->op_head))
965 { 918 {
966 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q); 919 GNUNET_CONTAINER_DLL_remove (h->op_head,
920 h->op_tail,
921 q);
967 GNUNET_free (q); 922 GNUNET_free (q);
968 } 923 }
969 GNUNET_break (NULL == h->z_head); 924 GNUNET_break (NULL == h->z_head);
970 while (NULL != (z = h->z_head)) 925 while (NULL != (z = h->z_head))
971 { 926 {
972 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z); 927 GNUNET_CONTAINER_DLL_remove (h->z_head,
928 h->z_tail,
929 z);
973 GNUNET_free (z); 930 GNUNET_free (z);
974 } 931 }
975 if (NULL != h->client) 932 if (NULL != h->mq)
976 { 933 {
977 GNUNET_CLIENT_disconnect (h->client); 934 GNUNET_MQ_destroy (h->mq);
978 h->client = NULL; 935 h->mq = NULL;
979 } 936 }
980 if (NULL != h->reconnect_task) 937 if (NULL != h->reconnect_task)
981 { 938 {
@@ -994,7 +951,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
994 * @param h handle to the namestore 951 * @param h handle to the namestore
995 * @param pkey private key of the zone 952 * @param pkey private key of the zone
996 * @param label name that is being mapped (at most 255 characters long) 953 * @param label name that is being mapped (at most 255 characters long)
997 * @param rd_count number of records in the 'rd' array 954 * @param rd_count number of records in the @a rd array
998 * @param rd array of records with data to store 955 * @param rd array of records with data to store
999 * @param cont continuation to call when done 956 * @param cont continuation to call when done
1000 * @param cont_cls closure for @a cont 957 * @param cont_cls closure for @a cont
@@ -1010,18 +967,14 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1010 void *cont_cls) 967 void *cont_cls)
1011{ 968{
1012 struct GNUNET_NAMESTORE_QueueEntry *qe; 969 struct GNUNET_NAMESTORE_QueueEntry *qe;
1013 struct PendingMessage *pe; 970 struct GNUNET_MQ_Envelope *env;
1014 char *name_tmp; 971 char *name_tmp;
1015 char *rd_ser; 972 char *rd_ser;
1016 size_t rd_ser_len; 973 size_t rd_ser_len;
1017 size_t msg_size;
1018 size_t name_len; 974 size_t name_len;
1019 uint32_t rid; 975 uint32_t rid;
1020 struct RecordStoreMessage *msg; 976 struct RecordStoreMessage *msg;
1021 977
1022 GNUNET_assert (NULL != h);
1023 GNUNET_assert (NULL != pkey);
1024 GNUNET_assert (NULL != label);
1025 name_len = strlen (label) + 1; 978 name_len = strlen (label) + 1;
1026 if (name_len > MAX_NAME_LEN) 979 if (name_len > MAX_NAME_LEN)
1027 { 980 {
@@ -1030,20 +983,20 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1030 } 983 }
1031 rid = get_op_id (h); 984 rid = get_op_id (h);
1032 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry); 985 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1033 qe->nsh = h; 986 qe->h = h;
1034 qe->cont = cont; 987 qe->cont = cont;
1035 qe->cont_cls = cont_cls; 988 qe->cont_cls = cont_cls;
1036 qe->op_id = rid; 989 qe->op_id = rid;
1037 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 990 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
991 h->op_tail,
992 qe);
1038 993
1039 /* setup msg */ 994 /* setup msg */
1040 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 995 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count,
1041 msg_size = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len; 996 rd);
1042 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 997 env = GNUNET_MQ_msg_extra (msg,
1043 pe->size = msg_size; 998 name_len + rd_ser_len,
1044 msg = (struct RecordStoreMessage *) &pe[1]; 999 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1045 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1046 msg->gns_header.header.size = htons (msg_size);
1047 msg->gns_header.r_id = htonl (rid); 1000 msg->gns_header.r_id = htonl (rid);
1048 msg->name_len = htons (name_len); 1001 msg->name_len = htons (name_len);
1049 msg->rd_count = htons (rd_count); 1002 msg->rd_count = htons (rd_count);
@@ -1052,21 +1005,29 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1052 msg->private_key = *pkey; 1005 msg->private_key = *pkey;
1053 1006
1054 name_tmp = (char *) &msg[1]; 1007 name_tmp = (char *) &msg[1];
1055 memcpy (name_tmp, label, name_len); 1008 memcpy (name_tmp,
1009 label,
1010 name_len);
1056 rd_ser = &name_tmp[name_len]; 1011 rd_ser = &name_tmp[name_len];
1057 GNUNET_break (rd_ser_len == 1012 GNUNET_assert (rd_ser_len ==
1058 GNUNET_GNSRECORD_records_serialize (rd_count, rd, 1013 GNUNET_GNSRECORD_records_serialize (rd_count,
1059 rd_ser_len, 1014 rd,
1060 rd_ser)); 1015 rd_ser_len,
1016 rd_ser));
1061 LOG (GNUNET_ERROR_TYPE_DEBUG, 1017 LOG (GNUNET_ERROR_TYPE_DEBUG,
1062 "Sending `%s' message for name `%s' with size %u and %u records\n", 1018 "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n",
1063 "NAMESTORE_RECORD_STORE", label, msg_size, 1019 label,
1064 rd_count); 1020 rd_count);
1065 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1021
1066 do_transmit (h); 1022 if (NULL == h->mq)
1023 qe->env = env;
1024 else
1025 GNUNET_MQ_send (h->mq,
1026 env);
1067 return qe; 1027 return qe;
1068} 1028}
1069 1029
1030
1070/** 1031/**
1071 * Set the desired nick name for a zone 1032 * Set the desired nick name for a zone
1072 * 1033 *
@@ -1074,7 +1035,7 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1074 * @param pkey private key of the zone 1035 * @param pkey private key of the zone
1075 * @param nick the nick name to set 1036 * @param nick the nick name to set
1076 * @param cont continuation to call when done 1037 * @param cont continuation to call when done
1077 * @param cont_cls closure for 'cont' 1038 * @param cont_cls closure for @a cont
1078 * @return handle to abort the request 1039 * @return handle to abort the request
1079 */ 1040 */
1080struct GNUNET_NAMESTORE_QueueEntry * 1041struct GNUNET_NAMESTORE_QueueEntry *
@@ -1086,13 +1047,21 @@ GNUNET_NAMESTORE_set_nick (struct GNUNET_NAMESTORE_Handle *h,
1086{ 1047{
1087 struct GNUNET_GNSRECORD_Data rd; 1048 struct GNUNET_GNSRECORD_Data rd;
1088 1049
1050 if (NULL == h->mq)
1051 return NULL;
1089 memset (&rd, 0, sizeof (rd)); 1052 memset (&rd, 0, sizeof (rd));
1090 rd.data = nick; 1053 rd.data = nick;
1091 rd.data_size = strlen (nick) +1; 1054 rd.data_size = strlen (nick) +1;
1092 rd.record_type = GNUNET_GNSRECORD_TYPE_NICK; 1055 rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
1093 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; 1056 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1094 rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE; 1057 rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1095 return GNUNET_NAMESTORE_records_store(h, pkey, GNUNET_GNS_MASTERZONE_STR, 1, &rd, cont, cont_cls); 1058 return GNUNET_NAMESTORE_records_store (h,
1059 pkey,
1060 GNUNET_GNS_MASTERZONE_STR,
1061 1,
1062 &rd,
1063 cont,
1064 cont_cls);
1096} 1065}
1097 1066
1098 1067
@@ -1114,39 +1083,39 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h,
1114 void *rm_cls) 1083 void *rm_cls)
1115{ 1084{
1116 struct GNUNET_NAMESTORE_QueueEntry *qe; 1085 struct GNUNET_NAMESTORE_QueueEntry *qe;
1117 struct PendingMessage *pe; 1086 struct GNUNET_MQ_Envelope *env;
1118 struct LabelLookupMessage * msg; 1087 struct LabelLookupMessage *msg;
1119 size_t msg_size;
1120 size_t label_len; 1088 size_t label_len;
1121 1089
1122 GNUNET_assert (NULL != h);
1123 GNUNET_assert (NULL != pkey);
1124 GNUNET_assert (NULL != label);
1125
1126 if (1 == (label_len = strlen (label) + 1)) 1090 if (1 == (label_len = strlen (label) + 1))
1091 {
1092 GNUNET_break (0);
1127 return NULL; 1093 return NULL;
1094 }
1128 1095
1129 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry); 1096 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1130 qe->nsh = h; 1097 qe->h = h;
1131 qe->proc = rm; 1098 qe->proc = rm;
1132 qe->proc_cls = rm_cls; 1099 qe->proc_cls = rm_cls;
1133 qe->op_id = get_op_id(h); 1100 qe->op_id = get_op_id(h);
1134 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 1101 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1135 1102 h->op_tail,
1136 msg_size = sizeof (struct LabelLookupMessage) + label_len; 1103 qe);
1137 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 1104
1138 pe->size = msg_size; 1105 env = GNUNET_MQ_msg_extra (msg,
1139 msg = (struct LabelLookupMessage *) &pe[1]; 1106 label_len,
1140 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP); 1107 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
1141 msg->gns_header.header.size = htons (msg_size);
1142 msg->gns_header.r_id = htonl (qe->op_id); 1108 msg->gns_header.r_id = htonl (qe->op_id);
1143 msg->zone = *pkey; 1109 msg->zone = *pkey;
1144 msg->label_len = htonl(label_len); 1110 msg->label_len = htonl (label_len);
1145 memcpy (&msg[1], label, label_len); 1111 memcpy (&msg[1],
1146 1112 label,
1147 /* transmit message */ 1113 label_len);
1148 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1114 if (NULL == h->mq)
1149 do_transmit (h); 1115 qe->env = env;
1116 else
1117 GNUNET_MQ_send (h->mq,
1118 env);
1150 return qe; 1119 return qe;
1151} 1120}
1152 1121
@@ -1168,38 +1137,34 @@ struct GNUNET_NAMESTORE_QueueEntry *
1168GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, 1137GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1169 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 1138 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1170 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, 1139 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
1171 GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls) 1140 GNUNET_NAMESTORE_RecordMonitor proc,
1141 void *proc_cls)
1172{ 1142{
1173 struct GNUNET_NAMESTORE_QueueEntry *qe; 1143 struct GNUNET_NAMESTORE_QueueEntry *qe;
1174 struct PendingMessage *pe; 1144 struct GNUNET_MQ_Envelope *env;
1175 struct ZoneToNameMessage * msg; 1145 struct ZoneToNameMessage *msg;
1176 size_t msg_size;
1177 uint32_t rid; 1146 uint32_t rid;
1178 1147
1179 GNUNET_assert (NULL != h);
1180 GNUNET_assert (NULL != zone);
1181 GNUNET_assert (NULL != value_zone);
1182 rid = get_op_id(h); 1148 rid = get_op_id(h);
1183 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry); 1149 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1184 qe->nsh = h; 1150 qe->h = h;
1185 qe->proc = proc; 1151 qe->proc = proc;
1186 qe->proc_cls = proc_cls; 1152 qe->proc_cls = proc_cls;
1187 qe->op_id = rid; 1153 qe->op_id = rid;
1188 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 1154 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1189 1155 h->op_tail,
1190 msg_size = sizeof (struct ZoneToNameMessage); 1156 qe);
1191 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 1157
1192 pe->size = msg_size; 1158 env = GNUNET_MQ_msg (msg,
1193 msg = (struct ZoneToNameMessage *) &pe[1]; 1159 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1194 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1195 msg->gns_header.header.size = htons (msg_size);
1196 msg->gns_header.r_id = htonl (rid); 1160 msg->gns_header.r_id = htonl (rid);
1197 msg->zone = *zone; 1161 msg->zone = *zone;
1198 msg->value_zone = *value_zone; 1162 msg->value_zone = *value_zone;
1199 1163 if (NULL == h->mq)
1200 /* transmit message */ 1164 qe->env = env;
1201 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1165 else
1202 do_transmit (h); 1166 GNUNET_MQ_send (h->mq,
1167 env);
1203 return qe; 1168 return qe;
1204} 1169}
1205 1170
@@ -1227,13 +1192,11 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1227 void *proc_cls) 1192 void *proc_cls)
1228{ 1193{
1229 struct GNUNET_NAMESTORE_ZoneIterator *it; 1194 struct GNUNET_NAMESTORE_ZoneIterator *it;
1230 struct PendingMessage *pe; 1195 struct GNUNET_MQ_Envelope *env;
1231 struct ZoneIterationStartMessage * msg; 1196 struct ZoneIterationStartMessage *msg;
1232 size_t msg_size;
1233 uint32_t rid; 1197 uint32_t rid;
1234 1198
1235 GNUNET_assert (NULL != h); 1199 rid = get_op_id (h);
1236 rid = get_op_id(h);
1237 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator); 1200 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1238 it->h = h; 1201 it->h = h;
1239 it->proc = proc; 1202 it->proc = proc;
@@ -1241,19 +1204,19 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1241 it->op_id = rid; 1204 it->op_id = rid;
1242 if (NULL != zone) 1205 if (NULL != zone)
1243 it->zone = *zone; 1206 it->zone = *zone;
1244 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it); 1207 GNUNET_CONTAINER_DLL_insert_tail (h->z_head,
1245 1208 h->z_tail,
1246 msg_size = sizeof (struct ZoneIterationStartMessage); 1209 it);
1247 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 1210 env = GNUNET_MQ_msg (msg,
1248 pe->size = msg_size; 1211 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1249 msg = (struct ZoneIterationStartMessage *) &pe[1];
1250 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1251 msg->gns_header.header.size = htons (msg_size);
1252 msg->gns_header.r_id = htonl (rid); 1212 msg->gns_header.r_id = htonl (rid);
1253 if (NULL != zone) 1213 if (NULL != zone)
1254 msg->zone = *zone; 1214 msg->zone = *zone;
1255 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1215 if (NULL == h->mq)
1256 do_transmit (h); 1216 it->env = env;
1217 else
1218 GNUNET_MQ_send (h->mq,
1219 env);
1257 return it; 1220 return it;
1258} 1221}
1259 1222
@@ -1267,25 +1230,17 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1267void 1230void
1268GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it) 1231GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1269{ 1232{
1270 struct GNUNET_NAMESTORE_Handle *h; 1233 struct GNUNET_NAMESTORE_Handle *h = it->h;
1271 struct ZoneIterationNextMessage * msg; 1234 struct ZoneIterationNextMessage *msg;
1272 struct PendingMessage *pe; 1235 struct GNUNET_MQ_Envelope *env;
1273 size_t msg_size; 1236
1274
1275 GNUNET_assert (NULL != it);
1276 h = it->h;
1277 msg_size = sizeof (struct ZoneIterationNextMessage);
1278 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1279 pe->size = msg_size;
1280 msg = (struct ZoneIterationNextMessage *) &pe[1];
1281 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1282 msg->gns_header.header.size = htons (msg_size);
1283 msg->gns_header.r_id = htonl (it->op_id);
1284 LOG (GNUNET_ERROR_TYPE_DEBUG, 1237 LOG (GNUNET_ERROR_TYPE_DEBUG,
1285 "Sending `%s' message\n", 1238 "Sending ZONE_ITERATION_NEXT message\n");
1286 "ZONE_ITERATION_NEXT"); 1239 env = GNUNET_MQ_msg (msg,
1287 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1240 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1288 do_transmit (h); 1241 msg->gns_header.r_id = htonl (it->op_id);
1242 GNUNET_MQ_send (h->mq,
1243 env);
1289} 1244}
1290 1245
1291 1246
@@ -1297,29 +1252,18 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1297void 1252void
1298GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it) 1253GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1299{ 1254{
1300 struct GNUNET_NAMESTORE_Handle *h; 1255 struct GNUNET_NAMESTORE_Handle *h = it->h;
1301 struct PendingMessage *pe; 1256 struct GNUNET_MQ_Envelope *env;
1302 size_t msg_size; 1257 struct ZoneIterationStopMessage *msg;
1303 struct ZoneIterationStopMessage * msg;
1304 1258
1305 GNUNET_assert (NULL != it);
1306 h = it->h;
1307 GNUNET_CONTAINER_DLL_remove (h->z_head,
1308 h->z_tail,
1309 it);
1310 msg_size = sizeof (struct ZoneIterationStopMessage);
1311 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1312 pe->size = msg_size;
1313 msg = (struct ZoneIterationStopMessage *) &pe[1];
1314 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1315 msg->gns_header.header.size = htons (msg_size);
1316 msg->gns_header.r_id = htonl (it->op_id);
1317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1318 "Sending `%s' message\n", 1260 "Sending ZONE_ITERATION_STOP message\n");
1319 "ZONE_ITERATION_STOP"); 1261 env = GNUNET_MQ_msg (msg,
1320 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1262 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1321 do_transmit (h); 1263 msg->gns_header.r_id = htonl (it->op_id);
1322 GNUNET_free (it); 1264 GNUNET_MQ_send (h->mq,
1265 env);
1266 free_ze (it);
1323} 1267}
1324 1268
1325 1269
@@ -1332,11 +1276,7 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1332void 1276void
1333GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe) 1277GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1334{ 1278{
1335 struct GNUNET_NAMESTORE_Handle *h = qe->nsh; 1279 free_qe (qe);
1336
1337 GNUNET_assert (NULL != qe);
1338 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
1339 GNUNET_free(qe);
1340} 1280}
1341 1281
1342 1282