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