aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-24 11:54:36 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-24 11:54:36 +0000
commiteafc8188ef6584f77dc4dbc6827210f384986e1a (patch)
tree501f87ddd224b0cbd5aaf9008b57005b129cac24 /src/peerinfo
parent2e95a6961bf57170b215ab28e50dbf2376d46747 (diff)
downloadgnunet-eafc8188ef6584f77dc4dbc6827210f384986e1a.tar.gz
gnunet-eafc8188ef6584f77dc4dbc6827210f384986e1a.zip
update peerinfo API to use MQ
Diffstat (limited to 'src/peerinfo')
-rw-r--r--src/peerinfo/peerinfo_api.c780
-rw-r--r--src/peerinfo/test_peerinfo_api.c9
-rw-r--r--src/peerinfo/test_peerinfo_api_friend_only.c78
-rw-r--r--src/peerinfo/test_peerinfo_api_notify_friend_only.c21
-rw-r--r--src/peerinfo/test_peerinfo_shipped_hellos.c53
5 files changed, 353 insertions, 588 deletions
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c
index 0637eda72..e477186ee 100644
--- a/src/peerinfo/peerinfo_api.c
+++ b/src/peerinfo/peerinfo_api.c
@@ -32,46 +32,6 @@
32 32
33 33
34/** 34/**
35 * Entry in the transmission queue to PEERINFO service. We use
36 * the same structure for queueing 'iteration' requests and
37 * actual 'add' messages.
38 */
39struct GNUNET_PEERINFO_AddContext
40{
41 /**
42 * This is a linked list.
43 */
44 struct GNUNET_PEERINFO_AddContext *next;
45
46 /**
47 * This is a linked list.
48 */
49 struct GNUNET_PEERINFO_AddContext *prev;
50
51 /**
52 * Handle to the PEERINFO service.
53 */
54 struct GNUNET_PEERINFO_Handle *h;
55
56 /**
57 * Function to call after request has been transmitted, or NULL.
58 */
59 GNUNET_PEERINFO_Continuation cont;
60
61 /**
62 * Closure for @e cont.
63 */
64 void *cont_cls;
65
66 /**
67 * Number of bytes of the request message (follows after this struct).
68 */
69 size_t size;
70
71};
72
73
74/**
75 * Context for an iteration request. 35 * Context for an iteration request.
76 */ 36 */
77struct GNUNET_PEERINFO_IteratorContext 37struct GNUNET_PEERINFO_IteratorContext
@@ -103,21 +63,6 @@ struct GNUNET_PEERINFO_IteratorContext
103 void *callback_cls; 63 void *callback_cls;
104 64
105 /** 65 /**
106 * Our entry in the transmission queue.
107 */
108 struct GNUNET_PEERINFO_AddContext *ac;
109
110 /**
111 * Task responsible for timeout.
112 */
113 struct GNUNET_SCHEDULER_Task *timeout_task;
114
115 /**
116 * Timeout for the operation.
117 */
118 struct GNUNET_TIME_Absolute timeout;
119
120 /**
121 * Peer we are interested in (only valid if iteration was restricted to one peer). 66 * Peer we are interested in (only valid if iteration was restricted to one peer).
122 */ 67 */
123 struct GNUNET_PeerIdentity peer; 68 struct GNUNET_PeerIdentity peer;
@@ -128,10 +73,9 @@ struct GNUNET_PEERINFO_IteratorContext
128 int have_peer; 73 int have_peer;
129 74
130 /** 75 /**
131 * Set to #GNUNET_YES if we are currently receiving replies from the 76 * Only include friends in reply?
132 * service.
133 */ 77 */
134 int request_transmitted; 78 int include_friend_only;
135 79
136}; 80};
137 81
@@ -149,22 +93,7 @@ struct GNUNET_PEERINFO_Handle
149 /** 93 /**
150 * Connection to the service. 94 * Connection to the service.
151 */ 95 */
152 struct GNUNET_CLIENT_Connection *client; 96 struct GNUNET_MQ_Handle *mq;
153
154 /**
155 * Head of transmission queue.
156 */
157 struct GNUNET_PEERINFO_AddContext *ac_head;
158
159 /**
160 * Tail of transmission queue.
161 */
162 struct GNUNET_PEERINFO_AddContext *ac_tail;
163
164 /**
165 * Handle for the current transmission request, or NULL if none is pending.
166 */
167 struct GNUNET_CLIENT_TransmitHandle *th;
168 97
169 /** 98 /**
170 * Head of iterator DLL. 99 * Head of iterator DLL.
@@ -181,15 +110,19 @@ struct GNUNET_PEERINFO_Handle
181 */ 110 */
182 struct GNUNET_SCHEDULER_Task *r_task; 111 struct GNUNET_SCHEDULER_Task *r_task;
183 112
184 /**
185 * Are we now receiving?
186 */
187 int in_receive;
188
189}; 113};
190 114
191 115
192/** 116/**
117 * Close the existing connection to PEERINFO and reconnect.
118 *
119 * @param h handle to the service
120 */
121static void
122reconnect (struct GNUNET_PEERINFO_Handle *h);
123
124
125/**
193 * Connect to the peerinfo service. 126 * Connect to the peerinfo service.
194 * 127 *
195 * @param cfg configuration to use 128 * @param cfg configuration to use
@@ -202,8 +135,13 @@ GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
202 struct GNUNET_PEERINFO_Handle *h; 135 struct GNUNET_PEERINFO_Handle *h;
203 136
204 h = GNUNET_new (struct GNUNET_PEERINFO_Handle); 137 h = GNUNET_new (struct GNUNET_PEERINFO_Handle);
205 h->client = GNUNET_CLIENT_connect ("peerinfo", cfg);
206 h->cfg = cfg; 138 h->cfg = cfg;
139 reconnect (h);
140 if (NULL == h->mq)
141 {
142 GNUNET_free (h);
143 return NULL;
144 }
207 return h; 145 return h;
208} 146}
209 147
@@ -220,32 +158,19 @@ GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
220void 158void
221GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h) 159GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
222{ 160{
223 struct GNUNET_PEERINFO_AddContext *ac;
224 struct GNUNET_PEERINFO_IteratorContext *ic; 161 struct GNUNET_PEERINFO_IteratorContext *ic;
225 162
226 while (NULL != (ic = h->ic_head)) 163 while (NULL != (ic = h->ic_head))
227 { 164 {
228 GNUNET_break (GNUNET_YES == ic->request_transmitted); 165 GNUNET_CONTAINER_DLL_remove (h->ic_head,
229 ic->request_transmitted = GNUNET_NO; 166 h->ic_tail,
230 GNUNET_PEERINFO_iterate_cancel (ic); 167 ic);
231 } 168 GNUNET_free (ic);
232 while (NULL != (ac = h->ac_head))
233 {
234 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac);
235 if (NULL != ac->cont)
236 ac->cont (ac->cont_cls,
237 _("aborted due to explicit disconnect request"));
238 GNUNET_free (ac);
239 }
240 if (NULL != h->th)
241 {
242 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
243 h->th = NULL;
244 } 169 }
245 if (NULL != h->client) 170 if (NULL != h->mq)
246 { 171 {
247 GNUNET_CLIENT_disconnect (h->client); 172 GNUNET_MQ_destroy (h->mq);
248 h->client = NULL; 173 h->mq = NULL;
249 } 174 }
250 if (NULL != h->r_task) 175 if (NULL != h->r_task)
251 { 176 {
@@ -257,25 +182,6 @@ GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
257 182
258 183
259/** 184/**
260 * Check if we have a request pending in the transmission queue and are
261 * able to transmit it right now. If so, schedule transmission.
262 *
263 * @param h handle to the service
264 */
265static void
266trigger_transmit (struct GNUNET_PEERINFO_Handle *h);
267
268
269/**
270 * Close the existing connection to PEERINFO and reconnect.
271 *
272 * @param h handle to the service
273 */
274static void
275reconnect (struct GNUNET_PEERINFO_Handle *h);
276
277
278/**
279 * Task scheduled to re-try connecting to the peerinfo service. 185 * Task scheduled to re-try connecting to the peerinfo service.
280 * 186 *
281 * @param cls the `struct GNUNET_PEERINFO_Handle *` 187 * @param cls the `struct GNUNET_PEERINFO_Handle *`
@@ -291,277 +197,79 @@ reconnect_task (void *cls)
291 197
292 198
293/** 199/**
294 * Close the existing connection to PEERINFO and reconnect. 200 * We encountered an error, reconnect to the PEERINFO service.
295 * 201 *
296 * @param h handle to the service 202 * @param h handle to reconnect
297 */ 203 */
298static void 204static void
299reconnect (struct GNUNET_PEERINFO_Handle *h) 205do_reconnect (struct GNUNET_PEERINFO_Handle *h)
300{ 206{
301 if (NULL != h->r_task) 207 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
302 {
303 GNUNET_SCHEDULER_cancel (h->r_task);
304 h->r_task = NULL;
305 }
306 if (NULL != h->th)
307 {
308 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
309 h->th = NULL;
310 }
311 if (NULL != h->client)
312 {
313 GNUNET_CLIENT_disconnect (h->client);
314 h->client = NULL;
315 }
316 h->in_receive = GNUNET_NO;
317 h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg);
318 if (NULL == h->client)
319 {
320 h->r_task =
321 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
322 &reconnect_task,
323 h);
324 return;
325 }
326 trigger_transmit (h);
327}
328
329
330/**
331 * Transmit the request at the head of the transmission queue
332 * and trigger continuation (if any).
333 *
334 * @param cls the `struct GNUNET_PEERINFO_Handle *` (with the queue)
335 * @param size size of @a buf (0 on error)
336 * @param buf where to copy the message
337 * @return number of bytes copied to @a buf
338 */
339static size_t
340do_transmit (void *cls,
341 size_t size,
342 void *buf)
343{
344 struct GNUNET_PEERINFO_Handle *h = cls;
345 struct GNUNET_PEERINFO_AddContext *ac = h->ac_head;
346 size_t ret;
347 208
348 h->th = NULL; 209 GNUNET_MQ_destroy (h->mq);
349 if (NULL == ac) 210 h->mq = NULL;
350 return 0; /* request was cancelled in the meantime */ 211 if (NULL != ic)
351 if (NULL == buf)
352 { 212 {
353 /* peerinfo service died */ 213 GNUNET_CONTAINER_DLL_remove (h->ic_head,
354 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 214 h->ic_tail,
355 "Failed to transmit message to `%s' service.\n", 215 ic);
356 "PEERINFO"); 216 if (NULL != ic->callback)
357 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); 217 ic->callback (ic->callback_cls,
358 reconnect (h); 218 NULL,
359 if (NULL != ac->cont) 219 NULL,
360 ac->cont (ac->cont_cls, 220 _("Failed to receive response from `PEERINFO' service."));
361 _("failed to transmit request (service down?)")); 221 GNUNET_free (ic);
362 GNUNET_free (ac);
363 return 0;
364 } 222 }
365 ret = ac->size; 223 h->r_task = GNUNET_SCHEDULER_add_now (&reconnect_task,
366 if (size < ret) 224 h);
367 {
368 /* change in head of queue (i.e. cancel + add), try again */
369 trigger_transmit (h);
370 return 0;
371 }
372 LOG (GNUNET_ERROR_TYPE_DEBUG,
373 "Transmitting request of size %u to `%s' service.\n",
374 ret,
375 "PEERINFO");
376 memcpy (buf, &ac[1], ret);
377 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac);
378 trigger_transmit (h);
379 if (NULL != ac->cont)
380 ac->cont (ac->cont_cls, NULL);
381 GNUNET_free (ac);
382 return ret;
383} 225}
384 226
385 227
386/** 228/**
387 * Check if we have a request pending in the transmission queue and are 229 * We got a disconnect after asking regex to do the announcement.
388 * able to transmit it right now. If so, schedule transmission. 230 * Retry.
389 * 231 *
390 * @param h handle to the service 232 * @param cls the `struct GNUNET_PEERINFO_Handle` to retry
233 * @param error error code
391 */ 234 */
392static void 235static void
393trigger_transmit (struct GNUNET_PEERINFO_Handle *h) 236mq_error_handler (void *cls,
237 enum GNUNET_MQ_Error error)
394{ 238{
395 struct GNUNET_PEERINFO_AddContext *ac; 239 struct GNUNET_PEERINFO_Handle *h = cls;
396
397 if (NULL == (ac = h->ac_head))
398 return; /* no requests queued */
399 if (NULL != h->th)
400 return; /* request already pending */
401 if (NULL == h->client)
402 {
403 /* disconnected, try to reconnect */
404 reconnect (h);
405 return;
406 }
407 h->th =
408 GNUNET_CLIENT_notify_transmit_ready (h->client,
409 ac->size,
410 GNUNET_TIME_UNIT_FOREVER_REL,
411 GNUNET_YES,
412 &do_transmit, h);
413}
414
415
416/**
417 * Add a host to the persistent list. This method operates in
418 * semi-reliable mode: if the transmission is not completed by
419 * the time #GNUNET_PEERINFO_disconnect() is called, it will be
420 * aborted. Furthermore, if a second HELLO is added for the
421 * same peer before the first one was transmitted, PEERINFO may
422 * merge the two HELLOs prior to transmission to the service.
423 *
424 * @param h handle to the peerinfo service
425 * @param hello the verified (!) HELLO message
426 * @param cont continuation to call when done, NULL is allowed
427 * @param cont_cls closure for @a cont
428 * @return handle to cancel add operation; all pending
429 * 'add' operations will be cancelled automatically
430 * on disconnect, so it is not necessary to keep this
431 * handle (unless @a cont is NULL and at some point
432 * calling @a cont must be prevented)
433 */
434struct GNUNET_PEERINFO_AddContext *
435GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
436 const struct GNUNET_HELLO_Message *hello,
437 GNUNET_PEERINFO_Continuation cont,
438 void *cont_cls)
439{
440 uint16_t hs = GNUNET_HELLO_size (hello);
441 struct GNUNET_PEERINFO_AddContext *ac;
442 struct GNUNET_PeerIdentity peer;
443 240
444 GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (hello, &peer)); 241 do_reconnect (h);
445 LOG (GNUNET_ERROR_TYPE_DEBUG,
446 "Adding peer `%s' to PEERINFO database (%u bytes of HELLO)\n",
447 GNUNET_i2s (&peer),
448 hs);
449 ac = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) + hs);
450 ac->h = h;
451 ac->size = hs;
452 ac->cont = cont;
453 ac->cont_cls = cont_cls;
454 memcpy (&ac[1], hello, hs);
455 GNUNET_CONTAINER_DLL_insert_tail (h->ac_head, h->ac_tail, ac);
456 trigger_transmit (h);
457 return ac;
458} 242}
459 243
460 244
461/**
462 * Cancel pending 'add' operation. Must only be called before
463 * either 'cont' or #GNUNET_PEERINFO_disconnect() are invoked.
464 *
465 * @param ac handle for the add operation to cancel
466 */
467void
468GNUNET_PEERINFO_add_peer_cancel (struct GNUNET_PEERINFO_AddContext *ac)
469{
470 struct GNUNET_PEERINFO_Handle *h = ac->h;
471
472 GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac);
473 GNUNET_free (ac);
474}
475
476 245
477/** 246/**
478 * Type of a function to call when we receive a message from the 247 * Function called when we receive an info message. Check it is
479 * service. Call the iterator with the result and (if applicable) 248 * well-formed.
480 * continue to receive more messages or trigger processing the next
481 * event (if applicable).
482 * 249 *
483 * @param cls closure 250 * @param cls closure
484 * @param msg message received, NULL on timeout or fatal error 251 * @param im message received
252 * @return #GNUNET_OK if the message is OK
485 */ 253 */
486static void 254static int
487peerinfo_handler (void *cls, 255check_info (void *cls,
488 const struct GNUNET_MessageHeader *msg) 256 const struct InfoMessage *im)
489{ 257{
490 struct GNUNET_PEERINFO_Handle *h = cls; 258 struct GNUNET_PEERINFO_Handle *h = cls;
491 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head; 259 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
492 const struct InfoMessage *im; 260 uint16_t ms = ntohs (im->header.size) - sizeof (*im);
493 const struct GNUNET_HELLO_Message *hello;
494 GNUNET_PEERINFO_Processor cb;
495 struct GNUNET_PeerIdentity id;
496 void *cb_cls;
497 uint16_t ms;
498 261
499 h->in_receive = GNUNET_NO; 262 if (0 != ntohl (im->reserved))
500 if (NULL == msg)
501 { 263 {
502 /* peerinfo service died, signal error */ 264 GNUNET_break (0);
503 if (NULL != ic) 265 return GNUNET_SYSERR;
504 {
505 cb = ic->callback;
506 cb_cls = ic->callback_cls;
507 GNUNET_PEERINFO_iterate_cancel (ic);
508 }
509 else
510 {
511 cb = NULL;
512 }
513 reconnect (h);
514 if (NULL != cb)
515 cb (cb_cls, NULL, NULL,
516 _("Failed to receive response from `PEERINFO' service."));
517 return;
518 } 266 }
519 if (NULL == ic) 267 if (NULL == ic)
520 { 268 {
521 /* didn't expect a response, reconnect */ 269 /* didn't expect a response, bad */
522 reconnect (h);
523 return;
524 }
525 ic->request_transmitted = GNUNET_NO;
526 cb = ic->callback;
527 cb_cls = ic->callback_cls;
528 if (GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END == ntohs (msg->type))
529 {
530 /* normal end of list of peers, signal end, process next pending request */
531 LOG (GNUNET_ERROR_TYPE_DEBUG,
532 "Received end of list of peers from `%s' service\n",
533 "PEERINFO");
534 GNUNET_PEERINFO_iterate_cancel (ic);
535 trigger_transmit (h);
536 if ( (GNUNET_NO == h->in_receive) &&
537 (NULL != h->ic_head) )
538 {
539 h->in_receive = GNUNET_YES;
540 GNUNET_CLIENT_receive (h->client,
541 &peerinfo_handler,
542 h,
543 GNUNET_TIME_absolute_get_remaining (h->ic_head->timeout));
544 }
545 if (NULL != cb)
546 cb (cb_cls, NULL, NULL, NULL);
547 return;
548 }
549
550 ms = ntohs (msg->size);
551 if ((ms < sizeof (struct InfoMessage)) ||
552 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
553 {
554 /* malformed message */
555 GNUNET_break (0); 270 GNUNET_break (0);
556 GNUNET_PEERINFO_iterate_cancel (ic); 271 return GNUNET_SYSERR;
557 reconnect (h);
558 if (NULL != cb)
559 cb (cb_cls, NULL, NULL,
560 _("Received invalid message from `PEERINFO' service."));
561 return;
562 } 272 }
563 im = (const struct InfoMessage *) msg;
564 GNUNET_break (0 == ntohl (im->reserved));
565 if ( (GNUNET_YES == ic->have_peer) && 273 if ( (GNUNET_YES == ic->have_peer) &&
566 (0 != memcmp (&ic->peer, 274 (0 != memcmp (&ic->peer,
567 &im->peer, 275 &im->peer,
@@ -572,46 +280,28 @@ peerinfo_handler (void *cls,
572 "Received HELLO for peer `%s', expected peer `%s'\n", 280 "Received HELLO for peer `%s', expected peer `%s'\n",
573 GNUNET_i2s (&im->peer), 281 GNUNET_i2s (&im->peer),
574 GNUNET_i2s (&ic->peer)); 282 GNUNET_i2s (&ic->peer));
575
576 GNUNET_break (0); 283 GNUNET_break (0);
577 GNUNET_PEERINFO_iterate_cancel (ic); 284 return GNUNET_SYSERR;
578 reconnect (h);
579 if (NULL != cb)
580 cb (cb_cls,
581 NULL,
582 NULL,
583 _("Received invalid message from `PEERINFO' service."));
584 return;
585 } 285 }
586 hello = NULL; 286 if (ms > sizeof (struct GNUNET_MessageHeader))
587 if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader))
588 { 287 {
288 const struct GNUNET_HELLO_Message *hello;
289 struct GNUNET_PeerIdentity id;
290
589 hello = (const struct GNUNET_HELLO_Message *) &im[1]; 291 hello = (const struct GNUNET_HELLO_Message *) &im[1];
590 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) 292 if (ms != GNUNET_HELLO_size (hello))
591 { 293 {
592 /* malformed message */ 294 /* malformed message */
593 GNUNET_break (0); 295 GNUNET_break (0);
594 GNUNET_PEERINFO_iterate_cancel (ic); 296 return GNUNET_SYSERR;
595 reconnect (h);
596 if (NULL != cb)
597 cb (cb_cls,
598 NULL,
599 NULL,
600 _("Received invalid message from `PEERINFO' service."));
601 return;
602 } 297 }
603 if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &id)) 298 if (GNUNET_OK !=
299 GNUNET_HELLO_get_id (hello,
300 &id))
604 { 301 {
605 /* malformed message */ 302 /* malformed message */
606 GNUNET_break (0); 303 GNUNET_break (0);
607 GNUNET_PEERINFO_iterate_cancel (ic); 304 return GNUNET_SYSERR;
608 reconnect (h);
609 if (NULL != cb)
610 cb (cb_cls,
611 NULL,
612 NULL,
613 _("Received invalid message from `PEERINFO' service."));
614 return;
615 } 305 }
616 if (0 != memcmp (&im->peer, 306 if (0 != memcmp (&im->peer,
617 &id, 307 &id,
@@ -619,100 +309,166 @@ peerinfo_handler (void *cls,
619 { 309 {
620 /* malformed message */ 310 /* malformed message */
621 GNUNET_break (0); 311 GNUNET_break (0);
622 GNUNET_PEERINFO_iterate_cancel (ic); 312 return GNUNET_SYSERR;
623 reconnect (h);
624 if (NULL != cb)
625 cb (cb_cls,
626 NULL,
627 NULL,
628 _("Received invalid message from `PEERINFO' service."));
629 return;
630 } 313 }
631 } 314 }
315 else if (0 != ms)
316 {
317 /* malformed message */
318 GNUNET_break (0);
319 return GNUNET_SYSERR;
320 }
321 return GNUNET_OK;
322}
632 323
633 /* normal data message */ 324
634 LOG (GNUNET_ERROR_TYPE_DEBUG, 325/**
635 "Received %u bytes of `%s' information about peer `%s' from `%s' service\n", 326 * Handle info message.
636 (hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), 327 *
637 "HELLO", 328 * @param cls closure
638 GNUNET_i2s (&im->peer), 329 * @param im message received
639 "PEERINFO"); 330 */
640 h->in_receive = GNUNET_YES; 331static void
641 GNUNET_CLIENT_receive (h->client, 332handle_info (void *cls,
642 &peerinfo_handler, 333 const struct InfoMessage *im)
643 h, 334{
644 GNUNET_TIME_absolute_get_remaining (ic->timeout)); 335 struct GNUNET_PEERINFO_Handle *h = cls;
645 if (NULL != cb) 336 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
646 cb (cb_cls, 337 const struct GNUNET_HELLO_Message *hello;
647 &im->peer, 338 uint16_t ms;
648 hello, 339
649 NULL); 340 ms = ntohs (im->header.size);
341 hello = (0 == ms) ? NULL : (const struct GNUNET_HELLO_Message *) &im[1];
342 if (NULL != ic->callback)
343 ic->callback (ic->callback_cls,
344 &im->peer,
345 hello,
346 NULL);
650} 347}
651 348
652 349
653/** 350/**
654 * We've transmitted the iteration request. Now get ready to process 351 * Send the next IC request at the head of the queue.
655 * the results (or handle transmission error).
656 * 352 *
657 * @param cls the `struct GNUNET_PEERINFO_IteratorContext *` 353 * @param h handle
658 * @param emsg error message, NULL if transmission worked
659 */ 354 */
660static void 355static void
661iterator_start_receive (void *cls, 356send_ic_request (struct GNUNET_PEERINFO_Handle *h)
662 const char *emsg)
663{ 357{
664 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 358 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
665 struct GNUNET_PEERINFO_Handle *h = ic->h; 359 struct GNUNET_MQ_Envelope *env;
666 GNUNET_PEERINFO_Processor cb; 360 struct ListAllPeersMessage *lapm;
667 void *cb_cls; 361 struct ListPeerMessage *lpm;
668 362
669 ic->ac = NULL; 363 if (NULL == ic)
670 if (NULL != emsg)
671 { 364 {
672 cb = ic->callback; 365 GNUNET_break (0);
673 cb_cls = ic->callback_cls;
674 GNUNET_PEERINFO_iterate_cancel (ic);
675 reconnect (h);
676 if (NULL != cb)
677 cb (cb_cls, NULL, NULL, emsg);
678 return; 366 return;
679 } 367 }
680 LOG (GNUNET_ERROR_TYPE_DEBUG, 368 if (NULL == h->mq)
681 "Waiting for response from `%s' service.\n", 369 {
682 "PEERINFO"); 370 GNUNET_break (0);
683 ic->request_transmitted = GNUNET_YES; 371 return;
684 if (GNUNET_NO == h->in_receive) 372 }
373 if (GNUNET_NO == ic->have_peer)
374 {
375 LOG (GNUNET_ERROR_TYPE_DEBUG,
376 "Requesting list of peers from PEERINFO service\n");
377 env = GNUNET_MQ_msg (lapm,
378 GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
379 lapm->include_friend_only = htonl (ic->include_friend_only);
380 }
381 else
382 {
383 LOG (GNUNET_ERROR_TYPE_DEBUG,
384 "Requesting information on peer `%s' from PEERINFO service\n",
385 GNUNET_i2s (&ic->peer));
386 env = GNUNET_MQ_msg (lpm,
387 GNUNET_MESSAGE_TYPE_PEERINFO_GET);
388 lpm->include_friend_only = htonl (ic->include_friend_only);
389 lpm->peer = ic->peer;
390 }
391 GNUNET_MQ_send (h->mq,
392 env);
393}
394
395
396/**
397 * Type of a function to call when we receive a message from the
398 * service. Call the iterator with the result and (if applicable)
399 * continue to receive more messages or trigger processing the next
400 * event (if applicable).
401 *
402 * @param cls closure
403 * @param msg message received, NULL on timeout or fatal error
404 */
405static void
406handle_end_iteration (void *cls,
407 const struct GNUNET_MessageHeader *msg)
408{
409 struct GNUNET_PEERINFO_Handle *h = cls;
410 struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
411
412 if (NULL == ic)
685 { 413 {
686 h->in_receive = GNUNET_YES; 414 /* didn't expect a response, reconnect */
687 GNUNET_CLIENT_receive (h->client, 415 GNUNET_break (0);
688 &peerinfo_handler, 416 reconnect (h);
689 h, 417 return;
690 GNUNET_TIME_absolute_get_remaining (ic->timeout));
691 } 418 }
419 LOG (GNUNET_ERROR_TYPE_DEBUG,
420 "Received end of list of peers from PEERINFO service\n");
421 GNUNET_CONTAINER_DLL_remove (h->ic_head,
422 h->ic_tail,
423 ic);
424 if (NULL != h->ic_head)
425 send_ic_request (h);
426 if (NULL != ic->callback)
427 ic->callback (ic->callback_cls,
428 NULL,
429 NULL,
430 NULL);
431 GNUNET_free (ic);
692} 432}
693 433
694 434
695/** 435/**
696 * Peerinfo iteration request has timed out. 436 * Close the existing connection to PEERINFO and reconnect.
697 * 437 *
698 * @param cls the `struct GNUNET_PEERINFO_IteratorContext *` 438 * @param h handle to the service
699 */ 439 */
700static void 440static void
701signal_timeout (void *cls) 441reconnect (struct GNUNET_PEERINFO_Handle *h)
702{ 442{
703 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 443 GNUNET_MQ_hd_var_size (info,
704 GNUNET_PEERINFO_Processor cb; 444 GNUNET_MESSAGE_TYPE_PEERINFO_INFO,
705 void *cb_cls; 445 struct InfoMessage);
706 446 GNUNET_MQ_hd_fixed_size (end_iteration,
707 ic->timeout_task = NULL; 447 GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END,
708 cb = ic->callback; 448 struct GNUNET_MessageHeader);
709 cb_cls = ic->callback_cls; 449 struct GNUNET_MQ_MessageHandler handlers[] = {
710 GNUNET_PEERINFO_iterate_cancel (ic); 450 make_info_handler (h),
711 if (NULL != cb) 451 make_end_iteration_handler (h),
712 cb (cb_cls, 452 GNUNET_MQ_handler_end ()
713 NULL, 453 };
714 NULL, 454
715 _("Timeout transmitting iteration request to `PEERINFO' service.")); 455 if (NULL != h->r_task)
456 {
457 GNUNET_SCHEDULER_cancel (h->r_task);
458 h->r_task = NULL;
459 }
460 if (NULL != h->mq)
461 {
462 GNUNET_MQ_destroy (h->mq);
463 h->mq = NULL;
464 }
465 h->mq = GNUNET_CLIENT_connecT (h->cfg,
466 "peerinfo",
467 handlers,
468 &mq_error_handler,
469 h);
470 if (NULL != h->ic_head)
471 send_ic_request (h);
716} 472}
717 473
718 474
@@ -728,7 +484,6 @@ signal_timeout (void *cls)
728 * @param h handle to the peerinfo service 484 * @param h handle to the peerinfo service
729 * @param include_friend_only include HELLO messages for friends only 485 * @param include_friend_only include HELLO messages for friends only
730 * @param peer restrict iteration to this peer only (can be NULL) 486 * @param peer restrict iteration to this peer only (can be NULL)
731 * @param timeout how long to wait until timing out
732 * @param callback the method to call for each peer 487 * @param callback the method to call for each peer
733 * @param callback_cls closure for @a callback 488 * @param callback_cls closure for @a callback
734 * @return iterator context 489 * @return iterator context
@@ -737,62 +492,26 @@ struct GNUNET_PEERINFO_IteratorContext *
737GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, 492GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
738 int include_friend_only, 493 int include_friend_only,
739 const struct GNUNET_PeerIdentity *peer, 494 const struct GNUNET_PeerIdentity *peer,
740 struct GNUNET_TIME_Relative timeout,
741 GNUNET_PEERINFO_Processor callback, 495 GNUNET_PEERINFO_Processor callback,
742 void *callback_cls) 496 void *callback_cls)
743{ 497{
744 struct ListAllPeersMessage *lapm;
745 struct ListPeerMessage *lpm;
746 struct GNUNET_PEERINFO_IteratorContext *ic; 498 struct GNUNET_PEERINFO_IteratorContext *ic;
747 struct GNUNET_PEERINFO_AddContext *ac;
748 499
749 ic = GNUNET_new (struct GNUNET_PEERINFO_IteratorContext); 500 ic = GNUNET_new (struct GNUNET_PEERINFO_IteratorContext);
750 if (NULL == peer) 501 ic->h = h;
751 { 502 ic->include_friend_only = include_friend_only;
752 LOG (GNUNET_ERROR_TYPE_DEBUG, 503 ic->callback = callback;
753 "Requesting list of peers from PEERINFO service\n"); 504 ic->callback_cls = callback_cls;
754 ac = 505 if (NULL != peer)
755 GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) +
756 sizeof (struct ListAllPeersMessage));
757 ac->size = sizeof (struct ListAllPeersMessage);
758 lapm = (struct ListAllPeersMessage *) &ac[1];
759 lapm->header.size = htons (sizeof (struct ListAllPeersMessage));
760 lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
761 lapm->include_friend_only = htonl (include_friend_only);
762 }
763 else
764 { 506 {
765 LOG (GNUNET_ERROR_TYPE_DEBUG,
766 "Requesting information on peer `%4s' from PEERINFO service\n",
767 GNUNET_i2s (peer));
768 ac =
769 GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) +
770 sizeof (struct ListPeerMessage));
771 ac->size = sizeof (struct ListPeerMessage);
772 lpm = (struct ListPeerMessage *) &ac[1];
773 lpm->header.size = htons (sizeof (struct ListPeerMessage));
774 lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
775 lpm->include_friend_only = htonl (include_friend_only);
776 memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
777 ic->have_peer = GNUNET_YES; 507 ic->have_peer = GNUNET_YES;
778 ic->peer = *peer; 508 ic->peer = *peer;
779 } 509 }
780 ic->h = h;
781 ic->ac = ac;
782 ic->callback = callback;
783 ic->callback_cls = callback_cls;
784 ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
785 ic->timeout_task =
786 GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic);
787 ac->cont = &iterator_start_receive;
788 ac->cont_cls = ic;
789 GNUNET_CONTAINER_DLL_insert_tail (h->ac_head,
790 h->ac_tail,
791 ac);
792 GNUNET_CONTAINER_DLL_insert_tail (h->ic_head, 510 GNUNET_CONTAINER_DLL_insert_tail (h->ic_head,
793 h->ic_tail, 511 h->ic_tail,
794 ic); 512 ic);
795 trigger_transmit (h); 513 if (h->ic_head == ic)
514 send_ic_request (h);
796 return ic; 515 return ic;
797} 516}
798 517
@@ -805,29 +524,62 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
805void 524void
806GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) 525GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic)
807{ 526{
808 struct GNUNET_PEERINFO_Handle *h; 527 struct GNUNET_PEERINFO_Handle *h = ic->h;
809 528
810 h = ic->h;
811 if (NULL != ic->timeout_task)
812 {
813 GNUNET_SCHEDULER_cancel (ic->timeout_task);
814 ic->timeout_task = NULL;
815 }
816 ic->callback = NULL; 529 ic->callback = NULL;
817 if (GNUNET_YES == ic->request_transmitted) 530 if (ic == h->ic_head)
818 return; /* need to finish processing */ 531 return;
819 GNUNET_CONTAINER_DLL_remove (h->ic_head, 532 GNUNET_CONTAINER_DLL_remove (h->ic_head,
820 h->ic_tail, 533 h->ic_tail,
821 ic); 534 ic);
822 if (NULL != ic->ac)
823 {
824 GNUNET_CONTAINER_DLL_remove (h->ac_head,
825 h->ac_tail,
826 ic->ac);
827 GNUNET_free (ic->ac);
828 }
829 GNUNET_free (ic); 535 GNUNET_free (ic);
830} 536}
831 537
832 538
539/**
540 * Add a host to the persistent list. This method operates in
541 * semi-reliable mode: if the transmission is not completed by
542 * the time #GNUNET_PEERINFO_disconnect() is called, it will be
543 * aborted. Furthermore, if a second HELLO is added for the
544 * same peer before the first one was transmitted, PEERINFO may
545 * merge the two HELLOs prior to transmission to the service.
546 *
547 * @param h handle to the peerinfo service
548 * @param hello the verified (!) HELLO message
549 * @param cont continuation to call when done, NULL is allowed
550 * @param cont_cls closure for @a cont
551 * @return handle to cancel add operation; all pending
552 * 'add' operations will be cancelled automatically
553 * on disconnect, so it is not necessary to keep this
554 * handle (unless @a cont is NULL and at some point
555 * calling @a cont must be prevented)
556 */
557struct GNUNET_MQ_Envelope *
558GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
559 const struct GNUNET_HELLO_Message *hello,
560 GNUNET_MQ_NotifyCallback cont,
561 void *cont_cls)
562{
563 struct GNUNET_MQ_Envelope *env;
564 struct GNUNET_PeerIdentity peer;
565
566 if (NULL == h->mq)
567 return NULL;
568 GNUNET_assert (GNUNET_OK ==
569 GNUNET_HELLO_get_id (hello,
570 &peer));
571 LOG (GNUNET_ERROR_TYPE_DEBUG,
572 "Adding peer `%s' to PEERINFO database\n",
573 GNUNET_i2s (&peer));
574 env = GNUNET_MQ_msg_copy ((const struct GNUNET_MessageHeader *) hello);
575 if (NULL != cont)
576 GNUNET_MQ_notify_sent (env,
577 cont,
578 cont_cls);
579 GNUNET_MQ_send (h->mq,
580 env);
581 return env;
582}
583
584
833/* end of peerinfo_api.c */ 585/* end of peerinfo_api.c */
diff --git a/src/peerinfo/test_peerinfo_api.c b/src/peerinfo/test_peerinfo_api.c
index 9fe6bf712..96e73e20a 100644
--- a/src/peerinfo/test_peerinfo_api.c
+++ b/src/peerinfo/test_peerinfo_api.c
@@ -119,8 +119,7 @@ process (void *cls, const struct GNUNET_PeerIdentity *peer,
119 retries++; 119 retries++;
120 add_peer (); 120 add_peer ();
121 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, NULL, 121 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, NULL,
122 GNUNET_TIME_relative_multiply 122 &process,
123 (GNUNET_TIME_UNIT_SECONDS, 15), &process,
124 cls); 123 cls);
125 return; 124 return;
126 } 125 }
@@ -135,7 +134,8 @@ process (void *cls, const struct GNUNET_PeerIdentity *peer,
135 { 134 {
136 GNUNET_assert (3 == global_ret); 135 GNUNET_assert (3 == global_ret);
137 agc = 3; 136 agc = 3;
138 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_it, &agc); 137 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
138 &check_it, &agc);
139 GNUNET_assert (agc == 0); 139 GNUNET_assert (agc == 0);
140 global_ret = 2; 140 global_ret = 2;
141 } 141 }
@@ -151,8 +151,7 @@ run (void *cls,
151 GNUNET_assert (NULL != h); 151 GNUNET_assert (NULL != h);
152 add_peer (); 152 add_peer ();
153 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, &pid, 153 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, &pid,
154 GNUNET_TIME_relative_multiply 154 &process, cls);
155 (GNUNET_TIME_UNIT_SECONDS, 15), &process, cls);
156} 155}
157 156
158 157
diff --git a/src/peerinfo/test_peerinfo_api_friend_only.c b/src/peerinfo/test_peerinfo_api_friend_only.c
index 1275e4668..8086d8d43 100644
--- a/src/peerinfo/test_peerinfo_api_friend_only.c
+++ b/src/peerinfo/test_peerinfo_api_friend_only.c
@@ -32,18 +32,23 @@
32#include "gnunet_util_lib.h" 32#include "gnunet_util_lib.h"
33#include "gnunet_peerinfo_service.h" 33#include "gnunet_peerinfo_service.h"
34#include "gnunet_testing_lib.h" 34#include "gnunet_testing_lib.h"
35#include "peerinfo.h" 35
36 36
37static struct GNUNET_PEERINFO_IteratorContext *ic; 37static struct GNUNET_PEERINFO_IteratorContext *ic;
38 38
39static struct GNUNET_PEERINFO_Handle *h; 39static struct GNUNET_PEERINFO_Handle *h;
40 40
41static struct GNUNET_PeerIdentity pid;
42
41static unsigned int retries; 43static unsigned int retries;
42 44
43static int global_ret; 45static int global_ret;
44 46
47
45static ssize_t 48static ssize_t
46address_generator (void *cls, size_t max, void *buf) 49address_generator (void *cls,
50 size_t max,
51 void *buf)
47{ 52{
48 size_t *agc = cls; 53 size_t *agc = cls;
49 ssize_t ret; 54 ssize_t ret;
@@ -51,19 +56,20 @@ address_generator (void *cls, size_t max, void *buf)
51 56
52 if (0 == *agc) 57 if (0 == *agc)
53 return GNUNET_SYSERR; /* Done */ 58 return GNUNET_SYSERR; /* Done */
54 memset (&address.peer, 0, sizeof (struct GNUNET_PeerIdentity)); 59 memset (&address.peer,
60 0,
61 sizeof (struct GNUNET_PeerIdentity));
55 address.address = "Address"; 62 address.address = "Address";
56 address.transport_name = "peerinfotest"; 63 address.transport_name = "peerinfotest";
57 address.address_length = *agc; 64 address.address_length = *agc;
58 ret = 65 ret = GNUNET_HELLO_add_address (&address,
59 GNUNET_HELLO_add_address (&address, 66 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS),
60 GNUNET_TIME_relative_to_absolute 67 buf,
61 (GNUNET_TIME_UNIT_HOURS), buf, max); 68 max);
62 (*agc)--; 69 (*agc)--;
63 return ret; 70 return ret;
64} 71}
65 72
66struct GNUNET_PeerIdentity pid;
67 73
68static void 74static void
69add_peer () 75add_peer ()
@@ -73,24 +79,32 @@ add_peer ()
73 79
74 agc = 2; 80 agc = 2;
75 memset (&pid, 32, sizeof (pid)); 81 memset (&pid, 32, sizeof (pid));
76 h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &agc, GNUNET_YES); 82 h2 = GNUNET_HELLO_create (&pid.public_key,
77 GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL); 83 &address_generator,
84 &agc,
85 GNUNET_YES);
86 GNUNET_PEERINFO_add_peer (h,
87 h2,
88 NULL,
89 NULL);
78 GNUNET_free (h2); 90 GNUNET_free (h2);
79 91
80} 92}
81 93
82 94
83static void 95static void
84process (void *cls, const struct GNUNET_PeerIdentity *peer, 96process (void *cls,
85 const struct GNUNET_HELLO_Message *hello, const char *err_msg) 97 const struct GNUNET_PeerIdentity *peer,
98 const struct GNUNET_HELLO_Message *hello,
99 const char *err_msg)
86{ 100{
87 if (err_msg != NULL) 101 if (NULL != err_msg)
88 { 102 {
89 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
90 _("Error in communication with PEERINFO service\n")); 104 "Error in communication with PEERINFO service: %s\n",
105 err_msg);
91 } 106 }
92 107 if (NULL == peer)
93 if (peer == NULL)
94 { 108 {
95 ic = NULL; 109 ic = NULL;
96 if ((3 == global_ret) && (retries < 50)) 110 if ((3 == global_ret) && (retries < 50))
@@ -98,29 +112,26 @@ process (void *cls, const struct GNUNET_PeerIdentity *peer,
98 /* try again */ 112 /* try again */
99 retries++; 113 retries++;
100 add_peer (); 114 add_peer ();
101 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, NULL, 115 ic = GNUNET_PEERINFO_iterate (h,
102 GNUNET_TIME_relative_multiply 116 GNUNET_NO,
103 (GNUNET_TIME_UNIT_SECONDS, 15), &process, 117 NULL,
118 &process,
104 cls); 119 cls);
105 return; 120 return;
106 } 121 }
107 GNUNET_assert (peer == NULL); 122 GNUNET_assert (peer == NULL);
108 GNUNET_assert (2 == global_ret);
109 GNUNET_PEERINFO_disconnect (h); 123 GNUNET_PEERINFO_disconnect (h);
110 h = NULL; 124 h = NULL;
111 global_ret = 0; 125 global_ret = 0;
112 return; 126 return;
113 } 127 }
114 128
115 if (hello == NULL) 129 if ( (NULL != hello) &&
116 { 130 (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) )
117 GNUNET_assert (3 == global_ret);
118 global_ret = 2;
119 }
120 else
121 { 131 {
122 fprintf (stderr, "Received %s HELLO\n", 132 fprintf (stderr,
123 (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) ? "friend only" : "public"); 133 "Received friend-only HELLO\n");
134 global_ret = 1;
124 GNUNET_PEERINFO_disconnect (h); 135 GNUNET_PEERINFO_disconnect (h);
125 h = NULL; 136 h = NULL;
126 return; 137 return;
@@ -136,14 +147,17 @@ run (void *cls,
136 h = GNUNET_PEERINFO_connect (cfg); 147 h = GNUNET_PEERINFO_connect (cfg);
137 GNUNET_assert (NULL != h); 148 GNUNET_assert (NULL != h);
138 add_peer (); 149 add_peer ();
139 ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, &pid, 150 ic = GNUNET_PEERINFO_iterate (h,
140 GNUNET_TIME_relative_multiply 151 GNUNET_NO,
141 (GNUNET_TIME_UNIT_SECONDS, 15), &process, cls); 152 &pid,
153 &process,
154 NULL);
142} 155}
143 156
144 157
145int 158int
146main (int argc, char *argv[]) 159main (int argc,
160 char *argv[])
147{ 161{
148 global_ret = 3; 162 global_ret = 3;
149 if (0 != GNUNET_TESTING_service_run ("test-peerinfo-api-friend-only", 163 if (0 != GNUNET_TESTING_service_run ("test-peerinfo-api-friend-only",
diff --git a/src/peerinfo/test_peerinfo_api_notify_friend_only.c b/src/peerinfo/test_peerinfo_api_notify_friend_only.c
index 403ed4b71..e91610c25 100644
--- a/src/peerinfo/test_peerinfo_api_notify_friend_only.c
+++ b/src/peerinfo/test_peerinfo_api_notify_friend_only.c
@@ -209,22 +209,6 @@ process_wo_fo (void *cls, const struct GNUNET_PeerIdentity *peer,
209 209
210 210
211static void 211static void
212add_peer_done (void *cls, const char *emsg)
213{
214 if (NULL == emsg)
215 {
216 return;
217 }
218 else
219 {
220 GNUNET_break(0);
221 GNUNET_SCHEDULER_cancel (timeout_task);
222 timeout_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
223 }
224}
225
226
227static void
228add_peer () 212add_peer ()
229{ 213{
230 struct GNUNET_HELLO_Message *h2; 214 struct GNUNET_HELLO_Message *h2;
@@ -233,10 +217,9 @@ add_peer ()
233 agc = 2; 217 agc = 2;
234 memset (&pid, 32, sizeof(pid)); 218 memset (&pid, 32, sizeof(pid));
235 h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &agc, 219 h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &agc,
236 GNUNET_YES); 220 GNUNET_YES);
237 GNUNET_PEERINFO_add_peer (h, h2, &add_peer_done, NULL); 221 GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL);
238 GNUNET_free(h2); 222 GNUNET_free(h2);
239
240} 223}
241 224
242 225
diff --git a/src/peerinfo/test_peerinfo_shipped_hellos.c b/src/peerinfo/test_peerinfo_shipped_hellos.c
index 7e3ba09d0..dfaac5da9 100644
--- a/src/peerinfo/test_peerinfo_shipped_hellos.c
+++ b/src/peerinfo/test_peerinfo_shipped_hellos.c
@@ -38,12 +38,13 @@ static struct GNUNET_PEERINFO_Handle *h;
38 38
39static int global_ret; 39static int global_ret;
40 40
41
41static int 42static int
42addr_cb (void *cls, 43addr_cb (void *cls,
43 const struct GNUNET_HELLO_Address *address, 44 const struct GNUNET_HELLO_Address *address,
44 struct GNUNET_TIME_Absolute expiration) 45 struct GNUNET_TIME_Absolute expiration)
45{ 46{
46 int *addr = cls; 47 unsigned int *addr = cls;
47 48
48 (*addr) ++; 49 (*addr) ++;
49 return GNUNET_OK; 50 return GNUNET_OK;
@@ -57,28 +58,35 @@ process (void *cls,
57 const char *err_msg) 58 const char *err_msg)
58{ 59{
59 static unsigned int calls = 0; 60 static unsigned int calls = 0;
60 int addr; 61 unsigned int addr;
61 62
62 if (err_msg != NULL) 63 if (NULL != err_msg)
63 { 64 {
64 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 65 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
65 _("Error in communication with PEERINFO service\n")); 66 "Error in communication with PEERINFO service: %s\n",
67 err_msg);
66 } 68 }
67 if (NULL != peer) 69 if (NULL != peer)
68 { 70 {
69 addr = 0; 71 addr = 0;
70 if (NULL != hello) 72 if (NULL != hello)
71 { 73 {
72 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &addr_cb, &addr); 74 GNUNET_HELLO_iterate_addresses (hello,
75 GNUNET_NO,
76 &addr_cb,
77 &addr);
73 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 78 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
74 "Got information about peer `%s' with %u addresses \n", 79 "Got information about peer %s with %u addresses\n",
75 GNUNET_i2s (peer), addr); 80 GNUNET_i2s (peer),
81 addr);
76 calls++; 82 calls++;
77 } 83 }
78 else 84 else
79 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 85 {
80 "Fail: Got information about peer `%s' without HELLO \n", 86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Got no HELLP for peer %s\n",
81 GNUNET_i2s (peer)); 88 GNUNET_i2s (peer));
89 }
82 } 90 }
83 else 91 else
84 { 92 {
@@ -87,13 +95,18 @@ process (void *cls,
87 fprintf (stderr, 95 fprintf (stderr,
88 "Failed: got no callbacks!\n"); 96 "Failed: got no callbacks!\n");
89 global_ret = 1; 97 global_ret = 1;
98 GNUNET_PEERINFO_disconnect (h);
99 h = NULL;
90 } 100 }
91 else 101 else
92 { 102 {
93 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
94 "Got %u callbacks\n", calls); 104 "Got %u HELLOs in total\n",
95 global_ret = 0; 105 calls);
96 } 106 global_ret = 0;
107 GNUNET_PEERINFO_disconnect (h);
108 h = NULL;
109 }
97 } 110 }
98} 111}
99 112
@@ -105,14 +118,18 @@ run (void *cls,
105{ 118{
106 h = GNUNET_PEERINFO_connect (cfg); 119 h = GNUNET_PEERINFO_connect (cfg);
107 GNUNET_assert (NULL != h); 120 GNUNET_assert (NULL != h);
108 ic = GNUNET_PEERINFO_iterate (h, GNUNET_YES, NULL, 121 ic = GNUNET_PEERINFO_iterate (h,
109 GNUNET_TIME_relative_multiply 122 GNUNET_YES,
110 (GNUNET_TIME_UNIT_SECONDS, 15), &process, cls); 123 NULL,
124 &process,
125 cls);
126 GNUNET_assert (NULL != ic);
111} 127}
112 128
113 129
114int 130int
115main (int argc, char *argv[]) 131main (int argc,
132 char *argv[])
116{ 133{
117 global_ret = 3; 134 global_ret = 3;
118 if (0 != GNUNET_TESTING_service_run ("test_peerinfo_shipped_hellos", 135 if (0 != GNUNET_TESTING_service_run ("test_peerinfo_shipped_hellos",