diff options
Diffstat (limited to 'src/util/client.c')
-rw-r--r-- | src/util/client.c | 817 |
1 files changed, 400 insertions, 417 deletions
diff --git a/src/util/client.c b/src/util/client.c index db53ab6f2..032a6c5e4 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -243,7 +243,7 @@ struct GNUNET_CLIENT_Connection | |||
243 | * Are we ignoring shutdown signals? | 243 | * Are we ignoring shutdown signals? |
244 | */ | 244 | */ |
245 | int ignore_shutdown; | 245 | int ignore_shutdown; |
246 | 246 | ||
247 | /** | 247 | /** |
248 | * How often have we tried to connect? | 248 | * How often have we tried to connect? |
249 | */ | 249 | */ |
@@ -262,8 +262,7 @@ struct GNUNET_CLIENT_Connection | |||
262 | */ | 262 | */ |
263 | static struct GNUNET_CONNECTION_Handle * | 263 | static struct GNUNET_CONNECTION_Handle * |
264 | do_connect (const char *service_name, | 264 | do_connect (const char *service_name, |
265 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 265 | const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) |
266 | unsigned int attempt) | ||
267 | { | 266 | { |
268 | struct GNUNET_CONNECTION_Handle *sock; | 267 | struct GNUNET_CONNECTION_Handle *sock; |
269 | char *hostname; | 268 | char *hostname; |
@@ -273,27 +272,24 @@ do_connect (const char *service_name, | |||
273 | sock = NULL; | 272 | sock = NULL; |
274 | #if AF_UNIX | 273 | #if AF_UNIX |
275 | if (0 == (attempt % 2)) | 274 | 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? */ | ||
276 | { | 279 | { |
277 | /* on even rounds, try UNIX */ | 280 | sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); |
278 | unixpath = NULL; | 281 | if (sock != NULL) |
279 | if ( (GNUNET_OK == | 282 | { |
280 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
281 | service_name, | ||
282 | "UNIXPATH", &unixpath)) && | ||
283 | (0 < strlen (unixpath)) ) /* We have a non-NULL unixpath, does that mean it's valid? */ | ||
284 | { | ||
285 | sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); | ||
286 | if (sock != NULL) | ||
287 | { | ||
288 | #if DEBUG_CLIENT | 283 | #if DEBUG_CLIENT |
289 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", unixpath); | 284 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", |
285 | unixpath); | ||
290 | #endif | 286 | #endif |
291 | GNUNET_free(unixpath); | 287 | GNUNET_free (unixpath); |
292 | return sock; | 288 | return sock; |
293 | } | 289 | } |
294 | } | ||
295 | GNUNET_free_non_null (unixpath); | ||
296 | } | 290 | } |
291 | GNUNET_free_non_null (unixpath); | ||
292 | } | ||
297 | #endif | 293 | #endif |
298 | 294 | ||
299 | if ((GNUNET_OK != | 295 | if ((GNUNET_OK != |
@@ -306,57 +302,56 @@ do_connect (const char *service_name, | |||
306 | GNUNET_CONFIGURATION_get_value_string (cfg, | 302 | GNUNET_CONFIGURATION_get_value_string (cfg, |
307 | service_name, | 303 | service_name, |
308 | "HOSTNAME", &hostname))) | 304 | "HOSTNAME", &hostname))) |
309 | { | 305 | { |
310 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 306 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
311 | _("Could not determine valid hostname and port for service `%s' from configuration.\n"), | 307 | _ |
312 | service_name); | 308 | ("Could not determine valid hostname and port for service `%s' from configuration.\n"), |
313 | return NULL; | 309 | service_name); |
314 | } | 310 | return NULL; |
311 | } | ||
315 | if (0 == strlen (hostname)) | 312 | if (0 == strlen (hostname)) |
316 | { | 313 | { |
317 | GNUNET_free (hostname); | 314 | GNUNET_free (hostname); |
318 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 315 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
319 | _("Need a non-empty hostname for service `%s'.\n"), | 316 | _("Need a non-empty hostname for service `%s'.\n"), |
320 | service_name); | 317 | service_name); |
321 | return NULL; | 318 | return NULL; |
322 | } | 319 | } |
323 | if (port == 0) | 320 | if (port == 0) |
324 | { | 321 | { |
325 | #if AF_UNIX | 322 | #if AF_UNIX |
326 | if (0 != (attempt % 2)) | 323 | if (0 != (attempt % 2)) |
327 | { | 324 | { |
328 | /* try UNIX */ | 325 | /* try UNIX */ |
329 | unixpath = NULL; | 326 | unixpath = NULL; |
330 | if ( (GNUNET_OK == | 327 | if ((GNUNET_OK == |
331 | GNUNET_CONFIGURATION_get_value_string (cfg, | 328 | GNUNET_CONFIGURATION_get_value_string (cfg, |
332 | service_name, | 329 | service_name, |
333 | "UNIXPATH", &unixpath)) && | 330 | "UNIXPATH", &unixpath)) && |
334 | (0 < strlen (unixpath))) | 331 | (0 < strlen (unixpath))) |
335 | { | 332 | { |
336 | sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, | 333 | sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, |
337 | unixpath); | 334 | unixpath); |
338 | if (sock != NULL) | 335 | if (sock != NULL) |
339 | { | 336 | { |
340 | GNUNET_free (unixpath); | 337 | GNUNET_free (unixpath); |
341 | GNUNET_free (hostname); | 338 | GNUNET_free (hostname); |
342 | return sock; | 339 | return sock; |
343 | } | 340 | } |
344 | } | 341 | } |
345 | GNUNET_free_non_null (unixpath); | 342 | GNUNET_free_non_null (unixpath); |
346 | } | 343 | } |
347 | #endif | 344 | #endif |
348 | #if DEBUG_CLIENT | 345 | #if DEBUG_CLIENT |
349 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 346 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
350 | "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", | 347 | "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", |
351 | service_name); | 348 | service_name); |
352 | #endif | 349 | #endif |
353 | GNUNET_free (hostname); | 350 | GNUNET_free (hostname); |
354 | return NULL; | 351 | return NULL; |
355 | } | 352 | } |
356 | 353 | ||
357 | sock = GNUNET_CONNECTION_create_from_connect (cfg, | 354 | sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); |
358 | hostname, | ||
359 | port); | ||
360 | GNUNET_free (hostname); | 355 | GNUNET_free (hostname); |
361 | return sock; | 356 | return sock; |
362 | } | 357 | } |
@@ -376,8 +371,7 @@ GNUNET_CLIENT_connect (const char *service_name, | |||
376 | struct GNUNET_CLIENT_Connection *ret; | 371 | struct GNUNET_CLIENT_Connection *ret; |
377 | struct GNUNET_CONNECTION_Handle *sock; | 372 | struct GNUNET_CONNECTION_Handle *sock; |
378 | 373 | ||
379 | sock = do_connect (service_name, | 374 | sock = do_connect (service_name, cfg, 0); |
380 | cfg, 0); | ||
381 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); | 375 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); |
382 | ret->attempts = 1; | 376 | ret->attempts = 1; |
383 | ret->sock = sock; | 377 | ret->sock = sock; |
@@ -396,12 +390,11 @@ GNUNET_CLIENT_connect (const char *service_name, | |||
396 | */ | 390 | */ |
397 | void | 391 | void |
398 | GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h, | 392 | GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h, |
399 | int do_ignore) | 393 | int do_ignore) |
400 | { | 394 | { |
401 | h->ignore_shutdown = do_ignore; | 395 | h->ignore_shutdown = do_ignore; |
402 | if (h->sock != NULL) | 396 | if (h->sock != NULL) |
403 | GNUNET_CONNECTION_ignore_shutdown (h->sock, | 397 | GNUNET_CONNECTION_ignore_shutdown (h->sock, do_ignore); |
404 | do_ignore); | ||
405 | } | 398 | } |
406 | 399 | ||
407 | 400 | ||
@@ -422,33 +415,33 @@ GNUNET_CLIENT_ignore_shutdown (struct GNUNET_CLIENT_Connection *h, | |||
422 | */ | 415 | */ |
423 | void | 416 | void |
424 | GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, | 417 | GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, |
425 | int finish_pending_write) | 418 | int finish_pending_write) |
426 | { | 419 | { |
427 | if (sock->in_receive == GNUNET_YES) | 420 | if (sock->in_receive == GNUNET_YES) |
428 | { | 421 | { |
429 | GNUNET_CONNECTION_receive_cancel (sock->sock); | 422 | GNUNET_CONNECTION_receive_cancel (sock->sock); |
430 | sock->in_receive = GNUNET_NO; | 423 | sock->in_receive = GNUNET_NO; |
431 | } | 424 | } |
432 | if (sock->th != NULL) | 425 | if (sock->th != NULL) |
433 | { | 426 | { |
434 | GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); | 427 | GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); |
435 | sock->th = NULL; | 428 | sock->th = NULL; |
436 | } | 429 | } |
437 | if (NULL != sock->sock) | 430 | if (NULL != sock->sock) |
438 | { | 431 | { |
439 | GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); | 432 | GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); |
440 | sock->sock = NULL; | 433 | sock->sock = NULL; |
441 | } | 434 | } |
442 | if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) | 435 | if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) |
443 | { | 436 | { |
444 | GNUNET_SCHEDULER_cancel (sock->receive_task); | 437 | GNUNET_SCHEDULER_cancel (sock->receive_task); |
445 | sock->receive_task = GNUNET_SCHEDULER_NO_TASK; | 438 | sock->receive_task = GNUNET_SCHEDULER_NO_TASK; |
446 | } | 439 | } |
447 | if (sock->tag != NULL) | 440 | if (sock->tag != NULL) |
448 | { | 441 | { |
449 | GNUNET_free (sock->tag); | 442 | GNUNET_free (sock->tag); |
450 | sock->tag = NULL; | 443 | sock->tag = NULL; |
451 | } | 444 | } |
452 | sock->receiver_handler = NULL; | 445 | sock->receiver_handler = NULL; |
453 | GNUNET_array_grow (sock->received_buf, sock->received_size, 0); | 446 | GNUNET_array_grow (sock->received_buf, sock->received_size, 0); |
454 | GNUNET_free (sock->service_name); | 447 | GNUNET_free (sock->service_name); |
@@ -496,26 +489,25 @@ receive_helper (void *cls, | |||
496 | GNUNET_assert (conn->msg_complete == GNUNET_NO); | 489 | GNUNET_assert (conn->msg_complete == GNUNET_NO); |
497 | conn->in_receive = GNUNET_NO; | 490 | conn->in_receive = GNUNET_NO; |
498 | if ((available == 0) || (conn->sock == NULL) || (errCode != 0)) | 491 | if ((available == 0) || (conn->sock == NULL) || (errCode != 0)) |
499 | { | 492 | { |
500 | /* signal timeout! */ | 493 | /* signal timeout! */ |
501 | #if DEBUG_CLIENT | 494 | #if DEBUG_CLIENT |
502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 495 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
503 | "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n", | 496 | "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n", |
504 | (unsigned int) available, | 497 | (unsigned int) available, |
505 | conn->sock == NULL ? "NULL" : "non-NULL", | 498 | conn->sock == NULL ? "NULL" : "non-NULL", STRERROR (errCode)); |
506 | STRERROR (errCode)); | ||
507 | #endif | 499 | #endif |
508 | if (NULL != (receive_handler = conn->receiver_handler)) | 500 | if (NULL != (receive_handler = conn->receiver_handler)) |
509 | { | 501 | { |
510 | receive_handler_cls = conn->receiver_handler_cls; | 502 | receive_handler_cls = conn->receiver_handler_cls; |
511 | conn->receiver_handler = NULL; | 503 | conn->receiver_handler = NULL; |
512 | receive_handler (receive_handler_cls, NULL); | 504 | receive_handler (receive_handler_cls, NULL); |
513 | } | ||
514 | return; | ||
515 | } | 505 | } |
506 | return; | ||
507 | } | ||
516 | 508 | ||
517 | /* FIXME: optimize for common fast case where buf contains the | 509 | /* FIXME: optimize for common fast case where buf contains the |
518 | entire message and we need no copying... */ | 510 | * entire message and we need no copying... */ |
519 | 511 | ||
520 | 512 | ||
521 | /* slow path: append to array */ | 513 | /* slow path: append to array */ |
@@ -528,12 +520,12 @@ receive_helper (void *cls, | |||
528 | /* check for timeout */ | 520 | /* check for timeout */ |
529 | remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout); | 521 | remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout); |
530 | if (remaining.rel_value == 0) | 522 | if (remaining.rel_value == 0) |
531 | { | 523 | { |
532 | /* signal timeout! */ | 524 | /* signal timeout! */ |
533 | if (NULL != conn->receiver_handler) | 525 | if (NULL != conn->receiver_handler) |
534 | conn->receiver_handler (conn->receiver_handler_cls, NULL); | 526 | conn->receiver_handler (conn->receiver_handler_cls, NULL); |
535 | return; | 527 | return; |
536 | } | 528 | } |
537 | /* back to receive -- either for more data or to call callback! */ | 529 | /* back to receive -- either for more data or to call callback! */ |
538 | GNUNET_CLIENT_receive (conn, | 530 | GNUNET_CLIENT_receive (conn, |
539 | conn->receiver_handler, | 531 | conn->receiver_handler, |
@@ -553,7 +545,7 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
553 | struct GNUNET_CLIENT_Connection *sock = cls; | 545 | struct GNUNET_CLIENT_Connection *sock = cls; |
554 | GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler; | 546 | GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler; |
555 | const struct GNUNET_MessageHeader *cmsg = | 547 | const struct GNUNET_MessageHeader *cmsg = |
556 | (const struct GNUNET_MessageHeader *) sock->received_buf; | 548 | (const struct GNUNET_MessageHeader *) sock->received_buf; |
557 | void *handler_cls = sock->receiver_handler_cls; | 549 | void *handler_cls = sock->receiver_handler_cls; |
558 | uint16_t msize = ntohs (cmsg->size); | 550 | uint16_t msize = ntohs (cmsg->size); |
559 | char mbuf[msize]; | 551 | char mbuf[msize]; |
@@ -561,9 +553,8 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
561 | 553 | ||
562 | #if DEBUG_CLIENT | 554 | #if DEBUG_CLIENT |
563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
564 | "Received message of type %u and size %u\n", | 556 | "Received message of type %u and size %u\n", |
565 | ntohs (cmsg->type), | 557 | ntohs (cmsg->type), msize); |
566 | msize); | ||
567 | #endif | 558 | #endif |
568 | sock->receive_task = GNUNET_SCHEDULER_NO_TASK; | 559 | sock->receive_task = GNUNET_SCHEDULER_NO_TASK; |
569 | GNUNET_assert (GNUNET_YES == sock->msg_complete); | 560 | GNUNET_assert (GNUNET_YES == sock->msg_complete); |
@@ -594,32 +585,32 @@ GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, | |||
594 | void *handler_cls, struct GNUNET_TIME_Relative timeout) | 585 | void *handler_cls, struct GNUNET_TIME_Relative timeout) |
595 | { | 586 | { |
596 | if (sock->sock == NULL) | 587 | if (sock->sock == NULL) |
597 | { | 588 | { |
598 | /* already disconnected, fail instantly! */ | 589 | /* already disconnected, fail instantly! */ |
599 | GNUNET_break (0); /* this should not happen in well-written code! */ | 590 | GNUNET_break (0); /* this should not happen in well-written code! */ |
600 | if (NULL != handler) | 591 | if (NULL != handler) |
601 | handler (handler_cls, NULL); | 592 | handler (handler_cls, NULL); |
602 | return; | 593 | return; |
603 | } | 594 | } |
604 | sock->receiver_handler = handler; | 595 | sock->receiver_handler = handler; |
605 | sock->receiver_handler_cls = handler_cls; | 596 | sock->receiver_handler_cls = handler_cls; |
606 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); | 597 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); |
607 | if (GNUNET_YES == sock->msg_complete) | 598 | if (GNUNET_YES == sock->msg_complete) |
608 | { | 599 | { |
609 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task); | 600 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task); |
610 | sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock); | 601 | sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock); |
611 | } | 602 | } |
612 | else | 603 | else |
613 | { | 604 | { |
614 | GNUNET_assert (sock->in_receive == GNUNET_NO); | 605 | GNUNET_assert (sock->in_receive == GNUNET_NO); |
615 | sock->in_receive = GNUNET_YES; | 606 | sock->in_receive = GNUNET_YES; |
616 | #if DEBUG_CLIENT | 607 | #if DEBUG_CLIENT |
617 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n"); | 608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n"); |
618 | #endif | 609 | #endif |
619 | GNUNET_CONNECTION_receive (sock->sock, | 610 | GNUNET_CONNECTION_receive (sock->sock, |
620 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 611 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
621 | timeout, &receive_helper, sock); | 612 | timeout, &receive_helper, sock); |
622 | } | 613 | } |
623 | } | 614 | } |
624 | 615 | ||
625 | 616 | ||
@@ -630,8 +621,7 @@ static void | |||
630 | service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) | 621 | service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) |
631 | { | 622 | { |
632 | GNUNET_SCHEDULER_add_continuation (task, | 623 | GNUNET_SCHEDULER_add_continuation (task, |
633 | task_cls, | 624 | task_cls, GNUNET_SCHEDULER_REASON_TIMEOUT); |
634 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
635 | } | 625 | } |
636 | 626 | ||
637 | 627 | ||
@@ -645,23 +635,24 @@ static void | |||
645 | confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 635 | confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg) |
646 | { | 636 | { |
647 | struct GNUNET_CLIENT_Connection *conn = cls; | 637 | struct GNUNET_CLIENT_Connection *conn = cls; |
638 | |||
648 | /* We may want to consider looking at the reply in more | 639 | /* We may want to consider looking at the reply in more |
649 | detail in the future, for example, is this the | 640 | * detail in the future, for example, is this the |
650 | correct service? FIXME! */ | 641 | * correct service? FIXME! */ |
651 | if (msg != NULL) | 642 | if (msg != NULL) |
652 | { | 643 | { |
653 | #if DEBUG_CLIENT | 644 | #if DEBUG_CLIENT |
654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 645 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
655 | "Received confirmation that service is running.\n"); | 646 | "Received confirmation that service is running.\n"); |
656 | #endif | 647 | #endif |
657 | GNUNET_SCHEDULER_add_continuation (conn->test_cb, | 648 | GNUNET_SCHEDULER_add_continuation (conn->test_cb, |
658 | conn->test_cb_cls, | 649 | conn->test_cb_cls, |
659 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 650 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
660 | } | 651 | } |
661 | else | 652 | else |
662 | { | 653 | { |
663 | service_test_error (conn->test_cb, conn->test_cb_cls); | 654 | service_test_error (conn->test_cb, conn->test_cb_cls); |
664 | } | 655 | } |
665 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); | 656 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); |
666 | } | 657 | } |
667 | 658 | ||
@@ -682,26 +673,26 @@ write_test (void *cls, size_t size, void *buf) | |||
682 | struct GNUNET_MessageHeader *msg; | 673 | struct GNUNET_MessageHeader *msg; |
683 | 674 | ||
684 | if (size < sizeof (struct GNUNET_MessageHeader)) | 675 | if (size < sizeof (struct GNUNET_MessageHeader)) |
685 | { | 676 | { |
686 | #if DEBUG_CLIENT | 677 | #if DEBUG_CLIENT |
687 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 678 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
688 | _("Failure to transmit TEST request.\n")); | 679 | _("Failure to transmit TEST request.\n")); |
689 | #endif | 680 | #endif |
690 | service_test_error (conn->test_cb, conn->test_cb_cls); | 681 | service_test_error (conn->test_cb, conn->test_cb_cls); |
691 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); | 682 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); |
692 | return 0; /* client disconnected */ | 683 | return 0; /* client disconnected */ |
693 | } | 684 | } |
694 | #if DEBUG_CLIENT | 685 | #if DEBUG_CLIENT |
695 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 686 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST"); |
696 | "Transmitting `%s' request.\n", "TEST"); | ||
697 | #endif | 687 | #endif |
698 | msg = (struct GNUNET_MessageHeader *) buf; | 688 | msg = (struct GNUNET_MessageHeader *) buf; |
699 | msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); | 689 | msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); |
700 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | 690 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); |
701 | GNUNET_CLIENT_receive (conn, | 691 | GNUNET_CLIENT_receive (conn, |
702 | &confirm_handler, | 692 | &confirm_handler, |
703 | conn, | 693 | conn, |
704 | GNUNET_TIME_absolute_get_remaining (conn->test_deadline)); | 694 | GNUNET_TIME_absolute_get_remaining |
695 | (conn->test_deadline)); | ||
705 | return sizeof (struct GNUNET_MessageHeader); | 696 | return sizeof (struct GNUNET_MessageHeader); |
706 | } | 697 | } |
707 | 698 | ||
@@ -740,60 +731,53 @@ GNUNET_CLIENT_service_test (const char *service, | |||
740 | struct sockaddr_un s_un; | 731 | struct sockaddr_un s_un; |
741 | size_t slen; | 732 | size_t slen; |
742 | char *unixpath; | 733 | char *unixpath; |
743 | 734 | ||
744 | unixpath = NULL; | 735 | unixpath = NULL; |
745 | if ( (GNUNET_OK == | 736 | 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? */ |
746 | GNUNET_CONFIGURATION_get_value_string (cfg, | 737 | { |
747 | service, | 738 | if (strlen (unixpath) >= sizeof (s_un.sun_path)) |
748 | "UNIXPATH", &unixpath)) && | ||
749 | (0 < strlen (unixpath)) ) /* We have a non-NULL unixpath, does that mean it's valid? */ | ||
750 | { | 739 | { |
751 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 740 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
752 | { | 741 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), |
753 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 742 | unixpath, sizeof (s_un.sun_path)); |
754 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | 743 | } |
755 | unixpath, | 744 | else |
756 | sizeof(s_un.sun_path)); | 745 | { |
757 | } | 746 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); |
758 | else | 747 | if (sock != NULL) |
759 | { | 748 | { |
760 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); | 749 | memset (&s_un, 0, sizeof (s_un)); |
761 | if (sock != NULL) | 750 | s_un.sun_family = AF_UNIX; |
762 | { | 751 | slen = strlen (unixpath) + 1; |
763 | memset (&s_un, 0, sizeof (s_un)); | 752 | if (slen >= sizeof (s_un.sun_path)) |
764 | s_un.sun_family = AF_UNIX; | 753 | slen = sizeof (s_un.sun_path) - 1; |
765 | slen = strlen (unixpath) + 1; | 754 | memcpy (s_un.sun_path, unixpath, slen); |
766 | if (slen >= sizeof (s_un.sun_path)) | 755 | s_un.sun_path[slen] = '\0'; |
767 | slen = sizeof (s_un.sun_path) - 1; | 756 | slen = sizeof (struct sockaddr_un); |
768 | memcpy (s_un.sun_path, | ||
769 | unixpath, | ||
770 | slen); | ||
771 | s_un.sun_path[slen] = '\0'; | ||
772 | slen = sizeof (struct sockaddr_un); | ||
773 | #if LINUX | 757 | #if LINUX |
774 | s_un.sun_path[0] = '\0'; | 758 | s_un.sun_path[0] = '\0'; |
775 | #endif | 759 | #endif |
776 | #if HAVE_SOCKADDR_IN_SIN_LEN | 760 | #if HAVE_SOCKADDR_IN_SIN_LEN |
777 | s_un.sun_len = (u_char) slen; | 761 | s_un.sun_len = (u_char) slen; |
778 | #endif | 762 | #endif |
779 | if (GNUNET_OK != | 763 | if (GNUNET_OK != |
780 | GNUNET_NETWORK_socket_bind (sock, | 764 | GNUNET_NETWORK_socket_bind (sock, |
781 | (const struct sockaddr*) &s_un, | 765 | (const struct sockaddr *) &s_un, |
782 | slen)) | 766 | slen)) |
783 | { | 767 | { |
784 | /* failed to bind => service must be running */ | 768 | /* failed to bind => service must be running */ |
785 | GNUNET_free (unixpath); | 769 | GNUNET_free (unixpath); |
786 | (void) GNUNET_NETWORK_socket_close (sock); | 770 | (void) GNUNET_NETWORK_socket_close (sock); |
787 | GNUNET_SCHEDULER_add_continuation (task, | 771 | GNUNET_SCHEDULER_add_continuation (task, |
788 | task_cls, | 772 | task_cls, |
789 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 773 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
790 | return; | 774 | return; |
791 | } | 775 | } |
792 | (void) GNUNET_NETWORK_socket_close (sock); | 776 | (void) GNUNET_NETWORK_socket_close (sock); |
793 | } | 777 | } |
794 | /* let's try IP */ | 778 | /* let's try IP */ |
795 | } | ||
796 | } | 779 | } |
780 | } | ||
797 | GNUNET_free_non_null (unixpath); | 781 | GNUNET_free_non_null (unixpath); |
798 | } | 782 | } |
799 | #endif | 783 | #endif |
@@ -807,128 +791,126 @@ GNUNET_CLIENT_service_test (const char *service, | |||
807 | (port > 65535) || | 791 | (port > 65535) || |
808 | (GNUNET_OK != | 792 | (GNUNET_OK != |
809 | GNUNET_CONFIGURATION_get_value_string (cfg, | 793 | GNUNET_CONFIGURATION_get_value_string (cfg, |
810 | service, | 794 | service, "HOSTNAME", &hostname))) |
811 | "HOSTNAME", &hostname))) | 795 | { |
812 | { | 796 | /* UNIXPATH failed (if possible) AND IP failed => error */ |
813 | /* UNIXPATH failed (if possible) AND IP failed => error */ | 797 | service_test_error (task, task_cls); |
814 | service_test_error (task, task_cls); | 798 | return; |
815 | return; | 799 | } |
816 | } | 800 | |
817 | |||
818 | if (0 == strcmp ("localhost", hostname) | 801 | if (0 == strcmp ("localhost", hostname) |
819 | #if WINDOWS | 802 | #if WINDOWS |
820 | && 0 | 803 | && 0 |
821 | #endif | 804 | #endif |
822 | ) | 805 | ) |
823 | { | 806 | { |
824 | /* can test using 'bind' */ | 807 | /* can test using 'bind' */ |
825 | struct sockaddr_in s_in; | 808 | struct sockaddr_in s_in; |
826 | 809 | ||
827 | memset (&s_in, 0, sizeof (s_in)); | 810 | memset (&s_in, 0, sizeof (s_in)); |
828 | #if HAVE_SOCKADDR_IN_SIN_LEN | 811 | #if HAVE_SOCKADDR_IN_SIN_LEN |
829 | s_in.sin_len = saddrlens[1]; | 812 | s_in.sin_len = saddrlens[1]; |
830 | #endif | 813 | #endif |
831 | s_in.sin_family = AF_INET; | 814 | s_in.sin_family = AF_INET; |
832 | s_in.sin_port = htons (port); | 815 | s_in.sin_port = htons (port); |
833 | 816 | ||
834 | sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); | 817 | sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); |
835 | if (sock != NULL) | 818 | if (sock != NULL) |
836 | { | 819 | { |
837 | if (GNUNET_OK != | 820 | if (GNUNET_OK != |
838 | GNUNET_NETWORK_socket_bind (sock, | 821 | GNUNET_NETWORK_socket_bind (sock, |
839 | (const struct sockaddr*) &s_in, | 822 | (const struct sockaddr *) &s_in, |
840 | sizeof (s_in))) | 823 | sizeof (s_in))) |
841 | { | 824 | { |
842 | /* failed to bind => service must be running */ | 825 | /* failed to bind => service must be running */ |
843 | GNUNET_free (hostname); | 826 | GNUNET_free (hostname); |
844 | (void) GNUNET_NETWORK_socket_close (sock); | 827 | (void) GNUNET_NETWORK_socket_close (sock); |
845 | GNUNET_SCHEDULER_add_continuation (task, | 828 | GNUNET_SCHEDULER_add_continuation (task, |
846 | task_cls, | 829 | task_cls, |
847 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 830 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
848 | return; | 831 | return; |
849 | } | 832 | } |
850 | (void) GNUNET_NETWORK_socket_close (sock); | 833 | (void) GNUNET_NETWORK_socket_close (sock); |
851 | } | ||
852 | } | 834 | } |
835 | } | ||
853 | 836 | ||
854 | if (0 == strcmp ("ip6-localhost", hostname) | 837 | if (0 == strcmp ("ip6-localhost", hostname) |
855 | #if WINDOWS | 838 | #if WINDOWS |
856 | && 0 | 839 | && 0 |
857 | #endif | 840 | #endif |
858 | ) | 841 | ) |
859 | { | 842 | { |
860 | /* can test using 'bind' */ | 843 | /* can test using 'bind' */ |
861 | struct sockaddr_in6 s_in6; | 844 | struct sockaddr_in6 s_in6; |
862 | 845 | ||
863 | memset (&s_in6, 0, sizeof (s_in6)); | 846 | memset (&s_in6, 0, sizeof (s_in6)); |
864 | #if HAVE_SOCKADDR_IN_SIN_LEN | 847 | #if HAVE_SOCKADDR_IN_SIN_LEN |
865 | s_in6.sin6_len = saddrlens[1]; | 848 | s_in6.sin6_len = saddrlens[1]; |
866 | #endif | 849 | #endif |
867 | s_in6.sin6_family = AF_INET6; | 850 | s_in6.sin6_family = AF_INET6; |
868 | s_in6.sin6_port = htons (port); | 851 | s_in6.sin6_port = htons (port); |
869 | 852 | ||
870 | sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); | 853 | sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); |
871 | if (sock != NULL) | 854 | if (sock != NULL) |
872 | { | 855 | { |
873 | if (GNUNET_OK != | 856 | if (GNUNET_OK != |
874 | GNUNET_NETWORK_socket_bind (sock, | 857 | GNUNET_NETWORK_socket_bind (sock, |
875 | (const struct sockaddr*) &s_in6, | 858 | (const struct sockaddr *) &s_in6, |
876 | sizeof (s_in6))) | 859 | sizeof (s_in6))) |
877 | { | 860 | { |
878 | /* failed to bind => service must be running */ | 861 | /* failed to bind => service must be running */ |
879 | GNUNET_free (hostname); | 862 | GNUNET_free (hostname); |
880 | (void) GNUNET_NETWORK_socket_close (sock); | 863 | (void) GNUNET_NETWORK_socket_close (sock); |
881 | GNUNET_SCHEDULER_add_continuation (task, | 864 | GNUNET_SCHEDULER_add_continuation (task, |
882 | task_cls, | 865 | task_cls, |
883 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 866 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
884 | return; | 867 | return; |
885 | } | 868 | } |
886 | (void) GNUNET_NETWORK_socket_close (sock); | 869 | (void) GNUNET_NETWORK_socket_close (sock); |
887 | } | ||
888 | } | 870 | } |
871 | } | ||
889 | 872 | ||
890 | if (( (0 == strcmp ("localhost", hostname)) || | 873 | if (((0 == strcmp ("localhost", hostname)) || |
891 | (0 == strcmp ("ip6-localhost", hostname))) | 874 | (0 == strcmp ("ip6-localhost", hostname))) |
892 | #if WINDOWS | 875 | #if WINDOWS |
893 | && 0 | 876 | && 0 |
894 | #endif | 877 | #endif |
895 | ) | 878 | ) |
896 | { | 879 | { |
897 | /* all binds succeeded => claim service not running right now */ | 880 | /* all binds succeeded => claim service not running right now */ |
898 | GNUNET_free_non_null (hostname); | 881 | GNUNET_free_non_null (hostname); |
899 | service_test_error (task, task_cls); | 882 | service_test_error (task, task_cls); |
900 | return; | 883 | return; |
901 | } | 884 | } |
902 | GNUNET_free_non_null (hostname); | 885 | GNUNET_free_non_null (hostname); |
903 | 886 | ||
904 | /* non-localhost, try 'connect' method */ | 887 | /* non-localhost, try 'connect' method */ |
905 | conn = GNUNET_CLIENT_connect (service, cfg); | 888 | conn = GNUNET_CLIENT_connect (service, cfg); |
906 | if (conn == NULL) | 889 | if (conn == NULL) |
907 | { | 890 | { |
908 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 891 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
909 | _ | 892 | _ |
910 | ("Could not connect to service `%s', must not be running.\n"), | 893 | ("Could not connect to service `%s', must not be running.\n"), |
911 | service); | 894 | service); |
912 | service_test_error (task, task_cls); | 895 | service_test_error (task, task_cls); |
913 | return; | 896 | return; |
914 | } | 897 | } |
915 | conn->test_cb = task; | 898 | conn->test_cb = task; |
916 | conn->test_cb_cls = task_cls; | 899 | conn->test_cb_cls = task_cls; |
917 | conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); | 900 | conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); |
918 | 901 | ||
919 | if (NULL == GNUNET_CLIENT_notify_transmit_ready (conn, | 902 | if (NULL == GNUNET_CLIENT_notify_transmit_ready (conn, |
920 | sizeof (struct GNUNET_MessageHeader), | 903 | sizeof (struct |
921 | timeout, | 904 | GNUNET_MessageHeader), |
922 | GNUNET_YES, | 905 | timeout, GNUNET_YES, |
923 | &write_test, conn)) | 906 | &write_test, conn)) |
924 | { | 907 | { |
925 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 908 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
926 | _("Failure to transmit request to service `%s'\n"), | 909 | _("Failure to transmit request to service `%s'\n"), service); |
927 | service); | 910 | service_test_error (task, task_cls); |
928 | service_test_error (task, task_cls); | 911 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); |
929 | GNUNET_CLIENT_disconnect (conn, GNUNET_NO); | 912 | return; |
930 | return; | 913 | } |
931 | } | ||
932 | } | 914 | } |
933 | 915 | ||
934 | 916 | ||
@@ -953,61 +935,60 @@ static size_t client_notify (void *cls, size_t size, void *buf); | |||
953 | * @param tc unused | 935 | * @param tc unused |
954 | */ | 936 | */ |
955 | static void | 937 | static void |
956 | client_delayed_retry (void *cls, | 938 | client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
957 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
958 | { | 939 | { |
959 | struct GNUNET_CLIENT_TransmitHandle *th = cls; | 940 | struct GNUNET_CLIENT_TransmitHandle *th = cls; |
960 | struct GNUNET_TIME_Relative delay; | 941 | struct GNUNET_TIME_Relative delay; |
961 | 942 | ||
962 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 943 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
963 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 944 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
964 | { | 945 | { |
965 | #if DEBUG_CLIENT | 946 | #if DEBUG_CLIENT |
966 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 947 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
967 | "Transmission failed due to shutdown.\n"); | 948 | "Transmission failed due to shutdown.\n"); |
968 | #endif | 949 | #endif |
969 | th->sock->th = NULL; | 950 | th->sock->th = NULL; |
970 | th->notify (th->notify_cls, 0, NULL); | 951 | th->notify (th->notify_cls, 0, NULL); |
971 | GNUNET_free (th); | 952 | GNUNET_free (th); |
972 | return; | 953 | return; |
973 | } | 954 | } |
974 | th->sock->sock = do_connect (th->sock->service_name, | 955 | th->sock->sock = do_connect (th->sock->service_name, |
975 | th->sock->cfg, | 956 | th->sock->cfg, th->sock->attempts++); |
976 | th->sock->attempts++); | ||
977 | if (NULL == th->sock->sock) | 957 | if (NULL == th->sock->sock) |
978 | { | 958 | { |
979 | /* could happen if we're out of sockets */ | 959 | /* could happen if we're out of sockets */ |
980 | delay = GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (th->timeout), | 960 | delay = |
981 | th->sock->back_off); | 961 | GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining |
982 | th->sock->back_off | 962 | (th->timeout), th->sock->back_off); |
983 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (th->sock->back_off, 2), | 963 | th->sock->back_off = |
984 | GNUNET_TIME_UNIT_SECONDS); | 964 | GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply |
965 | (th->sock->back_off, 2), | ||
966 | GNUNET_TIME_UNIT_SECONDS); | ||
985 | #if DEBUG_CLIENT | 967 | #if DEBUG_CLIENT |
986 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 968 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
987 | "Transmission failed %u times, trying again in %llums.\n", | 969 | "Transmission failed %u times, trying again in %llums.\n", |
988 | MAX_ATTEMPTS - th->attempts_left, | 970 | MAX_ATTEMPTS - th->attempts_left, |
989 | (unsigned long long) delay.rel_value); | 971 | (unsigned long long) delay.rel_value); |
990 | #endif | 972 | #endif |
991 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, | 973 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, |
992 | &client_delayed_retry, | 974 | &client_delayed_retry, |
993 | th); | 975 | th); |
994 | return; | 976 | return; |
995 | } | 977 | } |
996 | GNUNET_CONNECTION_ignore_shutdown (th->sock->sock, | 978 | GNUNET_CONNECTION_ignore_shutdown (th->sock->sock, th->sock->ignore_shutdown); |
997 | th->sock->ignore_shutdown); | ||
998 | th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, | 979 | th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, |
999 | th->size, | 980 | th->size, |
1000 | GNUNET_TIME_absolute_get_remaining | 981 | GNUNET_TIME_absolute_get_remaining |
1001 | (th->timeout), | 982 | (th->timeout), |
1002 | &client_notify, th); | 983 | &client_notify, th); |
1003 | if (th->th == NULL) | 984 | if (th->th == NULL) |
1004 | { | 985 | { |
1005 | GNUNET_break (0); | 986 | GNUNET_break (0); |
1006 | th->sock->th = NULL; | 987 | th->sock->th = NULL; |
1007 | th->notify (th->notify_cls, 0, NULL); | 988 | th->notify (th->notify_cls, 0, NULL); |
1008 | GNUNET_free (th); | 989 | GNUNET_free (th); |
1009 | return; | 990 | return; |
1010 | } | 991 | } |
1011 | } | 992 | } |
1012 | 993 | ||
1013 | 994 | ||
@@ -1030,47 +1011,49 @@ client_notify (void *cls, size_t size, void *buf) | |||
1030 | th->th = NULL; | 1011 | th->th = NULL; |
1031 | th->sock->th = NULL; | 1012 | th->sock->th = NULL; |
1032 | if (buf == NULL) | 1013 | if (buf == NULL) |
1014 | { | ||
1015 | delay = GNUNET_TIME_absolute_get_remaining (th->timeout); | ||
1016 | delay.rel_value /= 2; | ||
1017 | if ((0 != | ||
1018 | (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) || | ||
1019 | (GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) || | ||
1020 | (delay.rel_value < 1)) | ||
1033 | { | 1021 | { |
1034 | delay = GNUNET_TIME_absolute_get_remaining (th->timeout); | ||
1035 | delay.rel_value /= 2; | ||
1036 | if ( (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) || | ||
1037 | (GNUNET_YES != th->auto_retry) || | ||
1038 | (0 == --th->attempts_left) || | ||
1039 | (delay.rel_value < 1) ) | ||
1040 | { | ||
1041 | #if DEBUG_CLIENT | 1022 | #if DEBUG_CLIENT |
1042 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1023 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1043 | "Transmission failed %u times, giving up.\n", | 1024 | "Transmission failed %u times, giving up.\n", |
1044 | MAX_ATTEMPTS - th->attempts_left); | 1025 | MAX_ATTEMPTS - th->attempts_left); |
1045 | #endif | 1026 | #endif |
1046 | GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL)); | 1027 | GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL)); |
1047 | GNUNET_free (th); | 1028 | GNUNET_free (th); |
1048 | return 0; | 1029 | return 0; |
1049 | } | 1030 | } |
1050 | /* auto-retry */ | 1031 | /* auto-retry */ |
1051 | #if DEBUG_CLIENT | 1032 | #if DEBUG_CLIENT |
1052 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1033 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1053 | "Failed to connect to `%s', automatically trying again.\n", | 1034 | "Failed to connect to `%s', automatically trying again.\n", |
1054 | th->sock->service_name); | 1035 | th->sock->service_name); |
1055 | #endif | 1036 | #endif |
1056 | GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); | 1037 | GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); |
1057 | th->sock->sock = NULL; | 1038 | th->sock->sock = NULL; |
1058 | delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); | 1039 | delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); |
1059 | th->sock->back_off | 1040 | th->sock->back_off |
1060 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (th->sock->back_off, 2), | 1041 | = |
1061 | GNUNET_TIME_UNIT_SECONDS); | 1042 | GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply |
1043 | (th->sock->back_off, 2), | ||
1044 | GNUNET_TIME_UNIT_SECONDS); | ||
1062 | #if DEBUG_CLIENT | 1045 | #if DEBUG_CLIENT |
1063 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1046 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1064 | "Transmission failed %u times, trying again in %llums.\n", | 1047 | "Transmission failed %u times, trying again in %llums.\n", |
1065 | MAX_ATTEMPTS - th->attempts_left, | 1048 | MAX_ATTEMPTS - th->attempts_left, |
1066 | (unsigned long long) delay.rel_value); | 1049 | (unsigned long long) delay.rel_value); |
1067 | #endif | 1050 | #endif |
1068 | th->sock->th = th; | 1051 | th->sock->th = th; |
1069 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, | 1052 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, |
1070 | &client_delayed_retry, | 1053 | &client_delayed_retry, |
1071 | th); | 1054 | th); |
1072 | return 0; | 1055 | return 0; |
1073 | } | 1056 | } |
1074 | GNUNET_assert (size >= th->size); | 1057 | GNUNET_assert (size >= th->size); |
1075 | ret = th->notify (th->notify_cls, size, buf); | 1058 | ret = th->notify (th->notify_cls, size, buf); |
1076 | GNUNET_free (th); | 1059 | GNUNET_free (th); |
@@ -1108,12 +1091,12 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | |||
1108 | struct GNUNET_CLIENT_TransmitHandle *th; | 1091 | struct GNUNET_CLIENT_TransmitHandle *th; |
1109 | 1092 | ||
1110 | if (NULL != sock->th) | 1093 | if (NULL != sock->th) |
1111 | { | 1094 | { |
1112 | /* If this breaks, you most likley called this function twice without waiting | 1095 | /* If this breaks, you most likley called this function twice without waiting |
1113 | * for completion or canceling the request */ | 1096 | * for completion or canceling the request */ |
1114 | GNUNET_break (0); | 1097 | GNUNET_break (0); |
1115 | return NULL; | 1098 | return NULL; |
1116 | } | 1099 | } |
1117 | th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); | 1100 | th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); |
1118 | th->sock = sock; | 1101 | th->sock = sock; |
1119 | th->size = size; | 1102 | th->size = size; |
@@ -1124,26 +1107,26 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | |||
1124 | th->attempts_left = MAX_ATTEMPTS; | 1107 | th->attempts_left = MAX_ATTEMPTS; |
1125 | sock->th = th; | 1108 | sock->th = th; |
1126 | if (sock->sock == NULL) | 1109 | if (sock->sock == NULL) |
1127 | { | 1110 | { |
1128 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (sock->back_off, | 1111 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (sock->back_off, |
1129 | &client_delayed_retry, | 1112 | &client_delayed_retry, |
1130 | th); | 1113 | th); |
1131 | 1114 | ||
1132 | } | 1115 | } |
1133 | else | 1116 | else |
1117 | { | ||
1118 | th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | ||
1119 | size, | ||
1120 | timeout, | ||
1121 | &client_notify, th); | ||
1122 | if (NULL == th->th) | ||
1134 | { | 1123 | { |
1135 | th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | 1124 | GNUNET_break (0); |
1136 | size, | 1125 | GNUNET_free (th); |
1137 | timeout, | 1126 | sock->th = NULL; |
1138 | &client_notify, th); | 1127 | return NULL; |
1139 | if (NULL == th->th) | ||
1140 | { | ||
1141 | GNUNET_break (0); | ||
1142 | GNUNET_free (th); | ||
1143 | sock->th = NULL; | ||
1144 | return NULL; | ||
1145 | } | ||
1146 | } | 1128 | } |
1129 | } | ||
1147 | return th; | 1130 | return th; |
1148 | } | 1131 | } |
1149 | 1132 | ||
@@ -1158,16 +1141,16 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct | |||
1158 | GNUNET_CLIENT_TransmitHandle *th) | 1141 | GNUNET_CLIENT_TransmitHandle *th) |
1159 | { | 1142 | { |
1160 | if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK) | 1143 | if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK) |
1161 | { | 1144 | { |
1162 | GNUNET_assert (NULL == th->th); | 1145 | GNUNET_assert (NULL == th->th); |
1163 | GNUNET_SCHEDULER_cancel (th->reconnect_task); | 1146 | GNUNET_SCHEDULER_cancel (th->reconnect_task); |
1164 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 1147 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
1165 | } | 1148 | } |
1166 | else | 1149 | else |
1167 | { | 1150 | { |
1168 | GNUNET_assert (NULL != th->th); | 1151 | GNUNET_assert (NULL != th->th); |
1169 | GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); | 1152 | GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); |
1170 | } | 1153 | } |
1171 | th->sock->th = NULL; | 1154 | th->sock->th = NULL; |
1172 | GNUNET_free (th); | 1155 | GNUNET_free (th); |
1173 | } | 1156 | } |
@@ -1193,16 +1176,17 @@ transmit_for_response (void *cls, size_t size, void *buf) | |||
1193 | tc->sock->tag = NULL; | 1176 | tc->sock->tag = NULL; |
1194 | msize = ntohs (tc->hdr->size); | 1177 | msize = ntohs (tc->hdr->size); |
1195 | if (NULL == buf) | 1178 | if (NULL == buf) |
1196 | { | 1179 | { |
1197 | #if DEBUG_CLIENT | 1180 | #if DEBUG_CLIENT |
1198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1181 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1199 | _("Could not submit request, not expecting to receive a response.\n")); | 1182 | _ |
1183 | ("Could not submit request, not expecting to receive a response.\n")); | ||
1200 | #endif | 1184 | #endif |
1201 | if (NULL != tc->rn) | 1185 | if (NULL != tc->rn) |
1202 | tc->rn (tc->rn_cls, NULL); | 1186 | tc->rn (tc->rn_cls, NULL); |
1203 | GNUNET_free (tc); | 1187 | GNUNET_free (tc); |
1204 | return 0; | 1188 | return 0; |
1205 | } | 1189 | } |
1206 | GNUNET_assert (size >= msize); | 1190 | GNUNET_assert (size >= msize); |
1207 | memcpy (buf, tc->hdr, msize); | 1191 | memcpy (buf, tc->hdr, msize); |
1208 | GNUNET_CLIENT_receive (tc->sock, | 1192 | GNUNET_CLIENT_receive (tc->sock, |
@@ -1263,13 +1247,12 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection | |||
1263 | msize, | 1247 | msize, |
1264 | timeout, | 1248 | timeout, |
1265 | auto_retry, | 1249 | auto_retry, |
1266 | &transmit_for_response, | 1250 | &transmit_for_response, tc)) |
1267 | tc)) | 1251 | { |
1268 | { | 1252 | GNUNET_break (0); |
1269 | GNUNET_break (0); | 1253 | GNUNET_free (tc); |
1270 | GNUNET_free (tc); | 1254 | return GNUNET_SYSERR; |
1271 | return GNUNET_SYSERR; | 1255 | } |
1272 | } | ||
1273 | sock->tag = tc; | 1256 | sock->tag = tc; |
1274 | return GNUNET_OK; | 1257 | return GNUNET_OK; |
1275 | } | 1258 | } |