diff options
Diffstat (limited to 'src/util/client.c')
-rw-r--r-- | src/util/client.c | 804 |
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 | */ |
260 | static struct GNUNET_CONNECTION_Handle * | 260 | static struct GNUNET_CONNECTION_Handle * |
261 | do_connect (const char *service_name, | 261 | do_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 | */ |
361 | struct GNUNET_CLIENT_Connection * | 358 | struct GNUNET_CLIENT_Connection * |
362 | GNUNET_CLIENT_connect (const char *service_name, | 359 | GNUNET_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 | */ |
394 | void | 391 | void |
395 | GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, | 392 | GNUNET_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 | */ |
456 | static void | 453 | static void |
457 | receive_helper (void *cls, const void *buf, size_t available, | 454 | receive_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 | */ |
557 | void | 553 | void |
558 | GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, | 554 | GNUNET_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 | |||
596 | service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) | 591 | service_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 | */ |
684 | void | 679 | void |
685 | GNUNET_CLIENT_service_test (const char *service, | 680 | GNUNET_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 | */ |
892 | static size_t client_notify (void *cls, size_t size, void *buf); | 883 | static size_t |
884 | client_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 | */ |
902 | static void | 894 | static void |
903 | client_delayed_retry (void *cls, | 895 | client_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 | */ |
1044 | struct GNUNET_CLIENT_TransmitHandle * | 1035 | struct GNUNET_CLIENT_TransmitHandle * |
1045 | GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | 1036 | GNUNET_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 | */ |
1099 | void | 1090 | void |
1100 | GNUNET_CLIENT_notify_transmit_ready_cancel (struct | 1091 | GNUNET_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 | */ |
1180 | int | 1170 | int |
1181 | GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection | 1171 | GNUNET_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 | } |