diff options
Diffstat (limited to 'src/util/connection.c')
-rw-r--r-- | src/util/connection.c | 1015 |
1 files changed, 500 insertions, 515 deletions
diff --git a/src/util/connection.c b/src/util/connection.c index cd0035a8f..61c26673b 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -333,8 +333,7 @@ GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) | |||
333 | * @return the boxed socket handle | 333 | * @return the boxed socket handle |
334 | */ | 334 | */ |
335 | struct GNUNET_CONNECTION_Handle * | 335 | struct GNUNET_CONNECTION_Handle * |
336 | GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle | 336 | GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) |
337 | *osSocket) | ||
338 | { | 337 | { |
339 | struct GNUNET_CONNECTION_Handle *ret; | 338 | struct GNUNET_CONNECTION_Handle *ret; |
340 | 339 | ||
@@ -357,8 +356,8 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle | |||
357 | */ | 356 | */ |
358 | struct GNUNET_CONNECTION_Handle * | 357 | struct GNUNET_CONNECTION_Handle * |
359 | GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, | 358 | GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, |
360 | void *access_cls, | 359 | void *access_cls, |
361 | struct GNUNET_NETWORK_Handle *lsock) | 360 | struct GNUNET_NETWORK_Handle *lsock) |
362 | { | 361 | { |
363 | struct GNUNET_CONNECTION_Handle *ret; | 362 | struct GNUNET_CONNECTION_Handle *ret; |
364 | char addr[128]; | 363 | char addr[128]; |
@@ -379,94 +378,94 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, | |||
379 | 378 | ||
380 | addrlen = sizeof (addr); | 379 | addrlen = sizeof (addr); |
381 | sock = | 380 | sock = |
382 | GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen); | 381 | GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen); |
383 | if (NULL == sock) | 382 | if (NULL == sock) |
384 | { | 383 | { |
385 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept"); | 384 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept"); |
386 | return NULL; | 385 | return NULL; |
387 | } | 386 | } |
388 | if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t))) | 387 | if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t))) |
389 | { | 388 | { |
390 | GNUNET_break (0); | 389 | GNUNET_break (0); |
391 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 390 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
392 | return NULL; | 391 | return NULL; |
393 | } | 392 | } |
394 | 393 | ||
395 | sa = (struct sockaddr *) addr; | 394 | sa = (struct sockaddr *) addr; |
396 | v6 = (struct sockaddr_in6 *) addr; | 395 | v6 = (struct sockaddr_in6 *) addr; |
397 | if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) | 396 | if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) |
398 | { | 397 | { |
399 | /* convert to V4 address */ | 398 | /* convert to V4 address */ |
400 | v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); | 399 | v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); |
401 | memset (v4, 0, sizeof (struct sockaddr_in)); | 400 | memset (v4, 0, sizeof (struct sockaddr_in)); |
402 | v4->sin_family = AF_INET; | 401 | v4->sin_family = AF_INET; |
403 | #if HAVE_SOCKADDR_IN_SIN_LEN | 402 | #if HAVE_SOCKADDR_IN_SIN_LEN |
404 | v4->sin_len = (u_char) sizeof (struct sockaddr_in); | 403 | v4->sin_len = (u_char) sizeof (struct sockaddr_in); |
405 | #endif | 404 | #endif |
406 | memcpy (&v4->sin_addr, | 405 | memcpy (&v4->sin_addr, |
407 | &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) - | 406 | &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) - |
408 | sizeof (struct in_addr)], | 407 | sizeof (struct in_addr)], |
409 | sizeof (struct in_addr)); | 408 | sizeof (struct in_addr)); |
410 | v4->sin_port = v6->sin6_port; | 409 | v4->sin_port = v6->sin6_port; |
411 | uaddr = v4; | 410 | uaddr = v4; |
412 | addrlen = sizeof (struct sockaddr_in); | 411 | addrlen = sizeof (struct sockaddr_in); |
413 | } | 412 | } |
414 | else | 413 | else |
415 | { | 414 | { |
416 | uaddr = GNUNET_malloc (addrlen); | 415 | uaddr = GNUNET_malloc (addrlen); |
417 | memcpy (uaddr, addr, addrlen); | 416 | memcpy (uaddr, addr, addrlen); |
418 | } | 417 | } |
419 | gcp = NULL; | 418 | gcp = NULL; |
420 | gc.uid = 0; | 419 | gc.uid = 0; |
421 | gc.gid = 0; | 420 | gc.gid = 0; |
422 | if (sa->sa_family == AF_UNIX) | 421 | if (sa->sa_family == AF_UNIX) |
423 | { | 422 | { |
424 | #if HAVE_GETPEEREID | 423 | #if HAVE_GETPEEREID |
425 | /* most BSDs */ | 424 | /* most BSDs */ |
426 | if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid)) | 425 | if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid)) |
427 | gcp = &gc; | 426 | gcp = &gc; |
428 | #else | 427 | #else |
429 | #ifdef SO_PEERCRED | 428 | #ifdef SO_PEERCRED |
430 | /* largely traditional GNU/Linux */ | 429 | /* largely traditional GNU/Linux */ |
431 | olen = sizeof (uc); | 430 | olen = sizeof (uc); |
432 | if ((0 == | 431 | if ((0 == |
433 | getsockopt (GNUNET_NETWORK_get_fd (sock), SOL_SOCKET, SO_PEERCRED, | 432 | getsockopt (GNUNET_NETWORK_get_fd (sock), SOL_SOCKET, SO_PEERCRED, &uc, |
434 | &uc, &olen)) && (olen == sizeof (uc))) | 433 | &olen)) && (olen == sizeof (uc))) |
435 | { | 434 | { |
436 | gc.uid = uc.uid; | 435 | gc.uid = uc.uid; |
437 | gc.gid = uc.gid; | 436 | gc.gid = uc.gid; |
438 | gcp = &gc; | 437 | gcp = &gc; |
439 | } | 438 | } |
440 | #else | 439 | #else |
441 | #if HAVE_GETPEERUCRED | 440 | #if HAVE_GETPEERUCRED |
442 | /* this is for Solaris 10 */ | 441 | /* this is for Solaris 10 */ |
443 | ucred_t *uc; | 442 | ucred_t *uc; |
444 | 443 | ||
445 | uc = NULL; | 444 | uc = NULL; |
446 | if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc)) | 445 | if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc)) |
447 | { | 446 | { |
448 | gc.uid = ucred_geteuid (uc); | 447 | gc.uid = ucred_geteuid (uc); |
449 | gc.gid = ucred_getegid (uc); | 448 | gc.gid = ucred_getegid (uc); |
450 | gcp = &gc; | 449 | gcp = &gc; |
451 | } | 450 | } |
452 | ucred_free (uc); | 451 | ucred_free (uc); |
453 | #endif | 452 | #endif |
454 | #endif | 453 | #endif |
455 | #endif | 454 | #endif |
456 | } | 455 | } |
457 | 456 | ||
458 | if ((access != NULL) && | 457 | if ((access != NULL) && |
459 | (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) | 458 | (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) |
460 | { | 459 | { |
461 | if (aret == GNUNET_NO) | 460 | if (aret == GNUNET_NO) |
462 | LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"), | 461 | LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"), |
463 | GNUNET_a2s (uaddr, addrlen)); | 462 | GNUNET_a2s (uaddr, addrlen)); |
464 | GNUNET_break (GNUNET_OK == | 463 | GNUNET_break (GNUNET_OK == |
465 | GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR)); | 464 | GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR)); |
466 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 465 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
467 | GNUNET_free (uaddr); | 466 | GNUNET_free (uaddr); |
468 | return NULL; | 467 | return NULL; |
469 | } | 468 | } |
470 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 469 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
471 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 470 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
472 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); | 471 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); |
@@ -490,7 +489,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, | |||
490 | */ | 489 | */ |
491 | int | 490 | int |
492 | GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *sock, | 491 | GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *sock, |
493 | void **addr, size_t * addrlen) | 492 | void **addr, size_t * addrlen) |
494 | { | 493 | { |
495 | if ((sock->addr == NULL) || (sock->addrlen == 0)) | 494 | if ((sock->addr == NULL) || (sock->addrlen == 0)) |
496 | return GNUNET_NO; | 495 | return GNUNET_NO; |
@@ -523,8 +522,7 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | |||
523 | * @param tc unused | 522 | * @param tc unused |
524 | */ | 523 | */ |
525 | static void | 524 | static void |
526 | destroy_continuation (void *cls, | 525 | destroy_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
527 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
528 | { | 526 | { |
529 | struct GNUNET_CONNECTION_Handle *sock = cls; | 527 | struct GNUNET_CONNECTION_Handle *sock = cls; |
530 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 528 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
@@ -533,78 +531,77 @@ destroy_continuation (void *cls, | |||
533 | sock->destroy_task = GNUNET_SCHEDULER_NO_TASK; | 531 | sock->destroy_task = GNUNET_SCHEDULER_NO_TASK; |
534 | GNUNET_assert (sock->dns_active == NULL); | 532 | GNUNET_assert (sock->dns_active == NULL); |
535 | if (0 != (sock->ccs & COCO_TRANSMIT_READY)) | 533 | if (0 != (sock->ccs & COCO_TRANSMIT_READY)) |
536 | { | 534 | { |
537 | #if DEBUG_CONNECTION | 535 | #if DEBUG_CONNECTION |
538 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 536 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy waits for CCS-TR to be done (%p)\n", |
539 | "Destroy waits for CCS-TR to be done (%p)\n", sock); | 537 | sock); |
540 | #endif | 538 | #endif |
541 | sock->ccs |= COCO_DESTROY_CONTINUATION; | 539 | sock->ccs |= COCO_DESTROY_CONTINUATION; |
542 | return; | 540 | return; |
543 | } | 541 | } |
544 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 542 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) |
545 | { | 543 | { |
546 | #if DEBUG_CONNECTION | 544 | #if DEBUG_CONNECTION |
547 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 545 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
548 | "Destroy waits for write_task to be done (%p)\n", sock); | 546 | "Destroy waits for write_task to be done (%p)\n", sock); |
549 | #endif | 547 | #endif |
550 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 548 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
551 | sock->destroy_task = | 549 | sock->destroy_task = |
552 | GNUNET_SCHEDULER_add_after (sock->write_task, &destroy_continuation, | 550 | GNUNET_SCHEDULER_add_after (sock->write_task, &destroy_continuation, |
553 | sock); | 551 | sock); |
554 | return; | 552 | return; |
555 | } | 553 | } |
556 | if (0 != (sock->ccs & COCO_RECEIVE_AGAIN)) | 554 | if (0 != (sock->ccs & COCO_RECEIVE_AGAIN)) |
557 | { | 555 | { |
558 | sock->ccs |= COCO_DESTROY_CONTINUATION; | 556 | sock->ccs |= COCO_DESTROY_CONTINUATION; |
559 | return; | 557 | return; |
560 | } | 558 | } |
561 | if (sock->sock != NULL) | 559 | if (sock->sock != NULL) |
562 | { | 560 | { |
563 | #if DEBUG_CONNECTION | 561 | #if DEBUG_CONNECTION |
564 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket (%p)\n", sock); | 562 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket (%p)\n", sock); |
565 | #endif | 563 | #endif |
566 | if (sock->persist != GNUNET_YES) | 564 | if (sock->persist != GNUNET_YES) |
567 | { | ||
568 | if ((GNUNET_YES != | ||
569 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR)) | ||
570 | && (errno != ENOTCONN) && (errno != ECONNRESET)) | ||
571 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); | ||
572 | } | ||
573 | } | ||
574 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | ||
575 | { | 565 | { |
576 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 566 | if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR)) |
577 | sock->destroy_task = | 567 | && (errno != ENOTCONN) && (errno != ECONNRESET)) |
578 | GNUNET_SCHEDULER_add_after (sock->read_task, &destroy_continuation, | 568 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); |
579 | sock); | ||
580 | return; | ||
581 | } | 569 | } |
570 | } | ||
571 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | ||
572 | { | ||
573 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | ||
574 | sock->destroy_task = | ||
575 | GNUNET_SCHEDULER_add_after (sock->read_task, &destroy_continuation, | ||
576 | sock); | ||
577 | return; | ||
578 | } | ||
582 | #if DEBUG_CONNECTION | 579 | #if DEBUG_CONNECTION |
583 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", sock); | 580 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", sock); |
584 | #endif | 581 | #endif |
585 | while (NULL != (pos = sock->ap_head)) | 582 | while (NULL != (pos = sock->ap_head)) |
586 | { | 583 | { |
587 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); | 584 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); |
588 | GNUNET_SCHEDULER_cancel (pos->task); | 585 | GNUNET_SCHEDULER_cancel (pos->task); |
589 | GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos); | 586 | GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos); |
590 | GNUNET_free (pos); | 587 | GNUNET_free (pos); |
591 | } | 588 | } |
592 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); | 589 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); |
593 | GNUNET_assert (sock->ccs == COCO_NONE); | 590 | GNUNET_assert (sock->ccs == COCO_NONE); |
594 | if (NULL != (notify = sock->nth.notify_ready)) | 591 | if (NULL != (notify = sock->nth.notify_ready)) |
595 | { | 592 | { |
596 | sock->nth.notify_ready = NULL; | 593 | sock->nth.notify_ready = NULL; |
597 | notify (sock->nth.notify_ready_cls, 0, NULL); | 594 | notify (sock->nth.notify_ready_cls, 0, NULL); |
598 | } | 595 | } |
599 | 596 | ||
600 | if (sock->sock != NULL) | 597 | if (sock->sock != NULL) |
601 | { | 598 | { |
602 | if (sock->persist != GNUNET_YES) | 599 | if (sock->persist != GNUNET_YES) |
603 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); | 600 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); |
604 | else | 601 | else |
605 | GNUNET_free (sock->sock); /* at least no memory leak (we deliberately | 602 | GNUNET_free (sock->sock); /* at least no memory leak (we deliberately |
606 | * leak the socket in this special case) ... */ | 603 | * leak the socket in this special case) ... */ |
607 | } | 604 | } |
608 | GNUNET_free_non_null (sock->addr); | 605 | GNUNET_free_non_null (sock->addr); |
609 | GNUNET_free_non_null (sock->hostname); | 606 | GNUNET_free_non_null (sock->hostname); |
610 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 607 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
@@ -639,9 +636,8 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
639 | { | 636 | { |
640 | #if DEBUG_CONNECTION | 637 | #if DEBUG_CONNECTION |
641 | LOG ((0 != | 638 | LOG ((0 != |
642 | strncmp (h->hostname, "localhost:", | 639 | strncmp (h->hostname, "localhost:", |
643 | 10)) ? GNUNET_ERROR_TYPE_INFO : | 640 | 10)) ? GNUNET_ERROR_TYPE_INFO : GNUNET_ERROR_TYPE_WARNING, |
644 | GNUNET_ERROR_TYPE_WARNING, | ||
645 | _ | 641 | _ |
646 | ("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), | 642 | ("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), |
647 | h->hostname, h->port); | 643 | h->hostname, h->port); |
@@ -654,39 +650,39 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
654 | 650 | ||
655 | /* trigger jobs that used to wait on "connect_task" */ | 651 | /* trigger jobs that used to wait on "connect_task" */ |
656 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) | 652 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) |
657 | { | 653 | { |
658 | #if DEBUG_CONNECTION | 654 | #if DEBUG_CONNECTION |
659 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 655 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
660 | "connect_fail_continuation triggers receive_again (%p)\n", h); | 656 | "connect_fail_continuation triggers receive_again (%p)\n", h); |
661 | #endif | 657 | #endif |
662 | h->ccs -= COCO_RECEIVE_AGAIN; | 658 | h->ccs -= COCO_RECEIVE_AGAIN; |
663 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); | 659 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); |
664 | } | 660 | } |
665 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) | 661 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) |
666 | { | 662 | { |
667 | #if DEBUG_CONNECTION | 663 | #if DEBUG_CONNECTION |
668 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 664 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
669 | "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n", | 665 | "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n", |
670 | h); | 666 | h); |
671 | #endif | 667 | #endif |
672 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); | 668 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); |
673 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); | 669 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); |
674 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 670 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
675 | h->ccs -= COCO_TRANSMIT_READY; | 671 | h->ccs -= COCO_TRANSMIT_READY; |
676 | GNUNET_assert (h->nth.notify_ready != NULL); | 672 | GNUNET_assert (h->nth.notify_ready != NULL); |
677 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); | 673 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); |
678 | h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); | 674 | h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); |
679 | } | 675 | } |
680 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) | 676 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) |
681 | { | 677 | { |
682 | #if DEBUG_CONNECTION | 678 | #if DEBUG_CONNECTION |
683 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 679 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
684 | "connect_fail_continuation runs destroy_continuation (%p)\n", h); | 680 | "connect_fail_continuation runs destroy_continuation (%p)\n", h); |
685 | #endif | 681 | #endif |
686 | h->ccs -= COCO_DESTROY_CONTINUATION; | 682 | h->ccs -= COCO_DESTROY_CONTINUATION; |
687 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); | 683 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); |
688 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); | 684 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); |
689 | } | 685 | } |
690 | } | 686 | } |
691 | 687 | ||
692 | 688 | ||
@@ -704,43 +700,42 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
704 | #endif | 700 | #endif |
705 | /* trigger jobs that waited for the connection */ | 701 | /* trigger jobs that waited for the connection */ |
706 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) | 702 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) |
707 | { | 703 | { |
708 | #if DEBUG_CONNECTION | 704 | #if DEBUG_CONNECTION |
709 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 705 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
710 | "connect_success_continuation runs receive_again (%p)\n", h); | 706 | "connect_success_continuation runs receive_again (%p)\n", h); |
711 | #endif | 707 | #endif |
712 | h->ccs -= COCO_RECEIVE_AGAIN; | 708 | h->ccs -= COCO_RECEIVE_AGAIN; |
713 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); | 709 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); |
714 | } | 710 | } |
715 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) | 711 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) |
716 | { | 712 | { |
717 | #if DEBUG_CONNECTION | 713 | #if DEBUG_CONNECTION |
718 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 714 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
719 | "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n", | 715 | "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n", |
720 | h); | 716 | h); |
721 | #endif | 717 | #endif |
722 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); | 718 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); |
723 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); | 719 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); |
724 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 720 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
725 | h->ccs -= COCO_TRANSMIT_READY; | 721 | h->ccs -= COCO_TRANSMIT_READY; |
726 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); | 722 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); |
727 | GNUNET_assert (h->nth.notify_ready != NULL); | 723 | GNUNET_assert (h->nth.notify_ready != NULL); |
728 | h->write_task = | 724 | h->write_task = |
729 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining | 725 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining |
730 | (h->nth.transmit_timeout), h->sock, | 726 | (h->nth.transmit_timeout), h->sock, |
731 | &transmit_ready, h); | 727 | &transmit_ready, h); |
732 | } | 728 | } |
733 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) | 729 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) |
734 | { | 730 | { |
735 | #if DEBUG_CONNECTION | 731 | #if DEBUG_CONNECTION |
736 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 732 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
737 | "connect_success_continuation runs destroy_continuation (%p)\n", | 733 | "connect_success_continuation runs destroy_continuation (%p)\n", h); |
738 | h); | ||
739 | #endif | 734 | #endif |
740 | h->ccs -= COCO_DESTROY_CONTINUATION; | 735 | h->ccs -= COCO_DESTROY_CONTINUATION; |
741 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); | 736 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); |
742 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); | 737 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); |
743 | } | 738 | } |
744 | } | 739 | } |
745 | 740 | ||
746 | 741 | ||
@@ -753,7 +748,7 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
753 | */ | 748 | */ |
754 | static void | 749 | static void |
755 | connect_probe_continuation (void *cls, | 750 | connect_probe_continuation (void *cls, |
756 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 751 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
757 | { | 752 | { |
758 | struct AddressProbe *ap = cls; | 753 | struct AddressProbe *ap = cls; |
759 | struct GNUNET_CONNECTION_Handle *h = ap->h; | 754 | struct GNUNET_CONNECTION_Handle *h = ap->h; |
@@ -768,15 +763,15 @@ connect_probe_continuation (void *cls, | |||
768 | error = 0; | 763 | error = 0; |
769 | if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || | 764 | if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || |
770 | (GNUNET_OK != | 765 | (GNUNET_OK != |
771 | GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, | 766 | GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, &error, |
772 | &error, &len)) || (error != 0)) | 767 | &len)) || (error != 0)) |
773 | { | 768 | { |
774 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); | 769 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); |
775 | GNUNET_free (ap); | 770 | GNUNET_free (ap); |
776 | if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO)) | 771 | if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO)) |
777 | connect_fail_continuation (h); | 772 | connect_fail_continuation (h); |
778 | return; | 773 | return; |
779 | } | 774 | } |
780 | GNUNET_assert (h->sock == NULL); | 775 | GNUNET_assert (h->sock == NULL); |
781 | h->sock = ap->sock; | 776 | h->sock = ap->sock; |
782 | GNUNET_assert (h->addr == NULL); | 777 | GNUNET_assert (h->addr == NULL); |
@@ -786,12 +781,12 @@ connect_probe_continuation (void *cls, | |||
786 | GNUNET_free (ap); | 781 | GNUNET_free (ap); |
787 | /* cancel all other attempts */ | 782 | /* cancel all other attempts */ |
788 | while (NULL != (pos = h->ap_head)) | 783 | while (NULL != (pos = h->ap_head)) |
789 | { | 784 | { |
790 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); | 785 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); |
791 | GNUNET_SCHEDULER_cancel (pos->task); | 786 | GNUNET_SCHEDULER_cancel (pos->task); |
792 | GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos); | 787 | GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos); |
793 | GNUNET_free (pos); | 788 | GNUNET_free (pos); |
794 | } | 789 | } |
795 | connect_success_continuation (h); | 790 | connect_success_continuation (h); |
796 | } | 791 | } |
797 | 792 | ||
@@ -806,27 +801,27 @@ connect_probe_continuation (void *cls, | |||
806 | */ | 801 | */ |
807 | static void | 802 | static void |
808 | try_connect_using_address (void *cls, const struct sockaddr *addr, | 803 | try_connect_using_address (void *cls, const struct sockaddr *addr, |
809 | socklen_t addrlen) | 804 | socklen_t addrlen) |
810 | { | 805 | { |
811 | struct GNUNET_CONNECTION_Handle *h = cls; | 806 | struct GNUNET_CONNECTION_Handle *h = cls; |
812 | struct AddressProbe *ap; | 807 | struct AddressProbe *ap; |
813 | struct GNUNET_TIME_Relative delay; | 808 | struct GNUNET_TIME_Relative delay; |
814 | 809 | ||
815 | if (addr == NULL) | 810 | if (addr == NULL) |
816 | { | 811 | { |
817 | h->dns_active = NULL; | 812 | h->dns_active = NULL; |
818 | if ((NULL == h->ap_head) && (NULL == h->sock)) | 813 | if ((NULL == h->ap_head) && (NULL == h->sock)) |
819 | connect_fail_continuation (h); | 814 | connect_fail_continuation (h); |
820 | return; | 815 | return; |
821 | } | 816 | } |
822 | if (h->sock != NULL) | 817 | if (h->sock != NULL) |
823 | return; /* already connected */ | 818 | return; /* already connected */ |
824 | GNUNET_assert (h->addr == NULL); | 819 | GNUNET_assert (h->addr == NULL); |
825 | /* try to connect */ | 820 | /* try to connect */ |
826 | #if DEBUG_CONNECTION | 821 | #if DEBUG_CONNECTION |
827 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 822 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
828 | "Trying to connect using address `%s:%u/%s:%u'\n", h->hostname, | 823 | "Trying to connect using address `%s:%u/%s:%u'\n", h->hostname, h->port, |
829 | h->port, GNUNET_a2s (addr, addrlen), h->port); | 824 | GNUNET_a2s (addr, addrlen), h->port); |
830 | #endif | 825 | #endif |
831 | ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen); | 826 | ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen); |
832 | ap->addr = (const struct sockaddr *) &ap[1]; | 827 | ap->addr = (const struct sockaddr *) &ap[1]; |
@@ -835,25 +830,24 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, | |||
835 | ap->h = h; | 830 | ap->h = h; |
836 | 831 | ||
837 | switch (ap->addr->sa_family) | 832 | switch (ap->addr->sa_family) |
838 | { | 833 | { |
839 | case AF_INET: | 834 | case AF_INET: |
840 | ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port); | 835 | ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port); |
841 | break; | 836 | break; |
842 | case AF_INET6: | 837 | case AF_INET6: |
843 | ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port); | 838 | ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port); |
844 | break; | 839 | break; |
845 | default: | 840 | default: |
846 | GNUNET_break (0); | 841 | GNUNET_break (0); |
847 | GNUNET_free (ap); | 842 | GNUNET_free (ap); |
848 | return; /* not supported by us */ | 843 | return; /* not supported by us */ |
849 | } | 844 | } |
850 | ap->sock = | 845 | ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0); |
851 | GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0); | ||
852 | if (ap->sock == NULL) | 846 | if (ap->sock == NULL) |
853 | { | 847 | { |
854 | GNUNET_free (ap); | 848 | GNUNET_free (ap); |
855 | return; /* not supported by OS */ | 849 | return; /* not supported by OS */ |
856 | } | 850 | } |
857 | #if DEBUG_CONNECTION | 851 | #if DEBUG_CONNECTION |
858 | LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"), | 852 | LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"), |
859 | GNUNET_a2s (ap->addr, ap->addrlen), h); | 853 | GNUNET_a2s (ap->addr, ap->addrlen), h); |
@@ -861,33 +855,32 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, | |||
861 | if ((GNUNET_OK != | 855 | if ((GNUNET_OK != |
862 | GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) && | 856 | GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) && |
863 | (errno != EINPROGRESS)) | 857 | (errno != EINPROGRESS)) |
864 | { | 858 | { |
865 | /* maybe refused / unsupported address, try next */ | 859 | /* maybe refused / unsupported address, try next */ |
866 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); | 860 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); |
867 | #if 0 | 861 | #if 0 |
868 | LOG (GNUNET_ERROR_TYPE_INFO, | 862 | LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%s' (%p)\n"), |
869 | _("Failed to connect to `%s' (%p)\n"), | 863 | GNUNET_a2s (ap->addr, ap->addrlen), h); |
870 | GNUNET_a2s (ap->addr, ap->addrlen), h); | ||
871 | #endif | 864 | #endif |
872 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); | 865 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); |
873 | GNUNET_free (ap); | 866 | GNUNET_free (ap); |
874 | return; | 867 | return; |
875 | } | 868 | } |
876 | GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap); | 869 | GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap); |
877 | delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; | 870 | delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; |
878 | if (h->nth.notify_ready != NULL) | 871 | if (h->nth.notify_ready != NULL) |
879 | delay = | 872 | delay = |
880 | GNUNET_TIME_relative_min (delay, | 873 | GNUNET_TIME_relative_min (delay, |
881 | GNUNET_TIME_absolute_get_remaining (h-> | 874 | GNUNET_TIME_absolute_get_remaining (h-> |
882 | nth.transmit_timeout)); | 875 | nth.transmit_timeout)); |
883 | if (h->receiver != NULL) | 876 | if (h->receiver != NULL) |
884 | delay = | 877 | delay = |
885 | GNUNET_TIME_relative_min (delay, | 878 | GNUNET_TIME_relative_min (delay, |
886 | GNUNET_TIME_absolute_get_remaining | 879 | GNUNET_TIME_absolute_get_remaining |
887 | (h->receive_timeout)); | 880 | (h->receive_timeout)); |
888 | ap->task = | 881 | ap->task = |
889 | GNUNET_SCHEDULER_add_write_net (delay, ap->sock, | 882 | GNUNET_SCHEDULER_add_write_net (delay, ap->sock, |
890 | &connect_probe_continuation, ap); | 883 | &connect_probe_continuation, ap); |
891 | } | 884 | } |
892 | 885 | ||
893 | 886 | ||
@@ -902,13 +895,13 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, | |||
902 | * @return the socket handle | 895 | * @return the socket handle |
903 | */ | 896 | */ |
904 | struct GNUNET_CONNECTION_Handle * | 897 | struct GNUNET_CONNECTION_Handle * |
905 | GNUNET_CONNECTION_create_from_connect (const struct | 898 | GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle |
906 | GNUNET_CONFIGURATION_Handle *cfg, | 899 | *cfg, const char *hostname, |
907 | const char *hostname, uint16_t port) | 900 | uint16_t port) |
908 | { | 901 | { |
909 | struct GNUNET_CONNECTION_Handle *ret; | 902 | struct GNUNET_CONNECTION_Handle *ret; |
910 | 903 | ||
911 | GNUNET_assert (0 < strlen (hostname)); /* sanity check */ | 904 | GNUNET_assert (0 < strlen (hostname)); /* sanity check */ |
912 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 905 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
913 | ret->cfg = cfg; | 906 | ret->cfg = cfg; |
914 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 907 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
@@ -916,9 +909,9 @@ GNUNET_CONNECTION_create_from_connect (const struct | |||
916 | ret->port = port; | 909 | ret->port = port; |
917 | ret->hostname = GNUNET_strdup (hostname); | 910 | ret->hostname = GNUNET_strdup (hostname); |
918 | ret->dns_active = | 911 | ret->dns_active = |
919 | GNUNET_RESOLVER_ip_get (ret->hostname, AF_UNSPEC, | 912 | GNUNET_RESOLVER_ip_get (ret->hostname, AF_UNSPEC, |
920 | GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, | 913 | GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, |
921 | &try_connect_using_address, ret); | 914 | &try_connect_using_address, ret); |
922 | return ret; | 915 | return ret; |
923 | } | 916 | } |
924 | 917 | ||
@@ -934,15 +927,15 @@ GNUNET_CONNECTION_create_from_connect (const struct | |||
934 | */ | 927 | */ |
935 | struct GNUNET_CONNECTION_Handle * | 928 | struct GNUNET_CONNECTION_Handle * |
936 | GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | 929 | GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct |
937 | GNUNET_CONFIGURATION_Handle | 930 | GNUNET_CONFIGURATION_Handle |
938 | *cfg, const char *unixpath) | 931 | *cfg, const char *unixpath) |
939 | { | 932 | { |
940 | #ifdef AF_UNIX | 933 | #ifdef AF_UNIX |
941 | struct GNUNET_CONNECTION_Handle *ret; | 934 | struct GNUNET_CONNECTION_Handle *ret; |
942 | struct sockaddr_un *un; | 935 | struct sockaddr_un *un; |
943 | size_t slen; | 936 | size_t slen; |
944 | 937 | ||
945 | GNUNET_assert (0 < strlen (unixpath)); /* sanity check */ | 938 | GNUNET_assert (0 < strlen (unixpath)); /* sanity check */ |
946 | un = GNUNET_malloc (sizeof (struct sockaddr_un)); | 939 | un = GNUNET_malloc (sizeof (struct sockaddr_un)); |
947 | un->sun_family = AF_UNIX; | 940 | un->sun_family = AF_UNIX; |
948 | slen = strlen (unixpath); | 941 | slen = strlen (unixpath); |
@@ -967,20 +960,20 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | |||
967 | ret->addrlen = slen; | 960 | ret->addrlen = slen; |
968 | ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | 961 | ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); |
969 | if (NULL == ret->sock) | 962 | if (NULL == ret->sock) |
970 | { | 963 | { |
971 | GNUNET_free (ret->addr); | 964 | GNUNET_free (ret->addr); |
972 | GNUNET_free (ret->write_buffer); | 965 | GNUNET_free (ret->write_buffer); |
973 | GNUNET_free (ret); | 966 | GNUNET_free (ret); |
974 | return NULL; | 967 | return NULL; |
975 | } | 968 | } |
976 | if (GNUNET_OK != | 969 | if (GNUNET_OK != |
977 | GNUNET_NETWORK_socket_connect (ret->sock, ret->addr, ret->addrlen)) | 970 | GNUNET_NETWORK_socket_connect (ret->sock, ret->addr, ret->addrlen)) |
978 | { | 971 | { |
979 | /* Just return; we expect everything to work eventually so don't fail HARD */ | 972 | /* Just return; we expect everything to work eventually so don't fail HARD */ |
980 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock)); | 973 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock)); |
981 | ret->sock = NULL; | 974 | ret->sock = NULL; |
982 | return ret; | 975 | return ret; |
983 | } | 976 | } |
984 | connect_success_continuation (ret); | 977 | connect_success_continuation (ret); |
985 | return ret; | 978 | return ret; |
986 | #else | 979 | #else |
@@ -1001,8 +994,8 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | |||
1001 | */ | 994 | */ |
1002 | struct GNUNET_CONNECTION_Handle * | 995 | struct GNUNET_CONNECTION_Handle * |
1003 | GNUNET_CONNECTION_create_from_sockaddr (int af_family, | 996 | GNUNET_CONNECTION_create_from_sockaddr (int af_family, |
1004 | const struct sockaddr *serv_addr, | 997 | const struct sockaddr *serv_addr, |
1005 | socklen_t addrlen) | 998 | socklen_t addrlen) |
1006 | { | 999 | { |
1007 | struct GNUNET_NETWORK_Handle *s; | 1000 | struct GNUNET_NETWORK_Handle *s; |
1008 | struct GNUNET_CONNECTION_Handle *ret; | 1001 | struct GNUNET_CONNECTION_Handle *ret; |
@@ -1010,22 +1003,20 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, | |||
1010 | 1003 | ||
1011 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); | 1004 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); |
1012 | if (s == NULL) | 1005 | if (s == NULL) |
1013 | { | 1006 | { |
1014 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | 1007 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket"); |
1015 | "socket"); | 1008 | return NULL; |
1016 | return NULL; | 1009 | } |
1017 | } | ||
1018 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && | 1010 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && |
1019 | (errno != EINPROGRESS)) | 1011 | (errno != EINPROGRESS)) |
1020 | { | 1012 | { |
1021 | /* maybe refused / unsupported address, try next */ | 1013 | /* maybe refused / unsupported address, try next */ |
1022 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); | 1014 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); |
1023 | LOG (GNUNET_ERROR_TYPE_INFO, | 1015 | LOG (GNUNET_ERROR_TYPE_INFO, _("Attempt to connect to `%s' failed\n"), |
1024 | _("Attempt to connect to `%s' failed\n"), GNUNET_a2s (serv_addr, | 1016 | GNUNET_a2s (serv_addr, addrlen)); |
1025 | addrlen)); | 1017 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); |
1026 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); | 1018 | return NULL; |
1027 | return NULL; | 1019 | } |
1028 | } | ||
1029 | ret = GNUNET_CONNECTION_create_from_existing (s); | 1020 | ret = GNUNET_CONNECTION_create_from_existing (s); |
1030 | ret->addr = GNUNET_malloc (addrlen); | 1021 | ret->addr = GNUNET_malloc (addrlen); |
1031 | memcpy (ret->addr, serv_addr, addrlen); | 1022 | memcpy (ret->addr, serv_addr, addrlen); |
@@ -1050,7 +1041,7 @@ int | |||
1050 | GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock) | 1041 | GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock) |
1051 | { | 1042 | { |
1052 | if ((sock->ap_head != NULL) || (sock->dns_active != NULL)) | 1043 | if ((sock->ap_head != NULL) || (sock->dns_active != NULL)) |
1053 | return GNUNET_YES; /* still trying to connect */ | 1044 | return GNUNET_YES; /* still trying to connect */ |
1054 | return (sock->sock == NULL) ? GNUNET_NO : GNUNET_YES; | 1045 | return (sock->sock == NULL) ? GNUNET_NO : GNUNET_YES; |
1055 | } | 1046 | } |
1056 | 1047 | ||
@@ -1070,23 +1061,23 @@ GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock) | |||
1070 | */ | 1061 | */ |
1071 | void | 1062 | void |
1072 | GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, | 1063 | GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, |
1073 | int finish_pending_write) | 1064 | int finish_pending_write) |
1074 | { | 1065 | { |
1075 | if (GNUNET_NO == finish_pending_write) | 1066 | if (GNUNET_NO == finish_pending_write) |
1067 | { | ||
1068 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | ||
1076 | { | 1069 | { |
1077 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 1070 | GNUNET_SCHEDULER_cancel (sock->write_task); |
1078 | { | 1071 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; |
1079 | GNUNET_SCHEDULER_cancel (sock->write_task); | 1072 | sock->write_buffer_off = 0; |
1080 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1081 | sock->write_buffer_off = 0; | ||
1082 | } | ||
1083 | sock->nth.notify_ready = NULL; | ||
1084 | } | 1073 | } |
1074 | sock->nth.notify_ready = NULL; | ||
1075 | } | ||
1085 | if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL)) | 1076 | if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL)) |
1086 | { | 1077 | { |
1087 | GNUNET_RESOLVER_request_cancel (sock->dns_active); | 1078 | GNUNET_RESOLVER_request_cancel (sock->dns_active); |
1088 | sock->dns_active = NULL; | 1079 | sock->dns_active = NULL; |
1089 | } | 1080 | } |
1090 | 1081 | ||
1091 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 1082 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
1092 | sock->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock); | 1083 | sock->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock); |
@@ -1102,8 +1093,8 @@ signal_timeout (struct GNUNET_CONNECTION_Handle *sh) | |||
1102 | GNUNET_CONNECTION_Receiver receiver; | 1093 | GNUNET_CONNECTION_Receiver receiver; |
1103 | 1094 | ||
1104 | #if DEBUG_CONNECTION | 1095 | #if DEBUG_CONNECTION |
1105 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1096 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Network signals time out to receiver (%p)!\n", |
1106 | "Network signals time out to receiver (%p)!\n", sh); | 1097 | sh); |
1107 | #endif | 1098 | #endif |
1108 | GNUNET_assert (NULL != (receiver = sh->receiver)); | 1099 | GNUNET_assert (NULL != (receiver = sh->receiver)); |
1109 | sh->receiver = NULL; | 1100 | sh->receiver = NULL; |
@@ -1141,62 +1132,61 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1141 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; | 1132 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; |
1142 | if ((GNUNET_YES == sh->ignore_shutdown) && | 1133 | if ((GNUNET_YES == sh->ignore_shutdown) && |
1143 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1134 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1144 | { | 1135 | { |
1145 | /* ignore shutdown request, go again immediately */ | 1136 | /* ignore shutdown request, go again immediately */ |
1146 | #if DEBUG_CONNECTION | 1137 | #if DEBUG_CONNECTION |
1147 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1138 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1148 | "Ignoring shutdown signal per configuration\n"); | 1139 | "Ignoring shutdown signal per configuration\n"); |
1149 | #endif | 1140 | #endif |
1150 | sh->read_task = | 1141 | sh->read_task = |
1151 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining | 1142 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining |
1152 | (sh->receive_timeout), sh->sock, | 1143 | (sh->receive_timeout), sh->sock, |
1153 | &receive_ready, sh); | 1144 | &receive_ready, sh); |
1154 | return; | 1145 | return; |
1155 | } | 1146 | } |
1156 | now = GNUNET_TIME_absolute_get (); | 1147 | now = GNUNET_TIME_absolute_get (); |
1157 | if ((now.abs_value > sh->receive_timeout.abs_value) || | 1148 | if ((now.abs_value > sh->receive_timeout.abs_value) || |
1158 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) || | 1149 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) || |
1159 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1150 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1160 | { | 1151 | { |
1161 | #if DEBUG_CONNECTION | 1152 | #if DEBUG_CONNECTION |
1162 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 1153 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
1163 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1154 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1164 | "Receive from `%s' encounters error: time out by %llums... (%p)\n", | 1155 | "Receive from `%s' encounters error: time out by %llums... (%p)\n", |
1165 | GNUNET_a2s (sh->addr, sh->addrlen), | 1156 | GNUNET_a2s (sh->addr, sh->addrlen), |
1166 | GNUNET_TIME_absolute_get_duration (sh->receive_timeout). | 1157 | GNUNET_TIME_absolute_get_duration (sh->receive_timeout).rel_value, |
1167 | rel_value, sh); | 1158 | sh); |
1168 | #endif | 1159 | #endif |
1169 | signal_timeout (sh); | 1160 | signal_timeout (sh); |
1170 | return; | 1161 | return; |
1171 | } | 1162 | } |
1172 | if (sh->sock == NULL) | 1163 | if (sh->sock == NULL) |
1173 | { | 1164 | { |
1174 | /* connect failed for good */ | 1165 | /* connect failed for good */ |
1175 | #if DEBUG_CONNECTION | 1166 | #if DEBUG_CONNECTION |
1176 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1167 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1177 | "Receive encounters error, socket closed... (%p)\n", sh); | 1168 | "Receive encounters error, socket closed... (%p)\n", sh); |
1178 | #endif | 1169 | #endif |
1179 | signal_error (sh, ECONNREFUSED); | 1170 | signal_error (sh, ECONNREFUSED); |
1180 | return; | 1171 | return; |
1181 | } | 1172 | } |
1182 | GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock)); | 1173 | GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock)); |
1183 | RETRY: | 1174 | RETRY: |
1184 | ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max); | 1175 | ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max); |
1185 | if (ret == -1) | 1176 | if (ret == -1) |
1186 | { | 1177 | { |
1187 | if (errno == EINTR) | 1178 | if (errno == EINTR) |
1188 | goto RETRY; | 1179 | goto RETRY; |
1189 | #if DEBUG_CONNECTION | 1180 | #if DEBUG_CONNECTION |
1190 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving: %s\n", | 1181 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving: %s\n", STRERROR (errno)); |
1191 | STRERROR (errno)); | ||
1192 | #endif | 1182 | #endif |
1193 | signal_error (sh, errno); | 1183 | signal_error (sh, errno); |
1194 | return; | 1184 | return; |
1195 | } | 1185 | } |
1196 | #if DEBUG_CONNECTION | 1186 | #if DEBUG_CONNECTION |
1197 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1187 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1198 | "receive_ready read %u/%u bytes from `%s' (%p)!\n", | 1188 | "receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret, |
1199 | (unsigned int) ret, sh->max, GNUNET_a2s (sh->addr, sh->addrlen), sh); | 1189 | sh->max, GNUNET_a2s (sh->addr, sh->addrlen), sh); |
1200 | #endif | 1190 | #endif |
1201 | GNUNET_assert (NULL != (receiver = sh->receiver)); | 1191 | GNUNET_assert (NULL != (receiver = sh->receiver)); |
1202 | sh->receiver = NULL; | 1192 | sh->receiver = NULL; |
@@ -1222,32 +1212,32 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1222 | 1212 | ||
1223 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; | 1213 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; |
1224 | if (sh->sock == NULL) | 1214 | if (sh->sock == NULL) |
1225 | { | 1215 | { |
1226 | /* not connected and no longer trying */ | 1216 | /* not connected and no longer trying */ |
1227 | #if DEBUG_CONNECTION | 1217 | #if DEBUG_CONNECTION |
1228 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1218 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1229 | "Receive encounters error, socket closed (%p)...\n", sh); | 1219 | "Receive encounters error, socket closed (%p)...\n", sh); |
1230 | #endif | 1220 | #endif |
1231 | signal_error (sh, ECONNREFUSED); | 1221 | signal_error (sh, ECONNREFUSED); |
1232 | return; | 1222 | return; |
1233 | } | 1223 | } |
1234 | now = GNUNET_TIME_absolute_get (); | 1224 | now = GNUNET_TIME_absolute_get (); |
1235 | if ((now.abs_value > sh->receive_timeout.abs_value) || | 1225 | if ((now.abs_value > sh->receive_timeout.abs_value) || |
1236 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1226 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1237 | { | 1227 | { |
1238 | #if DEBUG_CONNECTION | 1228 | #if DEBUG_CONNECTION |
1239 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1229 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1240 | "Receive encounters error: time out (%p)...\n", sh); | 1230 | "Receive encounters error: time out (%p)...\n", sh); |
1241 | #endif | 1231 | #endif |
1242 | signal_timeout (sh); | 1232 | signal_timeout (sh); |
1243 | return; | 1233 | return; |
1244 | } | 1234 | } |
1245 | GNUNET_assert (sh->sock != NULL); | 1235 | GNUNET_assert (sh->sock != NULL); |
1246 | /* connect succeeded, wait for data! */ | 1236 | /* connect succeeded, wait for data! */ |
1247 | sh->read_task = | 1237 | sh->read_task = |
1248 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining | 1238 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining |
1249 | (sh->receive_timeout), sh->sock, | 1239 | (sh->receive_timeout), sh->sock, |
1250 | &receive_ready, sh); | 1240 | &receive_ready, sh); |
1251 | } | 1241 | } |
1252 | 1242 | ||
1253 | 1243 | ||
@@ -1266,31 +1256,31 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1266 | */ | 1256 | */ |
1267 | void | 1257 | void |
1268 | GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max, | 1258 | GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max, |
1269 | struct GNUNET_TIME_Relative timeout, | 1259 | struct GNUNET_TIME_Relative timeout, |
1270 | GNUNET_CONNECTION_Receiver receiver, | 1260 | GNUNET_CONNECTION_Receiver receiver, |
1271 | void *receiver_cls) | 1261 | void *receiver_cls) |
1272 | { | 1262 | { |
1273 | struct GNUNET_SCHEDULER_TaskContext tc; | 1263 | struct GNUNET_SCHEDULER_TaskContext tc; |
1274 | 1264 | ||
1275 | GNUNET_assert ((sock->read_task == GNUNET_SCHEDULER_NO_TASK) && | 1265 | GNUNET_assert ((sock->read_task == GNUNET_SCHEDULER_NO_TASK) && |
1276 | (0 == (sock->ccs & COCO_RECEIVE_AGAIN)) && | 1266 | (0 == (sock->ccs & COCO_RECEIVE_AGAIN)) && |
1277 | (sock->receiver == NULL)); | 1267 | (sock->receiver == NULL)); |
1278 | sock->receiver = receiver; | 1268 | sock->receiver = receiver; |
1279 | sock->receiver_cls = receiver_cls; | 1269 | sock->receiver_cls = receiver_cls; |
1280 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); | 1270 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); |
1281 | sock->max = max; | 1271 | sock->max = max; |
1282 | if (sock->sock != NULL) | 1272 | if (sock->sock != NULL) |
1283 | { | 1273 | { |
1284 | memset (&tc, 0, sizeof (tc)); | 1274 | memset (&tc, 0, sizeof (tc)); |
1285 | tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE; | 1275 | tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE; |
1286 | receive_again (sock, &tc); | 1276 | receive_again (sock, &tc); |
1287 | return; | 1277 | return; |
1288 | } | 1278 | } |
1289 | if ((sock->dns_active == NULL) && (sock->ap_head == NULL)) | 1279 | if ((sock->dns_active == NULL) && (sock->ap_head == NULL)) |
1290 | { | 1280 | { |
1291 | receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT); | 1281 | receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT); |
1292 | return; | 1282 | return; |
1293 | } | 1283 | } |
1294 | sock->ccs += COCO_RECEIVE_AGAIN; | 1284 | sock->ccs += COCO_RECEIVE_AGAIN; |
1295 | } | 1285 | } |
1296 | 1286 | ||
@@ -1303,7 +1293,7 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max, | |||
1303 | */ | 1293 | */ |
1304 | void | 1294 | void |
1305 | GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, | 1295 | GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, |
1306 | int do_ignore) | 1296 | int do_ignore) |
1307 | { | 1297 | { |
1308 | sock->ignore_shutdown = do_ignore; | 1298 | sock->ignore_shutdown = do_ignore; |
1309 | } | 1299 | } |
@@ -1321,15 +1311,15 @@ void * | |||
1321 | GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) | 1311 | GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) |
1322 | { | 1312 | { |
1323 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | 1313 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) |
1324 | { | 1314 | { |
1325 | GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task)); | 1315 | GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task)); |
1326 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; | 1316 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; |
1327 | } | 1317 | } |
1328 | else | 1318 | else |
1329 | { | 1319 | { |
1330 | GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN)); | 1320 | GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN)); |
1331 | sock->ccs -= COCO_RECEIVE_AGAIN; | 1321 | sock->ccs -= COCO_RECEIVE_AGAIN; |
1332 | } | 1322 | } |
1333 | sock->receiver = NULL; | 1323 | sock->receiver = NULL; |
1334 | return sock->receiver_cls; | 1324 | return sock->receiver_cls; |
1335 | } | 1325 | } |
@@ -1360,18 +1350,18 @@ process_notify (struct GNUNET_CONNECTION_Handle *sock) | |||
1360 | return GNUNET_NO; | 1350 | return GNUNET_NO; |
1361 | sock->nth.notify_ready = NULL; | 1351 | sock->nth.notify_ready = NULL; |
1362 | if (sock->write_buffer_size - sock->write_buffer_off < size) | 1352 | if (sock->write_buffer_size - sock->write_buffer_off < size) |
1363 | { | 1353 | { |
1364 | /* need to compact */ | 1354 | /* need to compact */ |
1365 | memmove (sock->write_buffer, | 1355 | memmove (sock->write_buffer, &sock->write_buffer[sock->write_buffer_pos], |
1366 | &sock->write_buffer[sock->write_buffer_pos], used); | 1356 | used); |
1367 | sock->write_buffer_off -= sock->write_buffer_pos; | 1357 | sock->write_buffer_off -= sock->write_buffer_pos; |
1368 | sock->write_buffer_pos = 0; | 1358 | sock->write_buffer_pos = 0; |
1369 | } | 1359 | } |
1370 | avail = sock->write_buffer_size - sock->write_buffer_off; | 1360 | avail = sock->write_buffer_size - sock->write_buffer_off; |
1371 | GNUNET_assert (avail >= size); | 1361 | GNUNET_assert (avail >= size); |
1372 | size = | 1362 | size = |
1373 | notify (sock->nth.notify_ready_cls, avail, | 1363 | notify (sock->nth.notify_ready_cls, avail, |
1374 | &sock->write_buffer[sock->write_buffer_off]); | 1364 | &sock->write_buffer[sock->write_buffer_off]); |
1375 | GNUNET_assert (size <= avail); | 1365 | GNUNET_assert (size <= avail); |
1376 | sock->write_buffer_off += size; | 1366 | sock->write_buffer_off += size; |
1377 | return GNUNET_YES; | 1367 | return GNUNET_YES; |
@@ -1401,12 +1391,11 @@ transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1401 | sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1391 | sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1402 | #if DEBUG_CONNECTION | 1392 | #if DEBUG_CONNECTION |
1403 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1393 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1404 | "Transmit to `%s:%u/%s' fails, time out reached (%p).\n", | 1394 | "Transmit to `%s:%u/%s' fails, time out reached (%p).\n", sock->hostname, |
1405 | sock->hostname, sock->port, GNUNET_a2s (sock->addr, | 1395 | sock->port, GNUNET_a2s (sock->addr, sock->addrlen), sock); |
1406 | sock->addrlen), sock); | ||
1407 | #endif | 1396 | #endif |
1408 | GNUNET_assert (0 != (sock->ccs & COCO_TRANSMIT_READY)); | 1397 | GNUNET_assert (0 != (sock->ccs & COCO_TRANSMIT_READY)); |
1409 | sock->ccs -= COCO_TRANSMIT_READY; /* remove request */ | 1398 | sock->ccs -= COCO_TRANSMIT_READY; /* remove request */ |
1410 | notify = sock->nth.notify_ready; | 1399 | notify = sock->nth.notify_ready; |
1411 | sock->nth.notify_ready = NULL; | 1400 | sock->nth.notify_ready = NULL; |
1412 | notify (sock->nth.notify_ready_cls, 0, NULL); | 1401 | notify (sock->nth.notify_ready_cls, 0, NULL); |
@@ -1451,20 +1440,20 @@ transmit_error (struct GNUNET_CONNECTION_Handle *sock) | |||
1451 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 1440 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
1452 | 1441 | ||
1453 | if (NULL != sock->sock) | 1442 | if (NULL != sock->sock) |
1454 | { | 1443 | { |
1455 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); | 1444 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); |
1456 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); | 1445 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); |
1457 | sock->sock = NULL; | 1446 | sock->sock = NULL; |
1458 | } | 1447 | } |
1459 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | 1448 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) |
1460 | { | 1449 | { |
1461 | GNUNET_SCHEDULER_cancel (sock->read_task); | 1450 | GNUNET_SCHEDULER_cancel (sock->read_task); |
1462 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; | 1451 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; |
1463 | signal_timeout (sock); | 1452 | signal_timeout (sock); |
1464 | return; | 1453 | return; |
1465 | } | 1454 | } |
1466 | if (sock->nth.notify_ready == NULL) | 1455 | if (sock->nth.notify_ready == NULL) |
1467 | return; /* nobody to tell about it */ | 1456 | return; /* nobody to tell about it */ |
1468 | notify = sock->nth.notify_ready; | 1457 | notify = sock->nth.notify_ready; |
1469 | sock->nth.notify_ready = NULL; | 1458 | sock->nth.notify_ready = NULL; |
1470 | notify (sock->nth.notify_ready_cls, 0, NULL); | 1459 | notify (sock->nth.notify_ready_cls, 0, NULL); |
@@ -1494,109 +1483,107 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1494 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; | 1483 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; |
1495 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); | 1484 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); |
1496 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 1485 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
1497 | { | 1486 | { |
1498 | if ( (sock->ignore_shutdown == GNUNET_YES) && | 1487 | if ((sock->ignore_shutdown == GNUNET_YES) && (NULL != sock->sock)) |
1499 | (NULL != sock->sock) ) | 1488 | goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */ |
1500 | goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */ | ||
1501 | #if DEBUG_CONNECTION | 1489 | #if DEBUG_CONNECTION |
1502 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1490 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1503 | "Transmit to `%s' fails, shutdown happened (%p).\n", | 1491 | "Transmit to `%s' fails, shutdown happened (%p).\n", |
1504 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | 1492 | GNUNET_a2s (sock->addr, sock->addrlen), sock); |
1505 | #endif | 1493 | #endif |
1506 | notify = sock->nth.notify_ready; | 1494 | notify = sock->nth.notify_ready; |
1507 | if (NULL != notify) | 1495 | if (NULL != notify) |
1508 | { | ||
1509 | sock->nth.notify_ready = NULL; | ||
1510 | notify (sock->nth.notify_ready_cls, 0, NULL); | ||
1511 | } | ||
1512 | return; | ||
1513 | } | ||
1514 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | ||
1515 | { | 1496 | { |
1516 | #if DEBUG_CONNECTION | ||
1517 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1518 | "Transmit to `%s' fails, time out reached (%p).\n", | ||
1519 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | ||
1520 | #endif | ||
1521 | notify = sock->nth.notify_ready; | ||
1522 | GNUNET_assert (NULL != notify); | ||
1523 | sock->nth.notify_ready = NULL; | 1497 | sock->nth.notify_ready = NULL; |
1524 | notify (sock->nth.notify_ready_cls, 0, NULL); | 1498 | notify (sock->nth.notify_ready_cls, 0, NULL); |
1525 | return; | ||
1526 | } | 1499 | } |
1500 | return; | ||
1501 | } | ||
1502 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | ||
1503 | { | ||
1504 | #if DEBUG_CONNECTION | ||
1505 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1506 | "Transmit to `%s' fails, time out reached (%p).\n", | ||
1507 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | ||
1508 | #endif | ||
1509 | notify = sock->nth.notify_ready; | ||
1510 | GNUNET_assert (NULL != notify); | ||
1511 | sock->nth.notify_ready = NULL; | ||
1512 | notify (sock->nth.notify_ready_cls, 0, NULL); | ||
1513 | return; | ||
1514 | } | ||
1527 | GNUNET_assert (NULL != sock->sock); | 1515 | GNUNET_assert (NULL != sock->sock); |
1528 | if (tc->write_ready == NULL) | 1516 | if (tc->write_ready == NULL) |
1529 | { | 1517 | { |
1530 | /* special circumstances (in particular, | 1518 | /* special circumstances (in particular, |
1531 | * PREREQ_DONE after connect): not yet ready to write, | 1519 | * PREREQ_DONE after connect): not yet ready to write, |
1532 | * but no "fatal" error either. Hence retry. */ | 1520 | * but no "fatal" error either. Hence retry. */ |
1533 | goto SCHEDULE_WRITE; | 1521 | goto SCHEDULE_WRITE; |
1534 | } | 1522 | } |
1535 | if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)) | 1523 | if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)) |
1536 | { | 1524 | { |
1537 | #if DEBUG_CONNECTION | 1525 | #if DEBUG_CONNECTION |
1538 | LOG (GNUNET_ERROR_TYPE_INFO, | 1526 | LOG (GNUNET_ERROR_TYPE_INFO, |
1539 | _ | 1527 | _ |
1540 | ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"), | 1528 | ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"), |
1541 | sock); | 1529 | sock); |
1542 | #endif | 1530 | #endif |
1543 | transmit_error (sock); | 1531 | transmit_error (sock); |
1544 | return; /* connect failed for good, we're finished */ | 1532 | return; /* connect failed for good, we're finished */ |
1545 | } | 1533 | } |
1546 | GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos); | 1534 | GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos); |
1547 | if ((sock->nth.notify_ready != NULL) && | 1535 | if ((sock->nth.notify_ready != NULL) && |
1548 | (sock->write_buffer_size < sock->nth.notify_size)) | 1536 | (sock->write_buffer_size < sock->nth.notify_size)) |
1549 | { | 1537 | { |
1550 | sock->write_buffer = | 1538 | sock->write_buffer = |
1551 | GNUNET_realloc (sock->write_buffer, sock->nth.notify_size); | 1539 | GNUNET_realloc (sock->write_buffer, sock->nth.notify_size); |
1552 | sock->write_buffer_size = sock->nth.notify_size; | 1540 | sock->write_buffer_size = sock->nth.notify_size; |
1553 | } | 1541 | } |
1554 | process_notify (sock); | 1542 | process_notify (sock); |
1555 | have = sock->write_buffer_off - sock->write_buffer_pos; | 1543 | have = sock->write_buffer_off - sock->write_buffer_pos; |
1556 | if (have == 0) | 1544 | if (have == 0) |
1557 | { | 1545 | { |
1558 | /* no data ready for writing, terminate write loop */ | 1546 | /* no data ready for writing, terminate write loop */ |
1559 | return; | 1547 | return; |
1560 | } | 1548 | } |
1561 | GNUNET_assert (have <= sock->write_buffer_size); | 1549 | GNUNET_assert (have <= sock->write_buffer_size); |
1562 | GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size); | 1550 | GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size); |
1563 | GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); | 1551 | GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); |
1564 | RETRY: | 1552 | RETRY: |
1565 | ret = | 1553 | ret = |
1566 | GNUNET_NETWORK_socket_send (sock->sock, | 1554 | GNUNET_NETWORK_socket_send (sock->sock, |
1567 | &sock->write_buffer[sock->write_buffer_pos], | 1555 | &sock->write_buffer[sock->write_buffer_pos], |
1568 | have); | 1556 | have); |
1569 | if (ret == -1) | 1557 | if (ret == -1) |
1570 | { | 1558 | { |
1571 | if (errno == EINTR) | 1559 | if (errno == EINTR) |
1572 | goto RETRY; | 1560 | goto RETRY; |
1573 | #if 0 | 1561 | #if 0 |
1574 | int en = errno; | 1562 | int en = errno; |
1575 | 1563 | ||
1576 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to send to `%s': %s\n"), | 1564 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to send to `%s': %s\n"), |
1577 | GNUNET_a2s (sock->addr, sock->addrlen), STRERROR (en)); | 1565 | GNUNET_a2s (sock->addr, sock->addrlen), STRERROR (en)); |
1578 | #endif | 1566 | #endif |
1579 | #if DEBUG_CONNECTION | 1567 | #if DEBUG_CONNECTION |
1580 | LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "send"); | 1568 | LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "send"); |
1581 | #endif | 1569 | #endif |
1582 | transmit_error (sock); | 1570 | transmit_error (sock); |
1583 | return; | 1571 | return; |
1584 | } | 1572 | } |
1585 | #if DEBUG_CONNECTION | 1573 | #if DEBUG_CONNECTION |
1586 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1574 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1587 | "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n", | 1575 | "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n", |
1588 | (unsigned int) ret, have, GNUNET_a2s (sock->addr, sock->addrlen), | 1576 | (unsigned int) ret, have, GNUNET_a2s (sock->addr, sock->addrlen), sock); |
1589 | sock); | ||
1590 | #endif | 1577 | #endif |
1591 | sock->write_buffer_pos += ret; | 1578 | sock->write_buffer_pos += ret; |
1592 | if (sock->write_buffer_pos == sock->write_buffer_off) | 1579 | if (sock->write_buffer_pos == sock->write_buffer_off) |
1593 | { | 1580 | { |
1594 | /* transmitted all pending data */ | 1581 | /* transmitted all pending data */ |
1595 | sock->write_buffer_pos = 0; | 1582 | sock->write_buffer_pos = 0; |
1596 | sock->write_buffer_off = 0; | 1583 | sock->write_buffer_off = 0; |
1597 | } | 1584 | } |
1598 | if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready)) | 1585 | if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready)) |
1599 | return; /* all data sent! */ | 1586 | return; /* all data sent! */ |
1600 | /* not done writing, schedule more */ | 1587 | /* not done writing, schedule more */ |
1601 | SCHEDULE_WRITE: | 1588 | SCHEDULE_WRITE: |
1602 | #if DEBUG_CONNECTION | 1589 | #if DEBUG_CONNECTION |
@@ -1607,11 +1594,11 @@ SCHEDULE_WRITE: | |||
1607 | GNUNET_assert ((sock->nth.notify_ready != NULL) || (have > 0)); | 1594 | GNUNET_assert ((sock->nth.notify_ready != NULL) || (have > 0)); |
1608 | if (sock->write_task == GNUNET_SCHEDULER_NO_TASK) | 1595 | if (sock->write_task == GNUNET_SCHEDULER_NO_TASK) |
1609 | sock->write_task = | 1596 | sock->write_task = |
1610 | GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == | 1597 | GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == |
1611 | NULL) ? GNUNET_TIME_UNIT_FOREVER_REL : | 1598 | NULL) ? GNUNET_TIME_UNIT_FOREVER_REL : |
1612 | GNUNET_TIME_absolute_get_remaining | 1599 | GNUNET_TIME_absolute_get_remaining |
1613 | (sock->nth.transmit_timeout), | 1600 | (sock->nth.transmit_timeout), |
1614 | sock->sock, &transmit_ready, sock); | 1601 | sock->sock, &transmit_ready, sock); |
1615 | } | 1602 | } |
1616 | 1603 | ||
1617 | 1604 | ||
@@ -1630,17 +1617,17 @@ SCHEDULE_WRITE: | |||
1630 | * NULL if we are already going to notify someone else (busy) | 1617 | * NULL if we are already going to notify someone else (busy) |
1631 | */ | 1618 | */ |
1632 | struct GNUNET_CONNECTION_TransmitHandle * | 1619 | struct GNUNET_CONNECTION_TransmitHandle * |
1633 | GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle | 1620 | GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *sock, |
1634 | *sock, size_t size, | 1621 | size_t size, |
1635 | struct GNUNET_TIME_Relative timeout, | 1622 | struct GNUNET_TIME_Relative timeout, |
1636 | GNUNET_CONNECTION_TransmitReadyNotify | 1623 | GNUNET_CONNECTION_TransmitReadyNotify |
1637 | notify, void *notify_cls) | 1624 | notify, void *notify_cls) |
1638 | { | 1625 | { |
1639 | if (sock->nth.notify_ready != NULL) | 1626 | if (sock->nth.notify_ready != NULL) |
1640 | { | 1627 | { |
1641 | GNUNET_assert (0); | 1628 | GNUNET_assert (0); |
1642 | return NULL; | 1629 | return NULL; |
1643 | } | 1630 | } |
1644 | GNUNET_assert (notify != NULL); | 1631 | GNUNET_assert (notify != NULL); |
1645 | GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1632 | GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1646 | GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size); | 1633 | GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size); |
@@ -1654,36 +1641,34 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle | |||
1654 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task); | 1641 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task); |
1655 | if ((sock->sock == NULL) && (sock->ap_head == NULL) && | 1642 | if ((sock->sock == NULL) && (sock->ap_head == NULL) && |
1656 | (sock->dns_active == NULL)) | 1643 | (sock->dns_active == NULL)) |
1657 | { | 1644 | { |
1658 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 1645 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) |
1659 | GNUNET_SCHEDULER_cancel (sock->write_task); | 1646 | GNUNET_SCHEDULER_cancel (sock->write_task); |
1660 | sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock); | 1647 | sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock); |
1661 | return &sock->nth; | 1648 | return &sock->nth; |
1662 | } | 1649 | } |
1663 | if (GNUNET_SCHEDULER_NO_TASK != sock->write_task) | 1650 | if (GNUNET_SCHEDULER_NO_TASK != sock->write_task) |
1664 | return &sock->nth; | 1651 | return &sock->nth; |
1665 | if (sock->sock != NULL) | 1652 | if (sock->sock != NULL) |
1666 | { | 1653 | { |
1667 | #if DEBUG_CONNECTION | 1654 | #if DEBUG_CONNECTION |
1668 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmit_ready (%p).\n", | 1655 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmit_ready (%p).\n", sock); |
1669 | sock); | ||
1670 | #endif | 1656 | #endif |
1671 | sock->write_task = | 1657 | sock->write_task = |
1672 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining | 1658 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining |
1673 | (sock->nth.transmit_timeout), | 1659 | (sock->nth.transmit_timeout), |
1674 | sock->sock, &transmit_ready, sock); | 1660 | sock->sock, &transmit_ready, sock); |
1675 | } | 1661 | } |
1676 | else | 1662 | else |
1677 | { | 1663 | { |
1678 | #if DEBUG_CONNECTION | 1664 | #if DEBUG_CONNECTION |
1679 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1665 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1680 | "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", | 1666 | "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", sock); |
1681 | sock); | ||
1682 | #endif | 1667 | #endif |
1683 | sock->ccs |= COCO_TRANSMIT_READY; | 1668 | sock->ccs |= COCO_TRANSMIT_READY; |
1684 | sock->nth.timeout_task = | 1669 | sock->nth.timeout_task = |
1685 | GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, sock); | 1670 | GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, sock); |
1686 | } | 1671 | } |
1687 | return &sock->nth; | 1672 | return &sock->nth; |
1688 | } | 1673 | } |
1689 | 1674 | ||
@@ -1695,28 +1680,28 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle | |||
1695 | */ | 1680 | */ |
1696 | void | 1681 | void |
1697 | GNUNET_CONNECTION_notify_transmit_ready_cancel (struct | 1682 | GNUNET_CONNECTION_notify_transmit_ready_cancel (struct |
1698 | GNUNET_CONNECTION_TransmitHandle | 1683 | GNUNET_CONNECTION_TransmitHandle |
1699 | *th) | 1684 | *th) |
1700 | { | 1685 | { |
1701 | GNUNET_assert (th->notify_ready != NULL); | 1686 | GNUNET_assert (th->notify_ready != NULL); |
1702 | if (0 != (th->sh->ccs & COCO_TRANSMIT_READY)) | 1687 | if (0 != (th->sh->ccs & COCO_TRANSMIT_READY)) |
1703 | { | 1688 | { |
1704 | #if DEBUG_CONNECTION | 1689 | #if DEBUG_CONNECTION |
1705 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1690 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1706 | "notify_transmit_ready_cancel cancels timeout_task (%p)\n", th); | 1691 | "notify_transmit_ready_cancel cancels timeout_task (%p)\n", th); |
1707 | #endif | 1692 | #endif |
1708 | GNUNET_SCHEDULER_cancel (th->timeout_task); | 1693 | GNUNET_SCHEDULER_cancel (th->timeout_task); |
1709 | th->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1694 | th->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1710 | th->sh->ccs -= COCO_TRANSMIT_READY; | 1695 | th->sh->ccs -= COCO_TRANSMIT_READY; |
1711 | } | 1696 | } |
1712 | else | 1697 | else |
1698 | { | ||
1699 | if (th->sh->write_task != GNUNET_SCHEDULER_NO_TASK) | ||
1713 | { | 1700 | { |
1714 | if (th->sh->write_task != GNUNET_SCHEDULER_NO_TASK) | 1701 | GNUNET_SCHEDULER_cancel (th->sh->write_task); |
1715 | { | 1702 | th->sh->write_task = GNUNET_SCHEDULER_NO_TASK; |
1716 | GNUNET_SCHEDULER_cancel (th->sh->write_task); | ||
1717 | th->sh->write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1718 | } | ||
1719 | } | 1703 | } |
1704 | } | ||
1720 | th->notify_ready = NULL; | 1705 | th->notify_ready = NULL; |
1721 | } | 1706 | } |
1722 | 1707 | ||