aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/peerstore_api.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-05-07 17:13:47 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-05-07 17:13:47 +0000
commit603d264417198385513b09844ddf4557dcc44952 (patch)
treef6a38a068f8e0e88a31debb064dce21d3790ecc2 /src/peerstore/peerstore_api.c
parent87d9416ddb4d60f3ad057da83bc45f9f16cdcae2 (diff)
downloadgnunet-603d264417198385513b09844ddf4557dcc44952.tar.gz
gnunet-603d264417198385513b09844ddf4557dcc44952.zip
update to PEERSTORE api
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r--src/peerstore/peerstore_api.c270
1 files changed, 234 insertions, 36 deletions
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index a49d2a720..16cf70939 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -52,12 +52,12 @@ struct GNUNET_PEERSTORE_Handle
52 /** 52 /**
53 * Head of transmission queue. 53 * Head of transmission queue.
54 */ 54 */
55 struct GNUNET_PEERSTORE_AddContext *ac_head; 55 struct GNUNET_PEERSTORE_RequestContext *rc_head;
56 56
57 /** 57 /**
58 * Tail of transmission queue. 58 * Tail of transmission queue.
59 */ 59 */
60 struct GNUNET_PEERSTORE_AddContext *ac_tail; 60 struct GNUNET_PEERSTORE_RequestContext *rc_tail;
61 61
62 /** 62 /**
63 * Handle for the current transmission request, or NULL if none is pending. 63 * Handle for the current transmission request, or NULL if none is pending.
@@ -65,6 +65,16 @@ struct GNUNET_PEERSTORE_Handle
65 struct GNUNET_CLIENT_TransmitHandle *th; 65 struct GNUNET_CLIENT_TransmitHandle *th;
66 66
67 /** 67 /**
68 * Head of store requests DLL.
69 */
70 struct GNUNET_PEERSTORE_StoreContext *sc_head;
71
72 /**
73 * Tail of store requests DLL.
74 */
75 struct GNUNET_PEERSTORE_StoreContext *sc_tail;
76
77 /**
68 * ID for a reconnect task. 78 * ID for a reconnect task.
69 */ 79 */
70 GNUNET_SCHEDULER_TaskIdentifier r_task; 80 GNUNET_SCHEDULER_TaskIdentifier r_task;
@@ -80,17 +90,17 @@ struct GNUNET_PEERSTORE_Handle
80 * Entry in the transmission queue to PEERSTORE service. 90 * Entry in the transmission queue to PEERSTORE service.
81 * 91 *
82 */ 92 */
83struct GNUNET_PEERSTORE_AddContext 93struct GNUNET_PEERSTORE_RequestContext
84{ 94{
85 /** 95 /**
86 * This is a linked list. 96 * This is a linked list.
87 */ 97 */
88 struct GNUNET_PEERSTORE_AddContext *next; 98 struct GNUNET_PEERSTORE_RequestContext *next;
89 99
90 /** 100 /**
91 * This is a linked list. 101 * This is a linked list.
92 */ 102 */
93 struct GNUNET_PEERSTORE_AddContext *prev; 103 struct GNUNET_PEERSTORE_RequestContext *prev;
94 104
95 /** 105 /**
96 * Handle to the PEERSTORE service. 106 * Handle to the PEERSTORE service.
@@ -114,6 +124,50 @@ struct GNUNET_PEERSTORE_AddContext
114 124
115}; 125};
116 126
127/**
128 * Context for a store request
129 *
130 */
131struct GNUNET_PEERSTORE_StoreContext
132{
133 /**
134 * Kept in a DLL.
135 */
136 struct GNUNET_PEERSTORE_StoreContext *next;
137
138 /**
139 * Kept in a DLL.
140 */
141 struct GNUNET_PEERSTORE_StoreContext *prev;
142
143 /**
144 * Handle to the PEERSTORE service.
145 */
146 struct GNUNET_PEERSTORE_Handle *h;
147
148 /**
149 * Our entry in the transmission queue.
150 */
151 struct GNUNET_PEERSTORE_RequestContext *rc;
152
153 /**
154 * Function to call with store operation result
155 */
156 GNUNET_PEERSTORE_Continuation cont;
157
158 /**
159 * Closure for 'cont'.
160 */
161 void *cont_cls;
162
163 /**
164 * Set to GNUNET_YES if we are currently receiving replies from the
165 * service.
166 */
167 int request_transmitted;
168
169};
170
117/******************************************************************************/ 171/******************************************************************************/
118/*********************** DECLARATIONS *************************/ 172/*********************** DECLARATIONS *************************/
119/******************************************************************************/ 173/******************************************************************************/
@@ -213,7 +267,6 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
213 GNUNET_CLIENT_disconnect (h->client); 267 GNUNET_CLIENT_disconnect (h->client);
214 h->client = NULL; 268 h->client = NULL;
215 } 269 }
216 h->in_receive = GNUNET_NO;
217 h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg); 270 h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg);
218 if (NULL == h->client) 271 if (NULL == h->client)
219 { 272 {
@@ -238,25 +291,25 @@ static size_t
238do_transmit (void *cls, size_t size, void *buf) 291do_transmit (void *cls, size_t size, void *buf)
239{ 292{
240 struct GNUNET_PEERSTORE_Handle *h = cls; 293 struct GNUNET_PEERSTORE_Handle *h = cls;
241 struct GNUNET_PEERSTORE_AddContext *ac = h->ac_head; 294 struct GNUNET_PEERSTORE_RequestContext *rc = h->rc_head;
242 size_t ret; 295 size_t ret;
243 296
244 h->th = NULL; 297 h->th = NULL;
245 if (NULL == ac) 298 if (NULL == rc)
246 return 0; /* request was cancelled in the meantime */ 299 return 0; /* request was canceled in the meantime */
247 if (NULL == buf) 300 if (NULL == buf)
248 { 301 {
249 /* peerstore service died */ 302 /* peerstore service died */
250 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 303 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
251 "Failed to transmit message to `%s' service.\n", "PEERSTORE"); 304 "Failed to transmit message to `%s' service.\n", "PEERSTORE");
252 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); 305 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
253 reconnect (h); 306 reconnect (h);
254 if (NULL != ac->cont) 307 if (NULL != rc->cont)
255 ac->cont (ac->cont_cls, _("failed to transmit request (service down?)")); 308 rc->cont (rc->cont_cls, _("failed to transmit request (service down?)"));
256 GNUNET_free (ac); 309 GNUNET_free (rc);
257 return 0; 310 return 0;
258 } 311 }
259 ret = ac->size; 312 ret = rc->size;
260 if (size < ret) 313 if (size < ret)
261 { 314 {
262 /* change in head of queue (i.e. cancel + add), try again */ 315 /* change in head of queue (i.e. cancel + add), try again */
@@ -265,12 +318,12 @@ do_transmit (void *cls, size_t size, void *buf)
265 } 318 }
266 LOG (GNUNET_ERROR_TYPE_DEBUG, 319 LOG (GNUNET_ERROR_TYPE_DEBUG,
267 "Transmitting request of size %u to `%s' service.\n", ret, "PEERSTORE"); 320 "Transmitting request of size %u to `%s' service.\n", ret, "PEERSTORE");
268 memcpy (buf, &ac[1], ret); 321 memcpy (buf, &rc[1], ret);
269 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); 322 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
270 trigger_transmit (h); 323 trigger_transmit (h);
271 if (NULL != ac->cont) 324 if (NULL != rc->cont)
272 ac->cont (ac->cont_cls, NULL); 325 rc->cont (rc->cont_cls, NULL);
273 GNUNET_free (ac); 326 GNUNET_free (rc);
274 return ret; 327 return ret;
275} 328}
276 329
@@ -283,9 +336,9 @@ do_transmit (void *cls, size_t size, void *buf)
283static void 336static void
284trigger_transmit (struct GNUNET_PEERSTORE_Handle *h) 337trigger_transmit (struct GNUNET_PEERSTORE_Handle *h)
285{ 338{
286 struct GNUNET_PEERSTORE_AddContext *ac; 339 struct GNUNET_PEERSTORE_RequestContext *rc;
287 340
288 if (NULL == (ac = h->ac_head)) 341 if (NULL == (rc = h->rc_head))
289 return; /* no requests queued */ 342 return; /* no requests queued */
290 if (NULL != h->th) 343 if (NULL != h->th)
291 return; /* request already pending */ 344 return; /* request already pending */
@@ -296,18 +349,154 @@ trigger_transmit (struct GNUNET_PEERSTORE_Handle *h)
296 return; 349 return;
297 } 350 }
298 h->th = 351 h->th =
299 GNUNET_CLIENT_notify_transmit_ready (h->client, ac->size, 352 GNUNET_CLIENT_notify_transmit_ready (h->client, rc->size,
300 GNUNET_TIME_UNIT_FOREVER_REL, 353 GNUNET_TIME_UNIT_FOREVER_REL,
301 GNUNET_YES, 354 GNUNET_YES,
302 &do_transmit, h); 355 &do_transmit, h);
303} 356}
304 357
305/******************************************************************************/ 358/******************************************************************************/
359/******************* GENERAL FUNCTIONS *********************/
360/******************************************************************************/
361
362/**
363 * Function called with server response message
364 * after a store operation is request
365 *
366 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext'
367 * @param msg message received, NULL on timeout or fatal error
368 */
369static void
370peerstore_handler (void *cls, const struct GNUNET_MessageHeader *msg)
371{
372 struct GNUNET_PEERSTORE_Handle *h = cls;
373 struct GNUNET_PEERSTORE_StoreContext *sc;
374 struct StoreResponseMessage *srm;
375 uint16_t response_type;
376 uint16_t response_size;
377 char *emsg;
378
379 h->in_receive = GNUNET_NO;
380 if(NULL == msg)
381 {
382 reconnect(h);
383 return;
384 }
385 response_type = ntohs(msg->type);
386 response_size = ntohs(msg->size);
387 switch(response_type)
388 {
389 case GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT:
390 GNUNET_assert(response_size >= sizeof(struct GNUNET_MessageHeader) + sizeof(struct StoreResponseMessage));
391 sc = h->sc_head;
392 if(NULL == sc)
393 {
394 LOG(GNUNET_ERROR_TYPE_ERROR, "Received a response to a non-existent store request\n");
395 return;
396 }
397 GNUNET_PEERSTORE_store_cancel(sc);
398 trigger_transmit (h);
399 if (NULL != h->sc_head)
400 {
401 h->in_receive = GNUNET_YES;
402 GNUNET_CLIENT_receive (h->client,
403 &peerstore_handler,
404 h,
405 GNUNET_TIME_UNIT_FOREVER_REL);
406 }
407 if(NULL != sc->cont)
408 {
409 srm = (struct StoreResponseMessage *)&msg[1];
410 emsg = NULL;
411 if(GNUNET_NO == ntohs(srm->success))
412 {
413 emsg = GNUNET_malloc(ntohs(srm->emsg_size));
414 memcpy(emsg, &srm[1], ntohs(srm->emsg_size));
415 }
416 sc->cont(sc->cont_cls, emsg);
417 }
418 break;
419 }
420
421}
422
423/******************************************************************************/
306/******************* ADD FUNCTIONS *********************/ 424/******************* ADD FUNCTIONS *********************/
307/******************************************************************************/ 425/******************************************************************************/
308 426
309struct GNUNET_PEERSTORE_AddContext * 427/**
310GNUNET_PEERSTORE_add (struct GNUNET_PEERSTORE_Handle *h, 428 * Cancel a store request
429 *
430 * @param sc Store request context
431 */
432void
433GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
434{
435 struct GNUNET_PEERSTORE_Handle *h;
436
437 h = sc->h;
438 sc->cont = NULL;
439 if (GNUNET_YES == sc->request_transmitted)
440 return; /* need to finish processing */
441 GNUNET_CONTAINER_DLL_remove (h->sc_head,
442 h->sc_tail,
443 sc);
444 if (NULL != sc->rc)
445 {
446 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, sc->rc);
447 GNUNET_free (sc->rc);
448 }
449 GNUNET_free (sc);
450}
451
452/**
453 * Called after store request is sent
454 * Waits for response from service
455 *
456 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext'
457 * @parma emsg error message (or NULL)
458 */
459void store_receive_result(void *cls, const char *emsg)
460{
461 struct GNUNET_PEERSTORE_StoreContext *sc = cls;
462 struct GNUNET_PEERSTORE_Handle *h = sc->h;
463
464 sc->rc = NULL;
465 if(NULL != emsg)
466 {
467 GNUNET_PEERSTORE_store_cancel (sc);
468 reconnect (h);
469 if (NULL != sc->cont)
470 sc->cont (sc->cont_cls, emsg);
471 return;
472 }
473 LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
474 "PEERSTORE");
475 sc->request_transmitted = GNUNET_YES;
476 if (GNUNET_NO == h->in_receive)
477 {
478 h->in_receive = GNUNET_YES;
479 GNUNET_CLIENT_receive (h->client,
480 &peerstore_handler,
481 h,
482 GNUNET_TIME_UNIT_FOREVER_REL);
483 }
484}
485
486/**
487 * Store a new entry in the PEERSTORE
488 *
489 * @param h Handle to the PEERSTORE service
490 * @param peer Peer Identity
491 * @param sub_system name of the sub system
492 * @param value entry value BLOB
493 * @param size size of 'value'
494 * @param lifetime relative time after which the entry is (possibly) deleted
495 * @param cont Continuation function after the store request is processed
496 * @param cont_cls Closure for 'cont'
497 */
498struct GNUNET_PEERSTORE_StoreContext *
499GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
311 const struct GNUNET_PeerIdentity *peer, 500 const struct GNUNET_PeerIdentity *peer,
312 const char *sub_system, 501 const char *sub_system,
313 const void *value, 502 const void *value,
@@ -316,8 +505,9 @@ GNUNET_PEERSTORE_add (struct GNUNET_PEERSTORE_Handle *h,
316 GNUNET_PEERSTORE_Continuation cont, 505 GNUNET_PEERSTORE_Continuation cont,
317 void *cont_cls) 506 void *cont_cls)
318{ 507{
319 struct GNUNET_PEERSTORE_AddContext *ac; 508 struct GNUNET_PEERSTORE_RequestContext *rc;
320 struct AddEntryMessage *entry; 509 struct StoreRequestMessage *entry;
510 struct GNUNET_PEERSTORE_StoreContext *sc;
321 char *ss; 511 char *ss;
322 void *val; 512 void *val;
323 size_t sub_system_size; 513 size_t sub_system_size;
@@ -327,24 +517,32 @@ GNUNET_PEERSTORE_add (struct GNUNET_PEERSTORE_Handle *h,
327 "Storing value (size: %lu) for subsytem `%s' and peer `%s'", 517 "Storing value (size: %lu) for subsytem `%s' and peer `%s'",
328 size, sub_system, GNUNET_i2s (peer)); 518 size, sub_system, GNUNET_i2s (peer));
329 sub_system_size = strlen(sub_system); 519 sub_system_size = strlen(sub_system);
330 request_size = sizeof(struct AddEntryMessage) + sub_system_size + size; 520 request_size = sizeof(struct StoreRequestMessage) + sub_system_size + size;
331 ac = GNUNET_malloc(sizeof(struct GNUNET_PEERSTORE_AddContext) + request_size); 521 rc = GNUNET_malloc(sizeof(struct GNUNET_PEERSTORE_RequestContext) + request_size);
332 ac->h = h; 522 rc->h = h;
333 ac->size = request_size; 523 rc->size = request_size;
334 entry = (struct AddEntryMessage *)&ac[1]; 524 entry = (struct StoreRequestMessage *)&rc[1];
335 entry->header.size = htons(request_size); 525 entry->header.size = htons(request_size);
336 entry->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_ADD); 526 entry->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
337 entry->peer = *peer; 527 entry->peer = *peer;
338 entry->sub_system_size = sub_system_size; 528 entry->sub_system_size = htons(sub_system_size);
339 entry->value_size = size; 529 entry->value_size = htons(size);
340 entry->lifetime = lifetime; 530 entry->lifetime = lifetime;
341 ss = (char *)&entry[1]; 531 ss = (char *)&entry[1];
342 memcpy(ss, sub_system, sub_system_size); 532 memcpy(ss, sub_system, sub_system_size);
343 val = ss + sub_system_size; 533 val = ss + sub_system_size;
344 memcpy(val, value, size); 534 memcpy(val, value, size);
345 GNUNET_CONTAINER_DLL_insert_tail(h->ac_head, h->ac_tail, ac); 535 sc = GNUNET_new(struct GNUNET_PEERSTORE_StoreContext);
536 sc->cont = cont;
537 sc->cont_cls = cont_cls;
538 sc->h = h;
539 sc->rc = rc;
540 rc->cont = &store_receive_result;
541 rc->cont_cls = sc;
542 GNUNET_CONTAINER_DLL_insert_tail(h->rc_head, h->rc_tail, rc);
543 GNUNET_CONTAINER_DLL_insert_tail(h->sc_head, h->sc_tail, sc);
346 trigger_transmit (h); 544 trigger_transmit (h);
347 return ac; 545 return sc;
348 546
349} 547}
350 548