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.c804
1 files changed, 396 insertions, 408 deletions
diff --git a/src/util/client.c b/src/util/client.c
index d2f347947..e71ccdf39 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -259,8 +259,7 @@ struct GNUNET_CLIENT_Connection
259 */ 259 */
260static struct GNUNET_CONNECTION_Handle * 260static struct GNUNET_CONNECTION_Handle *
261do_connect (const char *service_name, 261do_connect (const char *service_name,
262 const struct GNUNET_CONFIGURATION_Handle *cfg, 262 const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt)
263 unsigned int attempt)
264{ 263{
265 struct GNUNET_CONNECTION_Handle *sock; 264 struct GNUNET_CONNECTION_Handle *sock;
266 char *hostname; 265 char *hostname;
@@ -270,80 +269,78 @@ do_connect (const char *service_name,
270 sock = NULL; 269 sock = NULL;
271#if AF_UNIX 270#if AF_UNIX
272 if (0 == (attempt % 2)) 271 if (0 == (attempt % 2))
272 {
273 /* on even rounds, try UNIX */
274 unixpath = NULL;
275 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? */
273 { 276 {
274 /* on even rounds, try UNIX */ 277 sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
275 unixpath = NULL; 278 if (sock != NULL)
276 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 {
277 {
278 sock =
279 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
280 if (sock != NULL)
281 {
282#if DEBUG_CLIENT 280#if DEBUG_CLIENT
283 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", 281 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n",
284 unixpath); 282 unixpath);
285#endif 283#endif
286 GNUNET_free (unixpath); 284 GNUNET_free (unixpath);
287 return sock; 285 return sock;
288 } 286 }
289 }
290 GNUNET_free_non_null (unixpath);
291 } 287 }
288 GNUNET_free_non_null (unixpath);
289 }
292#endif 290#endif
293 291
294 if ((GNUNET_OK != 292 if ((GNUNET_OK !=
295 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", 293 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port))
296 &port)) || (port > 65535) 294 || (port > 65535) ||
297 || (GNUNET_OK != 295 (GNUNET_OK !=
298 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, 296 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME",
299 "HOSTNAME", &hostname))) 297 &hostname)))
300 { 298 {
301 LOG (GNUNET_ERROR_TYPE_WARNING, 299 LOG (GNUNET_ERROR_TYPE_WARNING,
302 _ 300 _
303 ("Could not determine valid hostname and port for service `%s' from configuration.\n"), 301 ("Could not determine valid hostname and port for service `%s' from configuration.\n"),
304 service_name); 302 service_name);
305 return NULL; 303 return NULL;
306 } 304 }
307 if (0 == strlen (hostname)) 305 if (0 == strlen (hostname))
308 { 306 {
309 GNUNET_free (hostname); 307 GNUNET_free (hostname);
310 LOG (GNUNET_ERROR_TYPE_WARNING, 308 LOG (GNUNET_ERROR_TYPE_WARNING,
311 _("Need a non-empty hostname for service `%s'.\n"), service_name); 309 _("Need a non-empty hostname for service `%s'.\n"), service_name);
312 return NULL; 310 return NULL;
313 } 311 }
314 if (port == 0) 312 if (port == 0)
315 { 313 {
316#if AF_UNIX 314#if AF_UNIX
317 if (0 != (attempt % 2)) 315 if (0 != (attempt % 2))
318 { 316 {
319 /* try UNIX */ 317 /* try UNIX */
320 unixpath = NULL; 318 unixpath = NULL;
321 if ((GNUNET_OK == 319 if ((GNUNET_OK ==
322 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, 320 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH",
323 "UNIXPATH", &unixpath)) 321 &unixpath)) &&
324 && (0 < strlen (unixpath))) 322 (0 < strlen (unixpath)))
325 { 323 {
326 sock = 324 sock =
327 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, 325 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
328 unixpath); 326 if (sock != NULL)
329 if (sock != NULL) 327 {
330 { 328 GNUNET_free (unixpath);
331 GNUNET_free (unixpath); 329 GNUNET_free (hostname);
332 GNUNET_free (hostname); 330 return sock;
333 return sock; 331 }
334 } 332 }
335 } 333 GNUNET_free_non_null (unixpath);
336 GNUNET_free_non_null (unixpath); 334 }
337 }
338#endif 335#endif
339#if DEBUG_CLIENT 336#if DEBUG_CLIENT
340 LOG (GNUNET_ERROR_TYPE_DEBUG, 337 LOG (GNUNET_ERROR_TYPE_DEBUG,
341 "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", 338 "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n",
342 service_name); 339 service_name);
343#endif 340#endif
344 GNUNET_free (hostname); 341 GNUNET_free (hostname);
345 return NULL; 342 return NULL;
346 } 343 }
347 344
348 sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); 345 sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
349 GNUNET_free (hostname); 346 GNUNET_free (hostname);
@@ -360,7 +357,7 @@ do_connect (const char *service_name,
360 */ 357 */
361struct GNUNET_CLIENT_Connection * 358struct GNUNET_CLIENT_Connection *
362GNUNET_CLIENT_connect (const char *service_name, 359GNUNET_CLIENT_connect (const char *service_name,
363 const struct GNUNET_CONFIGURATION_Handle *cfg) 360 const struct GNUNET_CONFIGURATION_Handle *cfg)
364{ 361{
365 struct GNUNET_CLIENT_Connection *ret; 362 struct GNUNET_CLIENT_Connection *ret;
366 struct GNUNET_CONNECTION_Handle *sock; 363 struct GNUNET_CONNECTION_Handle *sock;
@@ -393,33 +390,33 @@ GNUNET_CLIENT_connect (const char *service_name,
393 */ 390 */
394void 391void
395GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, 392GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock,
396 int finish_pending_write) 393 int finish_pending_write)
397{ 394{
398 if (sock->in_receive == GNUNET_YES) 395 if (sock->in_receive == GNUNET_YES)
399 { 396 {
400 GNUNET_CONNECTION_receive_cancel (sock->sock); 397 GNUNET_CONNECTION_receive_cancel (sock->sock);
401 sock->in_receive = GNUNET_NO; 398 sock->in_receive = GNUNET_NO;
402 } 399 }
403 if (sock->th != NULL) 400 if (sock->th != NULL)
404 { 401 {
405 GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); 402 GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th);
406 sock->th = NULL; 403 sock->th = NULL;
407 } 404 }
408 if (NULL != sock->sock) 405 if (NULL != sock->sock)
409 { 406 {
410 GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); 407 GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write);
411 sock->sock = NULL; 408 sock->sock = NULL;
412 } 409 }
413 if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) 410 if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK)
414 { 411 {
415 GNUNET_SCHEDULER_cancel (sock->receive_task); 412 GNUNET_SCHEDULER_cancel (sock->receive_task);
416 sock->receive_task = GNUNET_SCHEDULER_NO_TASK; 413 sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
417 } 414 }
418 if (sock->tag != NULL) 415 if (sock->tag != NULL)
419 { 416 {
420 GNUNET_free (sock->tag); 417 GNUNET_free (sock->tag);
421 sock->tag = NULL; 418 sock->tag = NULL;
422 } 419 }
423 sock->receiver_handler = NULL; 420 sock->receiver_handler = NULL;
424 GNUNET_array_grow (sock->received_buf, sock->received_size, 0); 421 GNUNET_array_grow (sock->received_buf, sock->received_size, 0);
425 GNUNET_free (sock->service_name); 422 GNUNET_free (sock->service_name);
@@ -436,7 +433,7 @@ check_complete (struct GNUNET_CLIENT_Connection *conn)
436 if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) && 433 if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
437 (conn->received_pos >= 434 (conn->received_pos >=
438 ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)-> 435 ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)->
439 size))) 436 size)))
440 conn->msg_complete = GNUNET_YES; 437 conn->msg_complete = GNUNET_YES;
441} 438}
442 439
@@ -455,7 +452,7 @@ check_complete (struct GNUNET_CLIENT_Connection *conn)
455 */ 452 */
456static void 453static void
457receive_helper (void *cls, const void *buf, size_t available, 454receive_helper (void *cls, const void *buf, size_t available,
458 const struct sockaddr *addr, socklen_t addrlen, int errCode) 455 const struct sockaddr *addr, socklen_t addrlen, int errCode)
459{ 456{
460 struct GNUNET_CLIENT_Connection *conn = cls; 457 struct GNUNET_CLIENT_Connection *conn = cls;
461 struct GNUNET_TIME_Relative remaining; 458 struct GNUNET_TIME_Relative remaining;
@@ -465,22 +462,22 @@ receive_helper (void *cls, const void *buf, size_t available,
465 GNUNET_assert (conn->msg_complete == GNUNET_NO); 462 GNUNET_assert (conn->msg_complete == GNUNET_NO);
466 conn->in_receive = GNUNET_NO; 463 conn->in_receive = GNUNET_NO;
467 if ((available == 0) || (conn->sock == NULL) || (errCode != 0)) 464 if ((available == 0) || (conn->sock == NULL) || (errCode != 0))
468 { 465 {
469 /* signal timeout! */ 466 /* signal timeout! */
470#if DEBUG_CLIENT 467#if DEBUG_CLIENT
471 LOG (GNUNET_ERROR_TYPE_DEBUG, 468 LOG (GNUNET_ERROR_TYPE_DEBUG,
472 "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n", 469 "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n",
473 (unsigned int) available, 470 (unsigned int) available, conn->sock == NULL ? "NULL" : "non-NULL",
474 conn->sock == NULL ? "NULL" : "non-NULL", STRERROR (errCode)); 471 STRERROR (errCode));
475#endif 472#endif
476 if (NULL != (receive_handler = conn->receiver_handler)) 473 if (NULL != (receive_handler = conn->receiver_handler))
477 { 474 {
478 receive_handler_cls = conn->receiver_handler_cls; 475 receive_handler_cls = conn->receiver_handler_cls;
479 conn->receiver_handler = NULL; 476 conn->receiver_handler = NULL;
480 receive_handler (receive_handler_cls, NULL); 477 receive_handler (receive_handler_cls, NULL);
481 }
482 return;
483 } 478 }
479 return;
480 }
484 481
485 /* FIXME: optimize for common fast case where buf contains the 482 /* FIXME: optimize for common fast case where buf contains the
486 * entire message and we need no copying... */ 483 * entire message and we need no copying... */
@@ -489,22 +486,22 @@ receive_helper (void *cls, const void *buf, size_t available,
489 /* slow path: append to array */ 486 /* slow path: append to array */
490 if (conn->received_size < conn->received_pos + available) 487 if (conn->received_size < conn->received_pos + available)
491 GNUNET_array_grow (conn->received_buf, conn->received_size, 488 GNUNET_array_grow (conn->received_buf, conn->received_size,
492 conn->received_pos + available); 489 conn->received_pos + available);
493 memcpy (&conn->received_buf[conn->received_pos], buf, available); 490 memcpy (&conn->received_buf[conn->received_pos], buf, available);
494 conn->received_pos += available; 491 conn->received_pos += available;
495 check_complete (conn); 492 check_complete (conn);
496 /* check for timeout */ 493 /* check for timeout */
497 remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout); 494 remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout);
498 if (remaining.rel_value == 0) 495 if (remaining.rel_value == 0)
499 { 496 {
500 /* signal timeout! */ 497 /* signal timeout! */
501 if (NULL != conn->receiver_handler) 498 if (NULL != conn->receiver_handler)
502 conn->receiver_handler (conn->receiver_handler_cls, NULL); 499 conn->receiver_handler (conn->receiver_handler_cls, NULL);
503 return; 500 return;
504 } 501 }
505 /* back to receive -- either for more data or to call callback! */ 502 /* back to receive -- either for more data or to call callback! */
506 GNUNET_CLIENT_receive (conn, conn->receiver_handler, 503 GNUNET_CLIENT_receive (conn, conn->receiver_handler,
507 conn->receiver_handler_cls, remaining); 504 conn->receiver_handler_cls, remaining);
508} 505}
509 506
510 507
@@ -520,23 +517,22 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
520 struct GNUNET_CLIENT_Connection *sock = cls; 517 struct GNUNET_CLIENT_Connection *sock = cls;
521 GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler; 518 GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler;
522 const struct GNUNET_MessageHeader *cmsg = 519 const struct GNUNET_MessageHeader *cmsg =
523 (const struct GNUNET_MessageHeader *) sock->received_buf; 520 (const struct GNUNET_MessageHeader *) sock->received_buf;
524 void *handler_cls = sock->receiver_handler_cls; 521 void *handler_cls = sock->receiver_handler_cls;
525 uint16_t msize = ntohs (cmsg->size); 522 uint16_t msize = ntohs (cmsg->size);
526 char mbuf[msize]; 523 char mbuf[msize];
527 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf; 524 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf;
528 525
529#if DEBUG_CLIENT 526#if DEBUG_CLIENT
530 LOG (GNUNET_ERROR_TYPE_DEBUG, 527 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u and size %u\n",
531 "Received message of type %u and size %u\n", ntohs (cmsg->type), 528 ntohs (cmsg->type), msize);
532 msize);
533#endif 529#endif
534 sock->receive_task = GNUNET_SCHEDULER_NO_TASK; 530 sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
535 GNUNET_assert (GNUNET_YES == sock->msg_complete); 531 GNUNET_assert (GNUNET_YES == sock->msg_complete);
536 GNUNET_assert (sock->received_pos >= msize); 532 GNUNET_assert (sock->received_pos >= msize);
537 memcpy (msg, cmsg, msize); 533 memcpy (msg, cmsg, msize);
538 memmove (sock->received_buf, &sock->received_buf[msize], 534 memmove (sock->received_buf, &sock->received_buf[msize],
539 sock->received_pos - msize); 535 sock->received_pos - msize);
540 sock->received_pos -= msize; 536 sock->received_pos -= msize;
541 sock->msg_complete = GNUNET_NO; 537 sock->msg_complete = GNUNET_NO;
542 sock->receiver_handler = NULL; 538 sock->receiver_handler = NULL;
@@ -556,36 +552,35 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
556 */ 552 */
557void 553void
558GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, 554GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
559 GNUNET_CLIENT_MessageHandler handler, 555 GNUNET_CLIENT_MessageHandler handler, void *handler_cls,
560 void *handler_cls, struct GNUNET_TIME_Relative timeout) 556 struct GNUNET_TIME_Relative timeout)
561{ 557{
562 if (sock->sock == NULL) 558 if (sock->sock == NULL)
563 { 559 {
564 /* already disconnected, fail instantly! */ 560 /* already disconnected, fail instantly! */
565 GNUNET_break (0); /* this should not happen in well-written code! */ 561 GNUNET_break (0); /* this should not happen in well-written code! */
566 if (NULL != handler) 562 if (NULL != handler)
567 handler (handler_cls, NULL); 563 handler (handler_cls, NULL);
568 return; 564 return;
569 } 565 }
570 sock->receiver_handler = handler; 566 sock->receiver_handler = handler;
571 sock->receiver_handler_cls = handler_cls; 567 sock->receiver_handler_cls = handler_cls;
572 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); 568 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
573 if (GNUNET_YES == sock->msg_complete) 569 if (GNUNET_YES == sock->msg_complete)
574 { 570 {
575 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task); 571 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task);
576 sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock); 572 sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock);
577 } 573 }
578 else 574 else
579 { 575 {
580 GNUNET_assert (sock->in_receive == GNUNET_NO); 576 GNUNET_assert (sock->in_receive == GNUNET_NO);
581 sock->in_receive = GNUNET_YES; 577 sock->in_receive = GNUNET_YES;
582#if DEBUG_CLIENT 578#if DEBUG_CLIENT
583 LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n"); 579 LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n");
584#endif 580#endif
585 GNUNET_CONNECTION_receive (sock->sock, 581 GNUNET_CONNECTION_receive (sock->sock, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
586 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, timeout, 582 timeout, &receive_helper, sock);
587 &receive_helper, sock); 583 }
588 }
589} 584}
590 585
591 586
@@ -596,7 +591,7 @@ static void
596service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) 591service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls)
597{ 592{
598 GNUNET_SCHEDULER_add_continuation (task, task_cls, 593 GNUNET_SCHEDULER_add_continuation (task, task_cls,
599 GNUNET_SCHEDULER_REASON_TIMEOUT); 594 GNUNET_SCHEDULER_REASON_TIMEOUT);
600} 595}
601 596
602 597
@@ -615,18 +610,18 @@ confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
615 * detail in the future, for example, is this the 610 * detail in the future, for example, is this the
616 * correct service? FIXME! */ 611 * correct service? FIXME! */
617 if (msg != NULL) 612 if (msg != NULL)
618 { 613 {
619#if DEBUG_CLIENT 614#if DEBUG_CLIENT
620 LOG (GNUNET_ERROR_TYPE_DEBUG, 615 LOG (GNUNET_ERROR_TYPE_DEBUG,
621 "Received confirmation that service is running.\n"); 616 "Received confirmation that service is running.\n");
622#endif 617#endif
623 GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls, 618 GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls,
624 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 619 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
625 } 620 }
626 else 621 else
627 { 622 {
628 service_test_error (conn->test_cb, conn->test_cb_cls); 623 service_test_error (conn->test_cb, conn->test_cb_cls);
629 } 624 }
630 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 625 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
631} 626}
632 627
@@ -647,14 +642,14 @@ write_test (void *cls, size_t size, void *buf)
647 struct GNUNET_MessageHeader *msg; 642 struct GNUNET_MessageHeader *msg;
648 643
649 if (size < sizeof (struct GNUNET_MessageHeader)) 644 if (size < sizeof (struct GNUNET_MessageHeader))
650 { 645 {
651#if DEBUG_CLIENT 646#if DEBUG_CLIENT
652 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n")); 647 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n"));
653#endif 648#endif
654 service_test_error (conn->test_cb, conn->test_cb_cls); 649 service_test_error (conn->test_cb, conn->test_cb_cls);
655 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 650 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
656 return 0; /* client disconnected */ 651 return 0; /* client disconnected */
657 } 652 }
658#if DEBUG_CLIENT 653#if DEBUG_CLIENT
659 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST"); 654 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST");
660#endif 655#endif
@@ -662,8 +657,8 @@ write_test (void *cls, size_t size, void *buf)
662 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); 657 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
663 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 658 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
664 GNUNET_CLIENT_receive (conn, &confirm_handler, conn, 659 GNUNET_CLIENT_receive (conn, &confirm_handler, conn,
665 GNUNET_TIME_absolute_get_remaining 660 GNUNET_TIME_absolute_get_remaining
666 (conn->test_deadline)); 661 (conn->test_deadline));
667 return sizeof (struct GNUNET_MessageHeader); 662 return sizeof (struct GNUNET_MessageHeader);
668} 663}
669 664
@@ -683,9 +678,9 @@ write_test (void *cls, size_t size, void *buf)
683 */ 678 */
684void 679void
685GNUNET_CLIENT_service_test (const char *service, 680GNUNET_CLIENT_service_test (const char *service,
686 const struct GNUNET_CONFIGURATION_Handle *cfg, 681 const struct GNUNET_CONFIGURATION_Handle *cfg,
687 struct GNUNET_TIME_Relative timeout, 682 struct GNUNET_TIME_Relative timeout,
688 GNUNET_SCHEDULER_Task task, void *task_cls) 683 GNUNET_SCHEDULER_Task task, void *task_cls)
689{ 684{
690 char *hostname; 685 char *hostname;
691 unsigned long long port; 686 unsigned long long port;
@@ -704,50 +699,49 @@ GNUNET_CLIENT_service_test (const char *service,
704 char *unixpath; 699 char *unixpath;
705 700
706 unixpath = NULL; 701 unixpath = NULL;
707 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? */ 702 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? */
703 {
704 if (strlen (unixpath) >= sizeof (s_un.sun_path))
705 {
706 LOG (GNUNET_ERROR_TYPE_WARNING,
707 _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
708 sizeof (s_un.sun_path));
709 }
710 else
708 { 711 {
709 if (strlen (unixpath) >= sizeof (s_un.sun_path)) 712 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
710 { 713 if (sock != NULL)
711 LOG (GNUNET_ERROR_TYPE_WARNING, 714 {
712 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 715 memset (&s_un, 0, sizeof (s_un));
713 unixpath, sizeof (s_un.sun_path)); 716 s_un.sun_family = AF_UNIX;
714 } 717 slen = strlen (unixpath) + 1;
715 else 718 if (slen >= sizeof (s_un.sun_path))
716 { 719 slen = sizeof (s_un.sun_path) - 1;
717 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); 720 memcpy (s_un.sun_path, unixpath, slen);
718 if (sock != NULL) 721 s_un.sun_path[slen] = '\0';
719 { 722 slen = sizeof (struct sockaddr_un);
720 memset (&s_un, 0, sizeof (s_un));
721 s_un.sun_family = AF_UNIX;
722 slen = strlen (unixpath) + 1;
723 if (slen >= sizeof (s_un.sun_path))
724 slen = sizeof (s_un.sun_path) - 1;
725 memcpy (s_un.sun_path, unixpath, slen);
726 s_un.sun_path[slen] = '\0';
727 slen = sizeof (struct sockaddr_un);
728#if LINUX 723#if LINUX
729 s_un.sun_path[0] = '\0'; 724 s_un.sun_path[0] = '\0';
730#endif 725#endif
731#if HAVE_SOCKADDR_IN_SIN_LEN 726#if HAVE_SOCKADDR_IN_SIN_LEN
732 s_un.sun_len = (u_char) slen; 727 s_un.sun_len = (u_char) slen;
733#endif 728#endif
734 if (GNUNET_OK != 729 if (GNUNET_OK !=
735 GNUNET_NETWORK_socket_bind (sock, 730 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un,
736 (const struct sockaddr *) 731 slen))
737 &s_un, slen)) 732 {
738 { 733 /* failed to bind => service must be running */
739 /* failed to bind => service must be running */ 734 GNUNET_free (unixpath);
740 GNUNET_free (unixpath); 735 (void) GNUNET_NETWORK_socket_close (sock);
741 (void) GNUNET_NETWORK_socket_close (sock); 736 GNUNET_SCHEDULER_add_continuation (task, task_cls,
742 GNUNET_SCHEDULER_add_continuation (task, task_cls, 737 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
743 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 738 return;
744 return; 739 }
745 } 740 (void) GNUNET_NETWORK_socket_close (sock);
746 (void) GNUNET_NETWORK_socket_close (sock); 741 }
747 } 742 /* let's try IP */
748 /* let's try IP */
749 }
750 } 743 }
744 }
751 GNUNET_free_non_null (unixpath); 745 GNUNET_free_non_null (unixpath);
752 } 746 }
753#endif 747#endif
@@ -758,124 +752,121 @@ GNUNET_CLIENT_service_test (const char *service,
758 (port > 65535) || 752 (port > 65535) ||
759 (GNUNET_OK != 753 (GNUNET_OK !=
760 GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME", 754 GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
761 &hostname))) 755 &hostname)))
762 { 756 {
763 /* UNIXPATH failed (if possible) AND IP failed => error */ 757 /* UNIXPATH failed (if possible) AND IP failed => error */
764 service_test_error (task, task_cls); 758 service_test_error (task, task_cls);
765 return; 759 return;
766 } 760 }
767 761
768 if (0 == strcmp ("localhost", hostname) 762 if (0 == strcmp ("localhost", hostname)
769#if !LINUX 763#if !LINUX
770 && 0 764 && 0
771#endif 765#endif
772 ) 766 )
773 { 767 {
774 /* can test using 'bind' */ 768 /* can test using 'bind' */
775 struct sockaddr_in s_in; 769 struct sockaddr_in s_in;
776 770
777 memset (&s_in, 0, sizeof (s_in)); 771 memset (&s_in, 0, sizeof (s_in));
778#if HAVE_SOCKADDR_IN_SIN_LEN 772#if HAVE_SOCKADDR_IN_SIN_LEN
779 s_in.sin_len = sizeof (struct sockaddr_in); 773 s_in.sin_len = sizeof (struct sockaddr_in);
780#endif 774#endif
781 s_in.sin_family = AF_INET; 775 s_in.sin_family = AF_INET;
782 s_in.sin_port = htons (port); 776 s_in.sin_port = htons (port);
783 777
784 sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); 778 sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
785 if (sock != NULL) 779 if (sock != NULL)
786 { 780 {
787 if (GNUNET_OK != 781 if (GNUNET_OK !=
788 GNUNET_NETWORK_socket_bind (sock, 782 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in,
789 (const struct sockaddr *) &s_in, 783 sizeof (s_in)))
790 sizeof (s_in))) 784 {
791 { 785 /* failed to bind => service must be running */
792 /* failed to bind => service must be running */ 786 GNUNET_free (hostname);
793 GNUNET_free (hostname); 787 (void) GNUNET_NETWORK_socket_close (sock);
794 (void) GNUNET_NETWORK_socket_close (sock); 788 GNUNET_SCHEDULER_add_continuation (task, task_cls,
795 GNUNET_SCHEDULER_add_continuation (task, task_cls, 789 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
796 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 790 return;
797 return; 791 }
798 } 792 (void) GNUNET_NETWORK_socket_close (sock);
799 (void) GNUNET_NETWORK_socket_close (sock);
800 }
801 } 793 }
794 }
802 795
803 if (0 == strcmp ("ip6-localhost", hostname) 796 if (0 == strcmp ("ip6-localhost", hostname)
804#if !LINUX 797#if !LINUX
805 && 0 798 && 0
806#endif 799#endif
807 ) 800 )
808 { 801 {
809 /* can test using 'bind' */ 802 /* can test using 'bind' */
810 struct sockaddr_in6 s_in6; 803 struct sockaddr_in6 s_in6;
811 804
812 memset (&s_in6, 0, sizeof (s_in6)); 805 memset (&s_in6, 0, sizeof (s_in6));
813#if HAVE_SOCKADDR_IN_SIN_LEN 806#if HAVE_SOCKADDR_IN_SIN_LEN
814 s_in6.sin6_len = sizeof (struct sockaddr_in6); 807 s_in6.sin6_len = sizeof (struct sockaddr_in6);
815#endif 808#endif
816 s_in6.sin6_family = AF_INET6; 809 s_in6.sin6_family = AF_INET6;
817 s_in6.sin6_port = htons (port); 810 s_in6.sin6_port = htons (port);
818 811
819 sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); 812 sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
820 if (sock != NULL) 813 if (sock != NULL)
821 { 814 {
822 if (GNUNET_OK != 815 if (GNUNET_OK !=
823 GNUNET_NETWORK_socket_bind (sock, 816 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6,
824 (const struct sockaddr *) &s_in6, 817 sizeof (s_in6)))
825 sizeof (s_in6))) 818 {
826 { 819 /* failed to bind => service must be running */
827 /* failed to bind => service must be running */ 820 GNUNET_free (hostname);
828 GNUNET_free (hostname); 821 (void) GNUNET_NETWORK_socket_close (sock);
829 (void) GNUNET_NETWORK_socket_close (sock); 822 GNUNET_SCHEDULER_add_continuation (task, task_cls,
830 GNUNET_SCHEDULER_add_continuation (task, task_cls, 823 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
831 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 824 return;
832 return; 825 }
833 } 826 (void) GNUNET_NETWORK_socket_close (sock);
834 (void) GNUNET_NETWORK_socket_close (sock);
835 }
836 } 827 }
828 }
837 829
838 if (((0 == strcmp ("localhost", hostname)) || 830 if (((0 == strcmp ("localhost", hostname)) ||
839 (0 == strcmp ("ip6-localhost", hostname))) 831 (0 == strcmp ("ip6-localhost", hostname)))
840#if !LINUX 832#if !LINUX
841 && 0 833 && 0
842#endif 834#endif
843 ) 835 )
844 { 836 {
845 /* all binds succeeded => claim service not running right now */ 837 /* all binds succeeded => claim service not running right now */
846 GNUNET_free_non_null (hostname); 838 GNUNET_free_non_null (hostname);
847 service_test_error (task, task_cls); 839 service_test_error (task, task_cls);
848 return; 840 return;
849 } 841 }
850 GNUNET_free_non_null (hostname); 842 GNUNET_free_non_null (hostname);
851 843
852 /* non-localhost, try 'connect' method */ 844 /* non-localhost, try 'connect' method */
853 conn = GNUNET_CLIENT_connect (service, cfg); 845 conn = GNUNET_CLIENT_connect (service, cfg);
854 if (conn == NULL) 846 if (conn == NULL)
855 { 847 {
856 LOG (GNUNET_ERROR_TYPE_INFO, 848 LOG (GNUNET_ERROR_TYPE_INFO,
857 _("Could not connect to service `%s', must not be running.\n"), 849 _("Could not connect to service `%s', must not be running.\n"),
858 service); 850 service);
859 service_test_error (task, task_cls); 851 service_test_error (task, task_cls);
860 return; 852 return;
861 } 853 }
862 conn->test_cb = task; 854 conn->test_cb = task;
863 conn->test_cb_cls = task_cls; 855 conn->test_cb_cls = task_cls;
864 conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); 856 conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
865 857
866 if (NULL == 858 if (NULL ==
867 GNUNET_CLIENT_notify_transmit_ready (conn, 859 GNUNET_CLIENT_notify_transmit_ready (conn,
868 sizeof (struct 860 sizeof (struct GNUNET_MessageHeader),
869 GNUNET_MessageHeader), 861 timeout, GNUNET_YES, &write_test,
870 timeout, GNUNET_YES, &write_test, 862 conn))
871 conn)) 863 {
872 { 864 LOG (GNUNET_ERROR_TYPE_WARNING,
873 LOG (GNUNET_ERROR_TYPE_WARNING, 865 _("Failure to transmit request to service `%s'\n"), service);
874 _("Failure to transmit request to service `%s'\n"), service); 866 service_test_error (task, task_cls);
875 service_test_error (task, task_cls); 867 GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
876 GNUNET_CLIENT_disconnect (conn, GNUNET_NO); 868 return;
877 return; 869 }
878 }
879} 870}
880 871
881 872
@@ -889,7 +880,8 @@ GNUNET_CLIENT_service_test (const char *service,
889 * @param buf where to write them 880 * @param buf where to write them
890 * @return number of bytes written to buf 881 * @return number of bytes written to buf
891 */ 882 */
892static size_t client_notify (void *cls, size_t size, void *buf); 883static size_t
884client_notify (void *cls, size_t size, void *buf);
893 885
894 886
895/** 887/**
@@ -900,58 +892,57 @@ static size_t client_notify (void *cls, size_t size, void *buf);
900 * @param tc unused 892 * @param tc unused
901 */ 893 */
902static void 894static void
903client_delayed_retry (void *cls, 895client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
904 const struct GNUNET_SCHEDULER_TaskContext *tc)
905{ 896{
906 struct GNUNET_CLIENT_TransmitHandle *th = cls; 897 struct GNUNET_CLIENT_TransmitHandle *th = cls;
907 struct GNUNET_TIME_Relative delay; 898 struct GNUNET_TIME_Relative delay;
908 899
909 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 900 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
910 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 901 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
911 { 902 {
912#if DEBUG_CLIENT 903#if DEBUG_CLIENT
913 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n"); 904 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n");
914#endif 905#endif
915 th->sock->th = NULL; 906 th->sock->th = NULL;
916 th->notify (th->notify_cls, 0, NULL); 907 th->notify (th->notify_cls, 0, NULL);
917 GNUNET_free (th); 908 GNUNET_free (th);
918 return; 909 return;
919 } 910 }
920 th->sock->sock = 911 th->sock->sock =
921 do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++); 912 do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++);
922 if (NULL == th->sock->sock) 913 if (NULL == th->sock->sock)
923 { 914 {
924 /* could happen if we're out of sockets */ 915 /* could happen if we're out of sockets */
925 delay = 916 delay =
926 GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining 917 GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining
927 (th->timeout), th->sock->back_off); 918 (th->timeout), th->sock->back_off);
928 th->sock->back_off = 919 th->sock->back_off =
929 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply 920 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
930 (th->sock->back_off, 2), 921 (th->sock->back_off, 2),
931 GNUNET_TIME_UNIT_SECONDS); 922 GNUNET_TIME_UNIT_SECONDS);
932#if DEBUG_CLIENT 923#if DEBUG_CLIENT
933 LOG (GNUNET_ERROR_TYPE_DEBUG, 924 LOG (GNUNET_ERROR_TYPE_DEBUG,
934 "Transmission failed %u times, trying again in %llums.\n", 925 "Transmission failed %u times, trying again in %llums.\n",
935 MAX_ATTEMPTS - th->attempts_left, 926 MAX_ATTEMPTS - th->attempts_left,
936 (unsigned long long) delay.rel_value); 927 (unsigned long long) delay.rel_value);
937#endif 928#endif
938 th->reconnect_task = 929 th->reconnect_task =
939 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); 930 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
940 return; 931 return;
941 } 932 }
942 th->th = 933 th->th =
943 GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size, 934 GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size,
944 GNUNET_TIME_absolute_get_remaining 935 GNUNET_TIME_absolute_get_remaining
945 (th->timeout), &client_notify, 936 (th->timeout), &client_notify,
946 th); 937 th);
947 if (th->th == NULL) 938 if (th->th == NULL)
948 { 939 {
949 GNUNET_break (0); 940 GNUNET_break (0);
950 th->sock->th = NULL; 941 th->sock->th = NULL;
951 th->notify (th->notify_cls, 0, NULL); 942 th->notify (th->notify_cls, 0, NULL);
952 GNUNET_free (th); 943 GNUNET_free (th);
953 return; 944 return;
954 } 945 }
955} 946}
956 947
957 948
@@ -974,47 +965,47 @@ client_notify (void *cls, size_t size, void *buf)
974 th->th = NULL; 965 th->th = NULL;
975 th->sock->th = NULL; 966 th->sock->th = NULL;
976 if (buf == NULL) 967 if (buf == NULL)
968 {
969 delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
970 delay.rel_value /= 2;
971 if ((0 !=
972 (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) ||
973 (GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) ||
974 (delay.rel_value < 1))
977 { 975 {
978 delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
979 delay.rel_value /= 2;
980 if ((0 !=
981 (GNUNET_SCHEDULER_REASON_SHUTDOWN &
982 GNUNET_SCHEDULER_get_reason ())) || (GNUNET_YES != th->auto_retry)
983 || (0 == --th->attempts_left) || (delay.rel_value < 1))
984 {
985#if DEBUG_CLIENT 976#if DEBUG_CLIENT
986 LOG (GNUNET_ERROR_TYPE_DEBUG, 977 LOG (GNUNET_ERROR_TYPE_DEBUG,
987 "Transmission failed %u times, giving up.\n", 978 "Transmission failed %u times, giving up.\n",
988 MAX_ATTEMPTS - th->attempts_left); 979 MAX_ATTEMPTS - th->attempts_left);
989#endif 980#endif
990 GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL)); 981 GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
991 GNUNET_free (th); 982 GNUNET_free (th);
992 return 0; 983 return 0;
993 } 984 }
994 /* auto-retry */ 985 /* auto-retry */
995#if DEBUG_CLIENT 986#if DEBUG_CLIENT
996 LOG (GNUNET_ERROR_TYPE_DEBUG, 987 LOG (GNUNET_ERROR_TYPE_DEBUG,
997 "Failed to connect to `%s', automatically trying again.\n", 988 "Failed to connect to `%s', automatically trying again.\n",
998 th->sock->service_name); 989 th->sock->service_name);
999#endif 990#endif
1000 GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); 991 GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO);
1001 th->sock->sock = NULL; 992 th->sock->sock = NULL;
1002 delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); 993 delay = GNUNET_TIME_relative_min (delay, th->sock->back_off);
1003 th->sock->back_off = 994 th->sock->back_off =
1004 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply 995 GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
1005 (th->sock->back_off, 2), 996 (th->sock->back_off, 2),
1006 GNUNET_TIME_UNIT_SECONDS); 997 GNUNET_TIME_UNIT_SECONDS);
1007#if DEBUG_CLIENT 998#if DEBUG_CLIENT
1008 LOG (GNUNET_ERROR_TYPE_DEBUG, 999 LOG (GNUNET_ERROR_TYPE_DEBUG,
1009 "Transmission failed %u times, trying again in %llums.\n", 1000 "Transmission failed %u times, trying again in %llums.\n",
1010 MAX_ATTEMPTS - th->attempts_left, 1001 MAX_ATTEMPTS - th->attempts_left,
1011 (unsigned long long) delay.rel_value); 1002 (unsigned long long) delay.rel_value);
1012#endif 1003#endif
1013 th->sock->th = th; 1004 th->sock->th = th;
1014 th->reconnect_task = 1005 th->reconnect_task =
1015 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); 1006 GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
1016 return 0; 1007 return 0;
1017 } 1008 }
1018 GNUNET_assert (size >= th->size); 1009 GNUNET_assert (size >= th->size);
1019 ret = th->notify (th->notify_cls, size, buf); 1010 ret = th->notify (th->notify_cls, size, buf);
1020 GNUNET_free (th); 1011 GNUNET_free (th);
@@ -1043,21 +1034,21 @@ client_notify (void *cls, size_t size, void *buf)
1043 */ 1034 */
1044struct GNUNET_CLIENT_TransmitHandle * 1035struct GNUNET_CLIENT_TransmitHandle *
1045GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, 1036GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1046 size_t size, 1037 size_t size,
1047 struct GNUNET_TIME_Relative timeout, 1038 struct GNUNET_TIME_Relative timeout,
1048 int auto_retry, 1039 int auto_retry,
1049 GNUNET_CONNECTION_TransmitReadyNotify 1040 GNUNET_CONNECTION_TransmitReadyNotify
1050 notify, void *notify_cls) 1041 notify, void *notify_cls)
1051{ 1042{
1052 struct GNUNET_CLIENT_TransmitHandle *th; 1043 struct GNUNET_CLIENT_TransmitHandle *th;
1053 1044
1054 if (NULL != sock->th) 1045 if (NULL != sock->th)
1055 { 1046 {
1056 /* If this breaks, you most likley called this function twice without waiting 1047 /* If this breaks, you most likley called this function twice without waiting
1057 * for completion or canceling the request */ 1048 * for completion or canceling the request */
1058 GNUNET_break (0); 1049 GNUNET_break (0);
1059 return NULL; 1050 return NULL;
1060 } 1051 }
1061 th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); 1052 th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
1062 th->sock = sock; 1053 th->sock = sock;
1063 th->size = size; 1054 th->size = size;
@@ -1068,25 +1059,25 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1068 th->attempts_left = MAX_ATTEMPTS; 1059 th->attempts_left = MAX_ATTEMPTS;
1069 sock->th = th; 1060 sock->th = th;
1070 if (sock->sock == NULL) 1061 if (sock->sock == NULL)
1071 { 1062 {
1072 th->reconnect_task = 1063 th->reconnect_task =
1073 GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry, 1064 GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry,
1074 th); 1065 th);
1075 1066
1076 } 1067 }
1077 else 1068 else
1069 {
1070 th->th =
1071 GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout,
1072 &client_notify, th);
1073 if (NULL == th->th)
1078 { 1074 {
1079 th->th = 1075 GNUNET_break (0);
1080 GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout, 1076 GNUNET_free (th);
1081 &client_notify, th); 1077 sock->th = NULL;
1082 if (NULL == th->th) 1078 return NULL;
1083 {
1084 GNUNET_break (0);
1085 GNUNET_free (th);
1086 sock->th = NULL;
1087 return NULL;
1088 }
1089 } 1079 }
1080 }
1090 return th; 1081 return th;
1091} 1082}
1092 1083
@@ -1097,20 +1088,20 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1097 * @param th handle from the original request. 1088 * @param th handle from the original request.
1098 */ 1089 */
1099void 1090void
1100GNUNET_CLIENT_notify_transmit_ready_cancel (struct 1091GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
1101 GNUNET_CLIENT_TransmitHandle *th) 1092 *th)
1102{ 1093{
1103 if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 1094 if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
1104 { 1095 {
1105 GNUNET_assert (NULL == th->th); 1096 GNUNET_assert (NULL == th->th);
1106 GNUNET_SCHEDULER_cancel (th->reconnect_task); 1097 GNUNET_SCHEDULER_cancel (th->reconnect_task);
1107 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 1098 th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1108 } 1099 }
1109 else 1100 else
1110 { 1101 {
1111 GNUNET_assert (NULL != th->th); 1102 GNUNET_assert (NULL != th->th);
1112 GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); 1103 GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th);
1113 } 1104 }
1114 th->sock->th = NULL; 1105 th->sock->th = NULL;
1115 GNUNET_free (th); 1106 GNUNET_free (th);
1116} 1107}
@@ -1136,21 +1127,20 @@ transmit_for_response (void *cls, size_t size, void *buf)
1136 tc->sock->tag = NULL; 1127 tc->sock->tag = NULL;
1137 msize = ntohs (tc->hdr->size); 1128 msize = ntohs (tc->hdr->size);
1138 if (NULL == buf) 1129 if (NULL == buf)
1139 { 1130 {
1140#if DEBUG_CLIENT 1131#if DEBUG_CLIENT
1141 LOG (GNUNET_ERROR_TYPE_DEBUG, 1132 LOG (GNUNET_ERROR_TYPE_DEBUG,
1142 _ 1133 _("Could not submit request, not expecting to receive a response.\n"));
1143 ("Could not submit request, not expecting to receive a response.\n"));
1144#endif 1134#endif
1145 if (NULL != tc->rn) 1135 if (NULL != tc->rn)
1146 tc->rn (tc->rn_cls, NULL); 1136 tc->rn (tc->rn_cls, NULL);
1147 GNUNET_free (tc); 1137 GNUNET_free (tc);
1148 return 0; 1138 return 0;
1149 } 1139 }
1150 GNUNET_assert (size >= msize); 1140 GNUNET_assert (size >= msize);
1151 memcpy (buf, tc->hdr, msize); 1141 memcpy (buf, tc->hdr, msize);
1152 GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls, 1142 GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls,
1153 GNUNET_TIME_absolute_get_remaining (tc->timeout)); 1143 GNUNET_TIME_absolute_get_remaining (tc->timeout));
1154 GNUNET_free (tc); 1144 GNUNET_free (tc);
1155 return msize; 1145 return msize;
1156} 1146}
@@ -1178,14 +1168,12 @@ transmit_for_response (void *cls, size_t size, void *buf)
1178 * is already pending 1168 * is already pending
1179 */ 1169 */
1180int 1170int
1181GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection 1171GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
1182 *sock, 1172 const struct GNUNET_MessageHeader *hdr,
1183 const struct GNUNET_MessageHeader 1173 struct GNUNET_TIME_Relative timeout,
1184 *hdr, 1174 int auto_retry,
1185 struct GNUNET_TIME_Relative timeout, 1175 GNUNET_CLIENT_MessageHandler rn,
1186 int auto_retry, 1176 void *rn_cls)
1187 GNUNET_CLIENT_MessageHandler rn,
1188 void *rn_cls)
1189{ 1177{
1190 struct TransmitGetResponseContext *tc; 1178 struct TransmitGetResponseContext *tc;
1191 uint16_t msize; 1179 uint16_t msize;
@@ -1203,12 +1191,12 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection
1203 tc->rn_cls = rn_cls; 1191 tc->rn_cls = rn_cls;
1204 if (NULL == 1192 if (NULL ==
1205 GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry, 1193 GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry,
1206 &transmit_for_response, tc)) 1194 &transmit_for_response, tc))
1207 { 1195 {
1208 GNUNET_break (0); 1196 GNUNET_break (0);
1209 GNUNET_free (tc); 1197 GNUNET_free (tc);
1210 return GNUNET_SYSERR; 1198 return GNUNET_SYSERR;
1211 } 1199 }
1212 sock->tag = tc; 1200 sock->tag = tc;
1213 return GNUNET_OK; 1201 return GNUNET_OK;
1214} 1202}