aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/peerstore_api.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-05-17 16:57:49 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-05-17 16:57:49 +0000
commit7eb684ec9f93d52ebae09729fcf01c16580b5cb9 (patch)
tree72a44f01de2dc157f47a0a70ccb90d36154ddcbf /src/peerstore/peerstore_api.c
parent83c058a5ea11b6d7aa05cb71963c6063cb373603 (diff)
downloadgnunet-7eb684ec9f93d52ebae09729fcf01c16580b5cb9.tar.gz
gnunet-7eb684ec9f93d52ebae09729fcf01c16580b5cb9.zip
peestore: towards iterate functionality
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r--src/peerstore/peerstore_api.c222
1 files changed, 217 insertions, 5 deletions
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index edf506f10..81d6c78a6 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -65,6 +65,16 @@ struct GNUNET_PEERSTORE_Handle
65 */ 65 */
66 struct GNUNET_PEERSTORE_StoreContext *store_tail; 66 struct GNUNET_PEERSTORE_StoreContext *store_tail;
67 67
68 /**
69 * Head of active ITERATE requests.
70 */
71 struct GNUNET_PEERSTORE_IterateContext *iterate_head;
72
73 /**
74 * Tail of active ITERATE requests.
75 */
76 struct GNUNET_PEERSTORE_IterateContext *iterate_tail;
77
68}; 78};
69 79
70/** 80/**
@@ -110,6 +120,49 @@ struct GNUNET_PEERSTORE_StoreContext
110 120
111}; 121};
112 122
123/**
124 * Context for a iterate request
125 */
126struct GNUNET_PEERSTORE_IterateContext
127{
128 /**
129 * Kept in a DLL.
130 */
131 struct GNUNET_PEERSTORE_IterateContext *next;
132
133 /**
134 * Kept in a DLL.
135 */
136 struct GNUNET_PEERSTORE_IterateContext *prev;
137
138 /**
139 * Handle to the PEERSTORE service.
140 */
141 struct GNUNET_PEERSTORE_Handle *h;
142
143 /**
144 * MQ Envelope with iterate request message
145 */
146 struct GNUNET_MQ_Envelope *ev;
147
148 /**
149 * Callback with each matching record
150 */
151 GNUNET_PEERSTORE_Processor callback;
152
153 /**
154 * Closure for 'callback'
155 */
156 void *callback_cls;
157
158 /**
159 * #GNUNET_YES / #GNUNET_NO
160 * if sent, cannot be canceled
161 */
162 int request_sent;
163
164};
165
113/******************************************************************************/ 166/******************************************************************************/
114/******************* DECLARATIONS *********************/ 167/******************* DECLARATIONS *********************/
115/******************************************************************************/ 168/******************************************************************************/
@@ -122,6 +175,19 @@ struct GNUNET_PEERSTORE_StoreContext
122 */ 175 */
123void handle_store_result (void *cls, const struct GNUNET_MessageHeader *msg); 176void handle_store_result (void *cls, const struct GNUNET_MessageHeader *msg);
124 177
178/**
179 * When a response for iterate request is received
180 *
181 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
182 * @param msg message received, NULL on timeout or fatal error
183 */
184void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg);
185
186/**
187 * Close the existing connection to PEERSTORE and reconnect.
188 *
189 * @param h handle to the service
190 */
125static void 191static void
126reconnect (struct GNUNET_PEERSTORE_Handle *h); 192reconnect (struct GNUNET_PEERSTORE_Handle *h);
127 193
@@ -131,6 +197,8 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h);
131static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { 197static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
132 {&handle_store_result, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK, sizeof(struct GNUNET_MessageHeader)}, 198 {&handle_store_result, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK, sizeof(struct GNUNET_MessageHeader)},
133 {&handle_store_result, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_FAIL, sizeof(struct GNUNET_MessageHeader)}, 199 {&handle_store_result, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_FAIL, sizeof(struct GNUNET_MessageHeader)},
200 {&handle_iterate_result, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD, 0},
201 {&handle_iterate_result, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END, sizeof(struct GNUNET_MessageHeader)},
134 GNUNET_MQ_HANDLERS_END 202 GNUNET_MQ_HANDLERS_END
135}; 203};
136 204
@@ -154,12 +222,18 @@ static void
154cleanup_handle(struct GNUNET_PEERSTORE_Handle *h) 222cleanup_handle(struct GNUNET_PEERSTORE_Handle *h)
155{ 223{
156 struct GNUNET_PEERSTORE_StoreContext *sc; 224 struct GNUNET_PEERSTORE_StoreContext *sc;
225 struct GNUNET_PEERSTORE_IterateContext *ic;
157 226
158 while (NULL != (sc = h->store_head)) 227 while (NULL != (sc = h->store_head))
159 { 228 {
160 GNUNET_CONTAINER_DLL_remove(h->store_head, h->store_tail, sc); 229 GNUNET_CONTAINER_DLL_remove(h->store_head, h->store_tail, sc);
161 GNUNET_free(sc); 230 GNUNET_free(sc);
162 } 231 }
232 while (NULL != (ic = h->iterate_head))
233 {
234 GNUNET_CONTAINER_DLL_remove(h->iterate_head, h->iterate_tail, ic);
235 GNUNET_free(ic);
236 }
163} 237}
164 238
165/** 239/**
@@ -254,7 +328,7 @@ GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
254/** 328/**
255 * When a response for store request is received 329 * When a response for store request is received
256 * 330 *
257 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *' 331 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
258 * @param msg message received, NULL on timeout or fatal error 332 * @param msg message received, NULL on timeout or fatal error
259 */ 333 */
260void handle_store_result (void *cls, const struct GNUNET_MessageHeader *msg) 334void handle_store_result (void *cls, const struct GNUNET_MessageHeader *msg)
@@ -304,6 +378,7 @@ void store_request_sent (void *cls)
304 struct GNUNET_PEERSTORE_StoreContext *sc = cls; 378 struct GNUNET_PEERSTORE_StoreContext *sc = cls;
305 379
306 sc->request_sent = GNUNET_YES; 380 sc->request_sent = GNUNET_YES;
381 sc->ev = NULL;
307} 382}
308 383
309/** 384/**
@@ -319,7 +394,10 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
319 if(GNUNET_NO == sc->request_sent) 394 if(GNUNET_NO == sc->request_sent)
320 { 395 {
321 if(NULL != sc->ev) 396 if(NULL != sc->ev)
322 GNUNET_MQ_discard(sc->ev); 397 {
398 //GNUNET_MQ_discard(sc->ev); //FIXME: this should be GNUNET_MQ_send_cancel
399 sc->ev = NULL;
400 }
323 GNUNET_CONTAINER_DLL_remove(sc->h->store_head, sc->h->store_tail, sc); 401 GNUNET_CONTAINER_DLL_remove(sc->h->store_head, sc->h->store_tail, sc);
324 GNUNET_free(sc); 402 GNUNET_free(sc);
325 } 403 }
@@ -365,10 +443,8 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
365 key, 443 key,
366 value, 444 value,
367 size, 445 size,
368 expiry, 446 &expiry,
369 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); 447 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
370 GNUNET_MQ_send(h->mq, ev);
371 GNUNET_MQ_notify_sent(ev, &store_request_sent, ev);
372 sc = GNUNET_new(struct GNUNET_PEERSTORE_StoreContext); 448 sc = GNUNET_new(struct GNUNET_PEERSTORE_StoreContext);
373 sc->ev = ev; 449 sc->ev = ev;
374 sc->cont = cont; 450 sc->cont = cont;
@@ -376,8 +452,144 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
376 sc->h = h; 452 sc->h = h;
377 sc->request_sent = GNUNET_NO; 453 sc->request_sent = GNUNET_NO;
378 GNUNET_CONTAINER_DLL_insert(h->store_head, h->store_tail, sc); 454 GNUNET_CONTAINER_DLL_insert(h->store_head, h->store_tail, sc);
455 GNUNET_MQ_notify_sent(ev, &store_request_sent, ev);
456 GNUNET_MQ_send(h->mq, ev);
379 return sc; 457 return sc;
380 458
381} 459}
382 460
461/******************************************************************************/
462/******************* ITERATE FUNCTIONS *********************/
463/******************************************************************************/
464
465/**
466 * When a response for iterate request is received
467 *
468 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
469 * @param msg message received, NULL on timeout or fatal error
470 */
471void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
472{
473 struct GNUNET_PEERSTORE_Handle *h = cls;
474 struct GNUNET_PEERSTORE_IterateContext *ic;
475 GNUNET_PEERSTORE_Processor callback;
476 void *callback_cls;
477 uint16_t msg_type;
478 struct GNUNET_PEERSTORE_Record *record;
479
480 ic = h->iterate_head;
481 if(NULL == ic)
482 {
483 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Unexpected iteration response, this should not happen.\n");
484 reconnect(h);
485 return;
486 }
487 callback = ic->callback;
488 callback_cls = ic->callback_cls;
489 if(NULL == msg) /* Connection error */
490 {
491
492 if(NULL != callback)
493 callback(callback_cls, NULL,
494 _("Error communicating with `PEERSTORE' service."));
495 reconnect(h);
496 return;
497 }
498 msg_type = ntohs(msg->type);
499 if(GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END == msg_type)
500 {
501 if(NULL != callback)
502 callback(callback_cls, NULL, NULL);
503 GNUNET_CONTAINER_DLL_remove(ic->h->iterate_head, ic->h->iterate_tail, ic);
504 GNUNET_free(ic);
505 return;
506 }
507 if(NULL != callback)
508 {
509 record = PEERSTORE_parse_record_message(msg);
510 if(NULL == record)
511 callback(callback_cls, record, _("Received a malformed response from service."));
512 else
513 callback(callback_cls, record, NULL);
514 }
515
516}
517
518/**
519 * Callback after MQ envelope is sent
520 *
521 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *'
522 */
523void iterate_request_sent (void *cls)
524{
525 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
526
527 ic->request_sent = GNUNET_YES;
528 ic->ev = NULL;
529}
530
531/**
532 * Cancel an iterate request
533 * Please do not call after the iterate request is done
534 *
535 * @param ic Iterate request context as returned by GNUNET_PEERSTORE_iterate()
536 */
537void
538GNUNET_PEERSTORE_iterate_cancel (struct GNUNET_PEERSTORE_IterateContext *ic)
539{
540 if(GNUNET_NO == ic->request_sent)
541 {
542 if(NULL != ic->ev)
543 {
544 //GNUNET_MQ_discard(ic->ev); //FIXME: this should be GNUNET_MQ_send_cancel
545 ic->ev = NULL;
546 }
547 GNUNET_CONTAINER_DLL_remove(ic->h->iterate_head, ic->h->iterate_tail, ic);
548 GNUNET_free(ic);
549 }
550 else
551 ic->callback = NULL;
552}
553
554/**
555 * Iterate over records matching supplied key information
556 *
557 * @param h handle to the PEERSTORE service
558 * @param sub_system name of sub system
559 * @param peer Peer identity (can be NULL)
560 * @param key entry key string (can be NULL)
561 * @param timeout time after which the iterate request is canceled
562 * @param callback function called with each matching record, all NULL's on end
563 * @param callback_cls closure for @a callback
564 */
565struct GNUNET_PEERSTORE_IterateContext *
566GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
567 char *sub_system,
568 const struct GNUNET_PeerIdentity *peer,
569 const char *key,
570 struct GNUNET_TIME_Relative timeout, //FIXME: handle timeout
571 GNUNET_PEERSTORE_Processor callback, void *callback_cls)
572{
573 struct GNUNET_MQ_Envelope *ev;
574 struct GNUNET_PEERSTORE_IterateContext *ic;
575
576 ev = PEERSTORE_create_record_mq_envelope(sub_system,
577 peer,
578 key,
579 NULL,
580 0,
581 NULL,
582 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
583 ic = GNUNET_new(struct GNUNET_PEERSTORE_IterateContext);
584 ic->callback = callback;
585 ic->callback_cls = callback_cls;
586 ic->ev = ev;
587 ic->h = h;
588 ic->request_sent = GNUNET_NO;
589 GNUNET_CONTAINER_DLL_insert(h->iterate_head, h->iterate_tail, ic);
590 GNUNET_MQ_notify_sent(ev, &iterate_request_sent, ev);
591 GNUNET_MQ_send(h->mq, ev);
592 return ic;
593}
594
383/* end of peerstore_api.c */ 595/* end of peerstore_api.c */