aboutsummaryrefslogtreecommitdiff
path: root/src/util/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/client.c')
-rw-r--r--src/util/client.c822
1 files changed, 416 insertions, 406 deletions
diff --git a/src/util/client.c b/src/util/client.c
index 5193f751f..5d5387ef9 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -43,6 +43,8 @@
43 */ 43 */
44#define MAX_ATTEMPTS 50 44#define MAX_ATTEMPTS 50
45 45
46#define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__)
47
46/** 48/**
47 * Handle for a transmission request. 49 * Handle for a transmission request.
48 */ 50 */
@@ -262,7 +264,8 @@ struct GNUNET_CLIENT_Connection
262 */ 264 */
263static struct GNUNET_CONNECTION_Handle * 265static struct GNUNET_CONNECTION_Handle *
264do_connect (const char *service_name, 266do_connect (const char *service_name,
265 const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) 267 const struct GNUNET_CONFIGURATION_Handle *cfg,
268 unsigned int attempt)
266{ 269{
267 struct GNUNET_CONNECTION_Handle *sock; 270 struct GNUNET_CONNECTION_Handle *sock;
268 char *hostname; 271 char *hostname;
@@ -272,79 +275,80 @@ do_connect (const char *service_name,
272 sock = NULL; 275 sock = NULL;
273#if AF_UNIX 276#if AF_UNIX
274 if (0 == (attempt % 2)) 277 if (0 == (attempt % 2))
275 {
276 /* on even rounds, try UNIX */
277 unixpath = NULL;
278 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */
279 { 278 {
280 sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); 279 /* on even rounds, try UNIX */
281 if (sock != NULL) 280 unixpath = NULL;
282 { 281 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */
282 {
283 sock =
284 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
285 if (sock != NULL)
286 {
283#if DEBUG_CLIENT 287#if DEBUG_CLIENT
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", 288 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n",
285 unixpath); 289 unixpath);
286#endif 290#endif
287 GNUNET_free (unixpath); 291 GNUNET_free (unixpath);
288 return sock; 292 return sock;
289 } 293 }
294 }
295 GNUNET_free_non_null (unixpath);
290 } 296 }
291 GNUNET_free_non_null (unixpath);
292 }
293#endif 297#endif
294 298
295 if ((GNUNET_OK != 299 if ((GNUNET_OK !=
296 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) 300 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT",
297 || (port > 65535) || 301 &port)) || (port > 65535)
298 (GNUNET_OK != 302 || (GNUNET_OK !=
299 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", 303 GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
300 &hostname))) 304 "HOSTNAME", &hostname)))
301 { 305 {
302 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 306 LOG (GNUNET_ERROR_TYPE_WARNING,
303 _ 307 _
304 ("Could not determine valid hostname and port for service `%s' from configuration.\n"), 308 ("Could not determine valid hostname and port for service `%s' from configuration.\n"),
305 service_name); 309 service_name);
306 return NULL; 310 return NULL;
307 } 311 }
308 if (0 == strlen (hostname)) 312 if (0 == strlen (hostname))
309 {
310 GNUNET_free (hostname);
311 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
312 _("Need a non-empty hostname for service `%s'.\n"),
313 service_name);
314 return NULL;
315 }
316 if (port == 0)
317 {
318#if AF_UNIX
319 if (0 != (attempt % 2))
320 { 313 {
321 /* try UNIX */ 314 GNUNET_free (hostname);
322 unixpath = NULL; 315 LOG (GNUNET_ERROR_TYPE_WARNING,
323 if ((GNUNET_OK == 316 _("Need a non-empty hostname for service `%s'.\n"), service_name);
324 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", 317 return NULL;
325 &unixpath)) &&
326 (0 < strlen (unixpath)))
327 {
328 sock =
329 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
330 if (sock != NULL)
331 {
332 GNUNET_free (unixpath);
333 GNUNET_free (hostname);
334 return sock;
335 }
336 }
337 GNUNET_free_non_null (unixpath);
338 } 318 }
319 if (port == 0)
320 {
321#if AF_UNIX
322 if (0 != (attempt % 2))
323 {
324 /* try UNIX */
325 unixpath = NULL;
326 if ((GNUNET_OK ==
327 GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
328 "UNIXPATH", &unixpath))
329 && (0 < strlen (unixpath)))
330 {
331 sock =
332 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg,
333 unixpath);
334 if (sock != NULL)
335 {
336 GNUNET_free (unixpath);
337 GNUNET_free (hostname);
338 return sock;
339 }
340 }
341 GNUNET_free_non_null (unixpath);
342 }
339#endif 343#endif
340#if DEBUG_CLIENT 344#if DEBUG_CLIENT
341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 345 LOG (GNUNET_ERROR_TYPE_DEBUG,
342 "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", 346 "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n",
343 service_name); 347 service_name);
344#endif 348#endif
345 GNUNET_free (hostname); 349 GNUNET_free (hostname);
346 return NULL; 350 return NULL;
347 } 351 }
348 352
349 sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); 353 sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
350 GNUNET_free (hostname); 354 GNUNET_free (hostname);
@@ -361,7 +365,7 @@ do_connect (const char *service_name,
361 */ 365 */
362struct GNUNET_CLIENT_Connection * 366struct GNUNET_CLIENT_Connection *
363GNUNET_CLIENT_connect (const char *service_name, 367GNUNET_CLIENT_connect (const char *service_name,
364 const struct GNUNET_CONFIGURATION_Handle *cfg) 368 const struct GNUNET_CONFIGURATION_Handle *cfg)
365{ 369{
366 struct GNUNET_CLIENT_Connection *ret; 370 struct GNUNET_CLIENT_Connection *ret;
367 struct GNUNET_CONNECTION_Handle *sock; 371 struct GNUNET_CONNECTION_Handle *sock;
@@ -385,7 +389,7 @@ GNUNET_CLIENT_connect (const char *service_name,
385 */ 389 */
386void 390void
387GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h, 391GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h,
388 int do_ignore) 392 int do_ignore)
389{ 393{
390 h->ignore_shutdown = do_ignore; 394 h->ignore_shutdown = do_ignore;
391 if (h->sock != NULL) 395 if (h->sock != NULL)
@@ -410,33 +414,33 @@ GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h,
410 */ 414 */
411void 415void
412GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, 416GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock,
413 int finish_pending_write) 417 int finish_pending_write)
414{ 418{
415 if (sock->in_receive == GNUNET_YES) 419 if (sock->in_receive == GNUNET_YES)
416 { 420 {
417 GNUNET_CONNECTION_receive_cancel (sock->sock); 421 GNUNET_CONNECTION_receive_cancel (sock->sock);
418 sock->in_receive = GNUNET_NO; 422 sock->in_receive = GNUNET_NO;
419 } 423 }
420 if (sock->th != NULL) 424 if (sock->th != NULL)
421 { 425 {
422 GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); 426 GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th);
423 sock->th = NULL; 427 sock->th = NULL;
424 } 428 }
425 if (NULL != sock->sock) 429 if (NULL != sock->sock)
426 { 430 {
427 GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); 431 GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write);
428 sock->sock = NULL; 432 sock->sock = NULL;
429 } 433 }
430 if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) 434 if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK)
431 { 435 {
432 GNUNET_SCHEDULER_cancel (sock->receive_task); 436 GNUNET_SCHEDULER_cancel (sock->receive_task);
433 sock->receive_task = GNUNET_SCHEDULER_NO_TASK; 437 sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
434 } 438 }
435 if (sock->tag != NULL) 439 if (sock->tag != NULL)
436 { 440 {
437 GNUNET_free (sock->tag); 441 GNUNET_free (sock->tag);
438 sock->tag = NULL; 442 sock->tag = NULL;
439 } 443 }
440 sock->receiver_handler = NULL; 444 sock->receiver_handler = NULL;
441 GNUNET_array_grow (sock->received_buf, sock->received_size, 0); 445 GNUNET_array_grow (sock->received_buf, sock->received_size, 0);
442 GNUNET_free (sock->service_name); 446 GNUNET_free (sock->service_name);
@@ -453,7 +457,7 @@ check_complete (struct GNUNET_CLIENT_Connection *conn)
453 if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) && 457 if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
454 (conn->received_pos >= 458 (conn->received_pos >=
455 ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)-> 459 ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)->
456 size))) 460 size)))
457 conn->msg_complete = GNUNET_YES; 461 conn->msg_complete = GNUNET_YES;
458} 462}
459 463
@@ -472,7 +476,7 @@ check_complete (struct GNUNET_CLIENT_Connection *conn)
472 */ 476 */
473static void 477static void
474receive_helper (void *cls, const void *buf, size_t available, 478receive_helper (void *cls, const void *buf, size_t available,
475 const struct sockaddr *addr, socklen_t addrlen, int errCode) 479 const struct sockaddr *addr, socklen_t addrlen, int errCode)
476{ 480{
477 struct GNUNET_CLIENT_Connection *conn = cls; 481 struct GNUNET_CLIENT_Connection *conn = cls;
478 struct GNUNET_TIME_Relative remaining; 482 struct GNUNET_TIME_Relative remaining;
@@ -482,22 +486,22 @@ receive_helper (void *cls, const void *buf, size_t available,
482 GNUNET_assert (conn->msg_complete == GNUNET_NO); 486 GNUNET_assert (conn->msg_complete == GNUNET_NO);
483 conn->in_receive = GNUNET_NO; 487 conn->in_receive = GNUNET_NO;
484 if ((available == 0) || (conn->sock == NULL) || (errCode != 0)) 488 if ((available == 0) || (conn->sock == NULL) || (errCode != 0))
485 { 489 {
486 /* signal timeout! */ 490 /* signal timeout! */
487#if DEBUG_CLIENT 491#if DEBUG_CLIENT
488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 492 LOG (GNUNET_ERROR_TYPE_DEBUG,
489 "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n", 493 "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n",
490 (unsigned int) available, 494 (unsigned int) available,
491 conn->sock == NULL ? "NULL" : "non-NULL", STRERROR (errCode)); 495 conn->sock == NULL ? "NULL" : "non-NULL", STRERROR (errCode));
492#endif 496#endif
493 if (NULL != (receive_handler = conn->receiver_handler)) 497 if (NULL != (receive_handler = conn->receiver_handler))
494 { 498 {
495 receive_handler_cls = conn->receiver_handler_cls; 499 receive_handler_cls = conn->receiver_handler_cls;
496 conn->receiver_handler = NULL; 500 conn->receiver_handler = NULL;
497 receive_handler (receive_handler_cls, NULL); 501 receive_handler (receive_handler_cls, NULL);
502 }
503 return;
498 } 504 }
499 return;
500 }
501 505
502 /* FIXME: optimize for common fast case where buf contains the 506 /* FIXME: optimize for common fast case where buf contains the
503 * entire message and we need no copying... */ 507 * entire message and we need no copying... */
@@ -506,22 +510,22 @@ receive_helper (void *cls, const void *buf, size_t available,
506 /* slow path: append to array */ 510 /* slow path: append to array */
507 if (conn->received_size < conn->received_pos + available) 511 if (conn->received_size < conn->received_pos + available)
508 GNUNET_array_grow (conn->received_buf, conn->received_size, 512 GNUNET_array_grow (conn->received_buf, conn->received_size,
509 conn->received_pos + available); 513 conn->received_pos + available);
510 memcpy (&conn->received_buf[conn->received_pos], buf, available); 514 memcpy (&conn->received_buf[conn->received_pos], buf, available);
511 conn->received_pos += available; 515 conn->received_pos += available;
512 check_complete (conn); 516 check_complete (conn);
513 /* check for timeout */ 517 /* check for timeout */
514 remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout); 518 remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout);
515 if (remaining.rel_value == 0) 519 if (remaining.rel_value == 0)
516 { 520 {
517 /* signal timeout! */ 521 /* signal timeout! */
518 if (NULL != conn->receiver_handler) 522 if (NULL != conn->receiver_handler)
519 conn->receiver_handler (conn->receiver_handler_cls, NULL); 523 conn->receiver_handler (conn->receiver_handler_cls, NULL);
520 return; 524 return;
521 } 525 }
522 /* back to receive -- either for more data or to call callback! */ 526 /* back to receive -- either for more data or to call callback! */
523 GNUNET_CLIENT_receive (conn, conn->receiver_handler, 527 GNUNET_CLIENT_receive (conn, conn->receiver_handler,
524 conn->receiver_handler_cls, remaining); 528 conn->receiver_handler_cls, remaining);
525} 529}
526 530
527 531
@@ -537,23 +541,23 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
537 struct GNUNET_CLIENT_Connection *sock = cls; 541 struct GNUNET_CLIENT_Connection *sock = cls;
538 GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler; 542 GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler;
539 const struct GNUNET_MessageHeader *cmsg = 543 const struct GNUNET_MessageHeader *cmsg =
540 (const struct GNUNET_MessageHeader *) sock->received_buf; 544 (const struct GNUNET_MessageHeader *) sock->received_buf;
541 void *handler_cls = sock->receiver_handler_cls; 545 void *handler_cls = sock->receiver_handler_cls;
542 uint16_t msize = ntohs (cmsg->size); 546 uint16_t msize = ntohs (cmsg->size);
543 char mbuf[msize]; 547 char mbuf[msize];
544 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf; 548 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf;
545 549
546#if DEBUG_CLIENT 550#if DEBUG_CLIENT
547 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 551 LOG (GNUNET_ERROR_TYPE_DEBUG,
548 "Received message of type %u and size %u\n", ntohs (cmsg->type), 552 "Received message of type %u and size %u\n", ntohs (cmsg->type),
549 msize); 553 msize);
550#endif 554#endif
551 sock->receive_task = GNUNET_SCHEDULER_NO_TASK; 555 sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
552 GNUNET_assert (GNUNET_YES == sock->msg_complete); 556 GNUNET_assert (GNUNET_YES == sock->msg_complete);
553 GNUNET_assert (sock->received_pos >= msize); 557 GNUNET_assert (sock->received_pos >= msize);
554 memcpy (msg, cmsg, msize); 558 memcpy (msg, cmsg, msize);
555 memmove (sock->received_buf, &sock->received_buf[msize], 559 memmove (sock->received_buf, &sock->received_buf[msize],
556 sock->received_pos - msize); 560 sock->received_pos - msize);
557 sock->received_pos -= msize; 561 sock->received_pos -= msize;
558 sock->msg_complete = GNUNET_NO; 562 sock->msg_complete = GNUNET_NO;
559 sock->receiver_handler = NULL; 563 sock->receiver_handler = NULL;
@@ -573,35 +577,36 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
573 */ 577 */
574void 578void
575GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, 579GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
576 GNUNET_CLIENT_MessageHandler handler, void *handler_cls, 580 GNUNET_CLIENT_MessageHandler handler,
577 struct GNUNET_TIME_Relative timeout) 581 void *handler_cls, struct GNUNET_TIME_Relative timeout)
578{ 582{
579 if (sock->sock == NULL) 583 if (sock->sock == NULL)
580 { 584 {
581 /* already disconnected, fail instantly! */ 585 /* already disconnected, fail instantly! */
582 GNUNET_break (0); /* this should not happen in well-written code! */ 586 GNUNET_break (0); /* this should not happen in well-written code! */
583 if (NULL != handler) 587 if (NULL != handler)
584 handler (handler_cls, NULL); 588 handler (handler_cls, NULL);
585 return; 589 return;
586 } 590 }
587 sock->receiver_handler = handler; 591 sock->receiver_handler = handler;
588 sock->receiver_handler_cls = handler_cls; 592 sock->receiver_handler_cls = handler_cls;
589 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); 593 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
590 if (GNUNET_YES == sock->msg_complete) 594 if (GNUNET_YES == sock->msg_complete)
591 { 595 {
592 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task); 596 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task);
593 sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock); 597 sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock);
594 } 598 }
595 else 599 else
596 { 600 {
597 GNUNET_assert (sock->in_receive == GNUNET_NO); 601 GNUNET_assert (sock->in_receive == GNUNET_NO);
598 sock->in_receive = GNUNET_YES; 602 sock->in_receive = GNUNET_YES;
599#if DEBUG_CLIENT 603#if DEBUG_CLIENT
600 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n"); 604 LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n");
601#endif 605#endif
602 GNUNET_CONNECTION_receive (sock->sock, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 606 GNUNET_CONNECTION_receive (sock->sock,
603 timeout, &receive_helper, sock); 607 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, timeout,
604 } 608 &receive_helper, sock);
609 }
605} 610}
606 611
607 612
@@ -612,7 +617,7 @@ static void
612service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) 617service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls)
613{ 618{
614 GNUNET_SCHEDULER_add_continuation (task, task_cls, 619 GNUNET_SCHEDULER_add_continuation (task, task_cls,
615 GNUNET_SCHEDULER_REASON_TIMEOUT); 620 GNUNET_SCHEDULER_REASON_TIMEOUT);
616} 621}
617 622
618 623
@@ -631,18 +636,18 @@ confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
631 * detail in the future, for example, is this the 636 * detail in the future, for example, is this the
632 * correct service? FIXME! */ 637 * correct service? FIXME! */
633 if (msg != NULL) 638 if (msg != NULL)
634 { 639 {
635#if DEBUG_CLIENT 640#if DEBUG_CLIENT
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 641 LOG (GNUNET_ERROR_TYPE_DEBUG,
637 "Received confirmation that service is running.\n"); 642 "Received confirmation that service is running.\n");
638#endif 643#endif
639 GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls, 644 GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls,
640 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 645 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
641 } 646 }
642 else 647 else
643 { 648 {
644 service_test_error (conn->test_cb, conn->test_cb_cls); 649 service_test_error (conn->test_cb, conn->test_cb_cls);
645 } 650 }
646 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 651 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
647} 652}
648 653
@@ -663,24 +668,23 @@ write_test (void *cls, size_t size, void *buf)
663 struct GNUNET_MessageHeader *msg; 668 struct GNUNET_MessageHeader *msg;
664 669
665 if (size < sizeof (struct GNUNET_MessageHeader)) 670 if (size < sizeof (struct GNUNET_MessageHeader))
666 { 671 {
667#if DEBUG_CLIENT 672#if DEBUG_CLIENT
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 673 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n"));
669 _("Failure to transmit TEST request.\n"));
670#endif 674#endif
671 service_test_error (conn->test_cb, conn->test_cb_cls); 675 service_test_error (conn->test_cb, conn->test_cb_cls);
672 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 676 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
673 return 0; /* client disconnected */ 677 return 0; /* client disconnected */
674 } 678 }
675#if DEBUG_CLIENT 679#if DEBUG_CLIENT
676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST"); 680 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST");
677#endif 681#endif
678 msg = (struct GNUNET_MessageHeader *) buf; 682 msg = (struct GNUNET_MessageHeader *) buf;
679 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); 683 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
680 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 684 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
681 GNUNET_CLIENT_receive (conn, &confirm_handler, conn, 685 GNUNET_CLIENT_receive (conn, &confirm_handler, conn,
682 GNUNET_TIME_absolute_get_remaining 686 GNUNET_TIME_absolute_get_remaining
683 (conn->test_deadline)); 687 (conn->test_deadline));
684 return sizeof (struct GNUNET_MessageHeader); 688 return sizeof (struct GNUNET_MessageHeader);
685} 689}
686 690
@@ -700,9 +704,9 @@ write_test (void *cls, size_t size, void *buf)
700 */ 704 */
701void 705void
702GNUNET_CLIENT_service_test (const char *service, 706GNUNET_CLIENT_service_test (const char *service,
703 const struct GNUNET_CONFIGURATION_Handle *cfg, 707 const struct GNUNET_CONFIGURATION_Handle *cfg,
704 struct GNUNET_TIME_Relative timeout, 708 struct GNUNET_TIME_Relative timeout,
705 GNUNET_SCHEDULER_Task task, void *task_cls) 709 GNUNET_SCHEDULER_Task task, void *task_cls)
706{ 710{
707 char *hostname; 711 char *hostname;
708 unsigned long long port; 712 unsigned long long port;
@@ -710,8 +714,8 @@ GNUNET_CLIENT_service_test (const char *service,
710 struct GNUNET_CLIENT_Connection *conn; 714 struct GNUNET_CLIENT_Connection *conn;
711 715
712#if DEBUG_CLIENT 716#if DEBUG_CLIENT
713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n", 717 LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n",
714 service); 718 service);
715#endif 719#endif
716#ifdef AF_UNIX 720#ifdef AF_UNIX
717 { 721 {
@@ -721,49 +725,50 @@ GNUNET_CLIENT_service_test (const char *service,
721 char *unixpath; 725 char *unixpath;
722 726
723 unixpath = NULL; 727 unixpath = NULL;
724 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */ 728 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */
725 {
726 if (strlen (unixpath) >= sizeof (s_un.sun_path))
727 { 729 {
728 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 730 if (strlen (unixpath) >= sizeof (s_un.sun_path))
729 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 731 {
730 unixpath, sizeof (s_un.sun_path)); 732 LOG (GNUNET_ERROR_TYPE_WARNING,
731 } 733 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
732 else 734 unixpath, sizeof (s_un.sun_path));
733 { 735 }
734 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); 736 else
735 if (sock != NULL) 737 {
736 { 738 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
737 memset (&s_un, 0, sizeof (s_un)); 739 if (sock != NULL)
738 s_un.sun_family = AF_UNIX; 740 {
739 slen = strlen (unixpath) + 1; 741 memset (&s_un, 0, sizeof (s_un));
740 if (slen >= sizeof (s_un.sun_path)) 742 s_un.sun_family = AF_UNIX;
741 slen = sizeof (s_un.sun_path) - 1; 743 slen = strlen (unixpath) + 1;
742 memcpy (s_un.sun_path, unixpath, slen); 744 if (slen >= sizeof (s_un.sun_path))
743 s_un.sun_path[slen] = '\0'; 745 slen = sizeof (s_un.sun_path) - 1;
744 slen = sizeof (struct sockaddr_un); 746 memcpy (s_un.sun_path, unixpath, slen);
747 s_un.sun_path[slen] = '\0';
748 slen = sizeof (struct sockaddr_un);
745#if LINUX 749#if LINUX
746 s_un.sun_path[0] = '\0'; 750 s_un.sun_path[0] = '\0';
747#endif 751#endif
748#if HAVE_SOCKADDR_IN_SIN_LEN 752#if HAVE_SOCKADDR_IN_SIN_LEN
749 s_un.sun_len = (u_char) slen; 753 s_un.sun_len = (u_char) slen;
750#endif 754#endif
751 if (GNUNET_OK != 755 if (GNUNET_OK !=
752 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un, 756 GNUNET_NETWORK_socket_bind (sock,
753 slen)) 757 (const struct sockaddr *)
754 { 758 &s_un, slen))
755 /* failed to bind => service must be running */ 759 {
756 GNUNET_free (unixpath); 760 /* failed to bind => service must be running */
757 (void) GNUNET_NETWORK_socket_close (sock); 761 GNUNET_free (unixpath);
758 GNUNET_SCHEDULER_add_continuation (task, task_cls, 762 (void) GNUNET_NETWORK_socket_close (sock);
759 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 763 GNUNET_SCHEDULER_add_continuation (task, task_cls,
760 return; 764 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
761 } 765 return;
762 (void) GNUNET_NETWORK_socket_close (sock); 766 }
763 } 767 (void) GNUNET_NETWORK_socket_close (sock);
764 /* let's try IP */ 768 }
769 /* let's try IP */
770 }
765 } 771 }
766 }
767 GNUNET_free_non_null (unixpath); 772 GNUNET_free_non_null (unixpath);
768 } 773 }
769#endif 774#endif
@@ -774,121 +779,124 @@ GNUNET_CLIENT_service_test (const char *service,
774 (port > 65535) || 779 (port > 65535) ||
775 (GNUNET_OK != 780 (GNUNET_OK !=
776 GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME", 781 GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
777 &hostname))) 782 &hostname)))
778 { 783 {
779 /* UNIXPATH failed (if possible) AND IP failed => error */ 784 /* UNIXPATH failed (if possible) AND IP failed => error */
780 service_test_error (task, task_cls); 785 service_test_error (task, task_cls);
781 return; 786 return;
782 } 787 }
783 788
784 if (0 == strcmp ("localhost", hostname) 789 if (0 == strcmp ("localhost", hostname)
785#if !LINUX 790#if !LINUX
786 && 0 791 && 0
787#endif 792#endif
788 ) 793 )
789 { 794 {
790 /* can test using 'bind' */ 795 /* can test using 'bind' */
791 struct sockaddr_in s_in; 796 struct sockaddr_in s_in;
792 797
793 memset (&s_in, 0, sizeof (s_in)); 798 memset (&s_in, 0, sizeof (s_in));
794#if HAVE_SOCKADDR_IN_SIN_LEN 799#if HAVE_SOCKADDR_IN_SIN_LEN
795 s_in.sin_len = sizeof (struct sockaddr_in); 800 s_in.sin_len = sizeof (struct sockaddr_in);
796#endif 801#endif
797 s_in.sin_family = AF_INET; 802 s_in.sin_family = AF_INET;
798 s_in.sin_port = htons (port); 803 s_in.sin_port = htons (port);
799 804
800 sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); 805 sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
801 if (sock != NULL) 806 if (sock != NULL)
802 { 807 {
803 if (GNUNET_OK != 808 if (GNUNET_OK !=
804 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in, 809 GNUNET_NETWORK_socket_bind (sock,
805 sizeof (s_in))) 810 (const struct sockaddr *) &s_in,
806 { 811 sizeof (s_in)))
807 /* failed to bind => service must be running */ 812 {
808 GNUNET_free (hostname); 813 /* failed to bind => service must be running */
809 (void) GNUNET_NETWORK_socket_close (sock); 814 GNUNET_free (hostname);
810 GNUNET_SCHEDULER_add_continuation (task, task_cls, 815 (void) GNUNET_NETWORK_socket_close (sock);
811 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 816 GNUNET_SCHEDULER_add_continuation (task, task_cls,
812 return; 817 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
813 } 818 return;
814 (void) GNUNET_NETWORK_socket_close (sock); 819 }
820 (void) GNUNET_NETWORK_socket_close (sock);
821 }
815 } 822 }
816 }
817 823
818 if (0 == strcmp ("ip6-localhost", hostname) 824 if (0 == strcmp ("ip6-localhost", hostname)
819#if !LINUX 825#if !LINUX
820 && 0 826 && 0
821#endif 827#endif
822 ) 828 )
823 { 829 {
824 /* can test using 'bind' */ 830 /* can test using 'bind' */
825 struct sockaddr_in6 s_in6; 831 struct sockaddr_in6 s_in6;
826 832
827 memset (&s_in6, 0, sizeof (s_in6)); 833 memset (&s_in6, 0, sizeof (s_in6));
828#if HAVE_SOCKADDR_IN_SIN_LEN 834#if HAVE_SOCKADDR_IN_SIN_LEN
829 s_in6.sin6_len = sizeof (struct sockaddr_in6); 835 s_in6.sin6_len = sizeof (struct sockaddr_in6);
830#endif 836#endif
831 s_in6.sin6_family = AF_INET6; 837 s_in6.sin6_family = AF_INET6;
832 s_in6.sin6_port = htons (port); 838 s_in6.sin6_port = htons (port);
833 839
834 sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); 840 sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
835 if (sock != NULL) 841 if (sock != NULL)
836 { 842 {
837 if (GNUNET_OK != 843 if (GNUNET_OK !=
838 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6, 844 GNUNET_NETWORK_socket_bind (sock,
839 sizeof (s_in6))) 845 (const struct sockaddr *) &s_in6,
840 { 846 sizeof (s_in6)))
841 /* failed to bind => service must be running */ 847 {
842 GNUNET_free (hostname); 848 /* failed to bind => service must be running */
843 (void) GNUNET_NETWORK_socket_close (sock); 849 GNUNET_free (hostname);
844 GNUNET_SCHEDULER_add_continuation (task, task_cls, 850 (void) GNUNET_NETWORK_socket_close (sock);
845 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 851 GNUNET_SCHEDULER_add_continuation (task, task_cls,
846 return; 852 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
847 } 853 return;
848 (void) GNUNET_NETWORK_socket_close (sock); 854 }
855 (void) GNUNET_NETWORK_socket_close (sock);
856 }
849 } 857 }
850 }
851 858
852 if (((0 == strcmp ("localhost", hostname)) || 859 if (((0 == strcmp ("localhost", hostname)) ||
853 (0 == strcmp ("ip6-localhost", hostname))) 860 (0 == strcmp ("ip6-localhost", hostname)))
854#if !LINUX 861#if !LINUX
855 && 0 862 && 0
856#endif 863#endif
857 ) 864 )
858 { 865 {
859 /* all binds succeeded => claim service not running right now */ 866 /* all binds succeeded => claim service not running right now */
860 GNUNET_free_non_null (hostname); 867 GNUNET_free_non_null (hostname);
861 service_test_error (task, task_cls); 868 service_test_error (task, task_cls);
862 return; 869 return;
863 } 870 }
864 GNUNET_free_non_null (hostname); 871 GNUNET_free_non_null (hostname);
865 872
866 /* non-localhost, try 'connect' method */ 873 /* non-localhost, try 'connect' method */
867 conn = GNUNET_CLIENT_connect (service, cfg); 874 conn = GNUNET_CLIENT_connect (service, cfg);
868 if (conn == NULL) 875 if (conn == NULL)
869 { 876 {
870 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 877 LOG (GNUNET_ERROR_TYPE_INFO,
871 _("Could not connect to service `%s', must not be running.\n"), 878 _("Could not connect to service `%s', must not be running.\n"),
872 service); 879 service);
873 service_test_error (task, task_cls); 880 service_test_error (task, task_cls);
874 return; 881 return;
875 } 882 }
876 conn->test_cb = task; 883 conn->test_cb = task;
877 conn->test_cb_cls = task_cls; 884 conn->test_cb_cls = task_cls;
878 conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); 885 conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
879 886
880 if (NULL == 887 if (NULL ==
881 GNUNET_CLIENT_notify_transmit_ready (conn, 888 GNUNET_CLIENT_notify_transmit_ready (conn,
882 sizeof (struct GNUNET_MessageHeader), 889 sizeof (struct
883 timeout, GNUNET_YES, &write_test, 890 GNUNET_MessageHeader),
884 conn)) 891 timeout, GNUNET_YES, &write_test,
885 { 892 conn))
886 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 893 {
887 _("Failure to transmit request to service `%s'\n"), service); 894 LOG (GNUNET_ERROR_TYPE_WARNING,
888 service_test_error (task, task_cls); 895 _("Failure to transmit request to service `%s'\n"), service);
889 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 896 service_test_error (task, task_cls);
890 return; 897 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
891 } 898 return;
899 }
892} 900}
893 901
894 902
@@ -902,8 +910,7 @@ GNUNET_CLIENT_service_test (const char *service,
902 * @param buf where to write them 910 * @param buf where to write them
903 * @return number of bytes written to buf 911 * @return number of bytes written to buf
904 */ 912 */
905static size_t 913static size_t client_notify (void *cls, size_t size, void *buf);
906client_notify (void *cls, size_t size, void *buf);
907 914
908 915
909/** 916/**
@@ -914,59 +921,60 @@ client_notify (void *cls, size_t size, void *buf);
914 * @param tc unused 921 * @param tc unused
915 */ 922 */
916static void 923static void
917client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 924client_delayed_retry (void *cls,
925 const struct GNUNET_SCHEDULER_TaskContext *tc)
918{ 926{
919 struct GNUNET_CLIENT_TransmitHandle *th = cls; 927 struct GNUNET_CLIENT_TransmitHandle *th = cls;
920 struct GNUNET_TIME_Relative delay; 928 struct GNUNET_TIME_Relative delay;
921 929
922 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 930 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
923 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 931 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
924 { 932 {
925#if DEBUG_CLIENT 933#if DEBUG_CLIENT
926 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 934 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n");
927 "Transmission failed due to shutdown.\n");
928#endif 935#endif
929 th->sock->th = NULL; 936 th->sock->th = NULL;
930 th->notify (th->notify_cls, 0, NULL); 937 th->notify (th->notify_cls, 0, NULL);
931 GNUNET_free (th); 938 GNUNET_free (th);
932 return; 939 return;
933 } 940 }
934 th->sock->sock = 941 th->sock->sock =
935 do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++); 942 do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++);
936 if (NULL == th->sock->sock) 943 if (NULL == th->sock->sock)
937 { 944 {
938 /* could happen if we're out of sockets */ 945 /* could happen if we're out of sockets */
939 delay = 946 delay =
940 GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining 947 GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining
941 (th->timeout), th->sock->back_off); 948 (th->timeout), th->sock->back_off);
942 th->sock->back_off = 949 th->sock->back_off =
943 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply 950 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
944 (th->sock->back_off, 2), 951 (th->sock->back_off, 2),
945 GNUNET_TIME_UNIT_SECONDS); 952 GNUNET_TIME_UNIT_SECONDS);
946#if DEBUG_CLIENT 953#if DEBUG_CLIENT
947 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 954 LOG (GNUNET_ERROR_TYPE_DEBUG,
948 "Transmission failed %u times, trying again in %llums.\n", 955 "Transmission failed %u times, trying again in %llums.\n",
949 MAX_ATTEMPTS - th->attempts_left, 956 MAX_ATTEMPTS - th->attempts_left,
950 (unsigned long long) delay.rel_value); 957 (unsigned long long) delay.rel_value);
951#endif 958#endif
952 th->reconnect_task = 959 th->reconnect_task =
953 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); 960 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
954 return; 961 return;
955 } 962 }
956 GNUNET_CONNECTION_ignore_shutdown (th->sock->sock, th->sock->ignore_shutdown); 963 GNUNET_CONNECTION_ignore_shutdown (th->sock->sock,
964 th->sock->ignore_shutdown);
957 th->th = 965 th->th =
958 GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size, 966 GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size,
959 GNUNET_TIME_absolute_get_remaining 967 GNUNET_TIME_absolute_get_remaining
960 (th->timeout), &client_notify, 968 (th->timeout), &client_notify,
961 th); 969 th);
962 if (th->th == NULL) 970 if (th->th == NULL)
963 { 971 {
964 GNUNET_break (0); 972 GNUNET_break (0);
965 th->sock->th = NULL; 973 th->sock->th = NULL;
966 th->notify (th->notify_cls, 0, NULL); 974 th->notify (th->notify_cls, 0, NULL);
967 GNUNET_free (th); 975 GNUNET_free (th);
968 return; 976 return;
969 } 977 }
970} 978}
971 979
972 980
@@ -989,47 +997,47 @@ client_notify (void *cls, size_t size, void *buf)
989 th->th = NULL; 997 th->th = NULL;
990 th->sock->th = NULL; 998 th->sock->th = NULL;
991 if (buf == NULL) 999 if (buf == NULL)
992 {
993 delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
994 delay.rel_value /= 2;
995 if ((0 !=
996 (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) ||
997 (GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) ||
998 (delay.rel_value < 1))
999 { 1000 {
1001 delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
1002 delay.rel_value /= 2;
1003 if ((0 !=
1004 (GNUNET_SCHEDULER_REASON_SHUTDOWN &
1005 GNUNET_SCHEDULER_get_reason ())) || (GNUNET_YES != th->auto_retry)
1006 || (0 == --th->attempts_left) || (delay.rel_value < 1))
1007 {
1000#if DEBUG_CLIENT 1008#if DEBUG_CLIENT
1001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1009 LOG (GNUNET_ERROR_TYPE_DEBUG,
1002 "Transmission failed %u times, giving up.\n", 1010 "Transmission failed %u times, giving up.\n",
1003 MAX_ATTEMPTS - th->attempts_left); 1011 MAX_ATTEMPTS - th->attempts_left);
1004#endif 1012#endif
1005 GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL)); 1013 GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
1006 GNUNET_free (th); 1014 GNUNET_free (th);
1007 return 0; 1015 return 0;
1008 } 1016 }
1009 /* auto-retry */ 1017 /* auto-retry */
1010#if DEBUG_CLIENT 1018#if DEBUG_CLIENT
1011 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1019 LOG (GNUNET_ERROR_TYPE_DEBUG,
1012 "Failed to connect to `%s', automatically trying again.\n", 1020 "Failed to connect to `%s', automatically trying again.\n",
1013 th->sock->service_name); 1021 th->sock->service_name);
1014#endif 1022#endif
1015 GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); 1023 GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO);
1016 th->sock->sock = NULL; 1024 th->sock->sock = NULL;
1017 delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); 1025 delay = GNUNET_TIME_relative_min (delay, th->sock->back_off);
1018 th->sock->back_off = 1026 th->sock->back_off =
1019 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply 1027 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
1020 (th->sock->back_off, 2), 1028 (th->sock->back_off, 2),
1021 GNUNET_TIME_UNIT_SECONDS); 1029 GNUNET_TIME_UNIT_SECONDS);
1022#if DEBUG_CLIENT 1030#if DEBUG_CLIENT
1023 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1031 LOG (GNUNET_ERROR_TYPE_DEBUG,
1024 "Transmission failed %u times, trying again in %llums.\n", 1032 "Transmission failed %u times, trying again in %llums.\n",
1025 MAX_ATTEMPTS - th->attempts_left, 1033 MAX_ATTEMPTS - th->attempts_left,
1026 (unsigned long long) delay.rel_value); 1034 (unsigned long long) delay.rel_value);
1027#endif 1035#endif
1028 th->sock->th = th; 1036 th->sock->th = th;
1029 th->reconnect_task = 1037 th->reconnect_task =
1030 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); 1038 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
1031 return 0; 1039 return 0;
1032 } 1040 }
1033 GNUNET_assert (size >= th->size); 1041 GNUNET_assert (size >= th->size);
1034 ret = th->notify (th->notify_cls, size, buf); 1042 ret = th->notify (th->notify_cls, size, buf);
1035 GNUNET_free (th); 1043 GNUNET_free (th);
@@ -1058,21 +1066,21 @@ client_notify (void *cls, size_t size, void *buf)
1058 */ 1066 */
1059struct GNUNET_CLIENT_TransmitHandle * 1067struct GNUNET_CLIENT_TransmitHandle *
1060GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, 1068GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1061 size_t size, 1069 size_t size,
1062 struct GNUNET_TIME_Relative timeout, 1070 struct GNUNET_TIME_Relative timeout,
1063 int auto_retry, 1071 int auto_retry,
1064 GNUNET_CONNECTION_TransmitReadyNotify 1072 GNUNET_CONNECTION_TransmitReadyNotify
1065 notify, void *notify_cls) 1073 notify, void *notify_cls)
1066{ 1074{
1067 struct GNUNET_CLIENT_TransmitHandle *th; 1075 struct GNUNET_CLIENT_TransmitHandle *th;
1068 1076
1069 if (NULL != sock->th) 1077 if (NULL != sock->th)
1070 { 1078 {
1071 /* If this breaks, you most likley called this function twice without waiting 1079 /* If this breaks, you most likley called this function twice without waiting
1072 * for completion or canceling the request */ 1080 * for completion or canceling the request */
1073 GNUNET_break (0); 1081 GNUNET_break (0);
1074 return NULL; 1082 return NULL;
1075 } 1083 }
1076 th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); 1084 th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
1077 th->sock = sock; 1085 th->sock = sock;
1078 th->size = size; 1086 th->size = size;
@@ -1083,25 +1091,25 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1083 th->attempts_left = MAX_ATTEMPTS; 1091 th->attempts_left = MAX_ATTEMPTS;
1084 sock->th = th; 1092 sock->th = th;
1085 if (sock->sock == NULL) 1093 if (sock->sock == NULL)
1086 { 1094 {
1087 th->reconnect_task = 1095 th->reconnect_task =
1088 GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry, 1096 GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry,
1089 th); 1097 th);
1090 1098
1091 } 1099 }
1092 else 1100 else
1093 {
1094 th->th =
1095 GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout,
1096 &client_notify, th);
1097 if (NULL == th->th)
1098 { 1101 {
1099 GNUNET_break (0); 1102 th->th =
1100 GNUNET_free (th); 1103 GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout,
1101 sock->th = NULL; 1104 &client_notify, th);
1102 return NULL; 1105 if (NULL == th->th)
1106 {
1107 GNUNET_break (0);
1108 GNUNET_free (th);
1109 sock->th = NULL;
1110 return NULL;
1111 }
1103 } 1112 }
1104 }
1105 return th; 1113 return th;
1106} 1114}
1107 1115
@@ -1112,20 +1120,20 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1112 * @param th handle from the original request. 1120 * @param th handle from the original request.
1113 */ 1121 */
1114void 1122void
1115GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle 1123GNUNET_CLIENT_notify_transmit_ready_cancel (struct
1116 *th) 1124 GNUNET_CLIENT_TransmitHandle *th)
1117{ 1125{
1118 if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 1126 if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
1119 { 1127 {
1120 GNUNET_assert (NULL == th->th); 1128 GNUNET_assert (NULL == th->th);
1121 GNUNET_SCHEDULER_cancel (th->reconnect_task); 1129 GNUNET_SCHEDULER_cancel (th->reconnect_task);
1122 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 1130 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1123 } 1131 }
1124 else 1132 else
1125 { 1133 {
1126 GNUNET_assert (NULL != th->th); 1134 GNUNET_assert (NULL != th->th);
1127 GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); 1135 GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th);
1128 } 1136 }
1129 th->sock->th = NULL; 1137 th->sock->th = NULL;
1130 GNUNET_free (th); 1138 GNUNET_free (th);
1131} 1139}
@@ -1151,21 +1159,21 @@ transmit_for_response (void *cls, size_t size, void *buf)
1151 tc->sock->tag = NULL; 1159 tc->sock->tag = NULL;
1152 msize = ntohs (tc->hdr->size); 1160 msize = ntohs (tc->hdr->size);
1153 if (NULL == buf) 1161 if (NULL == buf)
1154 { 1162 {
1155#if DEBUG_CLIENT 1163#if DEBUG_CLIENT
1156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1164 LOG (GNUNET_ERROR_TYPE_DEBUG,
1157 _ 1165 _
1158 ("Could not submit request, not expecting to receive a response.\n")); 1166 ("Could not submit request, not expecting to receive a response.\n"));
1159#endif 1167#endif
1160 if (NULL != tc->rn) 1168 if (NULL != tc->rn)
1161 tc->rn (tc->rn_cls, NULL); 1169 tc->rn (tc->rn_cls, NULL);
1162 GNUNET_free (tc); 1170 GNUNET_free (tc);
1163 return 0; 1171 return 0;
1164 } 1172 }
1165 GNUNET_assert (size >= msize); 1173 GNUNET_assert (size >= msize);
1166 memcpy (buf, tc->hdr, msize); 1174 memcpy (buf, tc->hdr, msize);
1167 GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls, 1175 GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls,
1168 GNUNET_TIME_absolute_get_remaining (tc->timeout)); 1176 GNUNET_TIME_absolute_get_remaining (tc->timeout));
1169 GNUNET_free (tc); 1177 GNUNET_free (tc);
1170 return msize; 1178 return msize;
1171} 1179}
@@ -1193,12 +1201,14 @@ transmit_for_response (void *cls, size_t size, void *buf)
1193 * is already pending 1201 * is already pending
1194 */ 1202 */
1195int 1203int
1196GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, 1204GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection
1197 const struct GNUNET_MessageHeader *hdr, 1205 *sock,
1198 struct GNUNET_TIME_Relative timeout, 1206 const struct GNUNET_MessageHeader
1199 int auto_retry, 1207 *hdr,
1200 GNUNET_CLIENT_MessageHandler rn, 1208 struct GNUNET_TIME_Relative timeout,
1201 void *rn_cls) 1209 int auto_retry,
1210 GNUNET_CLIENT_MessageHandler rn,
1211 void *rn_cls)
1202{ 1212{
1203 struct TransmitGetResponseContext *tc; 1213 struct TransmitGetResponseContext *tc;
1204 uint16_t msize; 1214 uint16_t msize;
@@ -1216,12 +1226,12 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
1216 tc->rn_cls = rn_cls; 1226 tc->rn_cls = rn_cls;
1217 if (NULL == 1227 if (NULL ==
1218 GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry, 1228 GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry,
1219 &transmit_for_response, tc)) 1229 &transmit_for_response, tc))
1220 { 1230 {
1221 GNUNET_break (0); 1231 GNUNET_break (0);
1222 GNUNET_free (tc); 1232 GNUNET_free (tc);
1223 return GNUNET_SYSERR; 1233 return GNUNET_SYSERR;
1224 } 1234 }
1225 sock->tag = tc; 1235 sock->tag = tc;
1226 return GNUNET_OK; 1236 return GNUNET_OK;
1227} 1237}