diff options
Diffstat (limited to 'src/util/connection.c')
-rw-r--r-- | src/util/connection.c | 1020 |
1 files changed, 496 insertions, 524 deletions
diff --git a/src/util/connection.c b/src/util/connection.c index f26130a06..1ac1b2304 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -296,7 +296,8 @@ struct GNUNET_CONNECTION_Handle | |||
296 | * | 296 | * |
297 | * @param sock the connection to set persistent | 297 | * @param sock the connection to set persistent |
298 | */ | 298 | */ |
299 | void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock) | 299 | void |
300 | GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *sock) | ||
300 | { | 301 | { |
301 | sock->persist = GNUNET_YES; | 302 | sock->persist = GNUNET_YES; |
302 | } | 303 | } |
@@ -313,7 +314,8 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock) | |||
313 | * @param sock the connection to make flushing and blocking | 314 | * @param sock the connection to make flushing and blocking |
314 | * @return GNUNET_OK on success | 315 | * @return GNUNET_OK on success |
315 | */ | 316 | */ |
316 | int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) | 317 | int |
318 | GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) | ||
317 | { | 319 | { |
318 | return GNUNET_NETWORK_socket_disable_corking (sock->sock); | 320 | return GNUNET_NETWORK_socket_disable_corking (sock->sock); |
319 | } | 321 | } |
@@ -327,13 +329,13 @@ int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) | |||
327 | * @return the boxed socket handle | 329 | * @return the boxed socket handle |
328 | */ | 330 | */ |
329 | struct GNUNET_CONNECTION_Handle * | 331 | struct GNUNET_CONNECTION_Handle * |
330 | GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle | 332 | GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) |
331 | *osSocket) | ||
332 | { | 333 | { |
333 | struct GNUNET_CONNECTION_Handle *ret; | 334 | struct GNUNET_CONNECTION_Handle *ret; |
335 | |||
334 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 336 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
335 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 337 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
336 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); | 338 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); |
337 | ret->sock = osSocket; | 339 | ret->sock = osSocket; |
338 | return ret; | 340 | return ret; |
339 | } | 341 | } |
@@ -362,8 +364,9 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, | |||
362 | struct sockaddr_in6 *v6; | 364 | struct sockaddr_in6 *v6; |
363 | struct sockaddr *sa; | 365 | struct sockaddr *sa; |
364 | void *uaddr; | 366 | void *uaddr; |
365 | struct GNUNET_CONNECTION_Credentials *gcp; | 367 | struct GNUNET_CONNECTION_Credentials *gcp; |
366 | struct GNUNET_CONNECTION_Credentials gc; | 368 | struct GNUNET_CONNECTION_Credentials gc; |
369 | |||
367 | #ifdef SO_PEERCRED | 370 | #ifdef SO_PEERCRED |
368 | struct ucred uc; | 371 | struct ucred uc; |
369 | socklen_t olen; | 372 | socklen_t olen; |
@@ -371,102 +374,98 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, | |||
371 | 374 | ||
372 | addrlen = sizeof (addr); | 375 | addrlen = sizeof (addr); |
373 | sock = | 376 | sock = |
374 | GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen); | 377 | GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen); |
375 | if (NULL == sock) | 378 | if (NULL == sock) |
376 | { | 379 | { |
377 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | 380 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); |
378 | return NULL; | 381 | return NULL; |
379 | } | 382 | } |
380 | if ( (addrlen > sizeof (addr)) || | 383 | if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t))) |
381 | (addrlen < sizeof (sa_family_t)) ) | 384 | { |
382 | { | 385 | GNUNET_break (0); |
383 | GNUNET_break (0); | 386 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
384 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 387 | return NULL; |
385 | return NULL; | 388 | } |
386 | } | ||
387 | 389 | ||
388 | sa = (struct sockaddr *) addr; | 390 | sa = (struct sockaddr *) addr; |
389 | v6 = (struct sockaddr_in6 *) addr; | 391 | v6 = (struct sockaddr_in6 *) addr; |
390 | if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) | 392 | if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) |
391 | { | 393 | { |
392 | /* convert to V4 address */ | 394 | /* convert to V4 address */ |
393 | v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); | 395 | v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); |
394 | memset (v4, 0, sizeof (struct sockaddr_in)); | 396 | memset (v4, 0, sizeof (struct sockaddr_in)); |
395 | v4->sin_family = AF_INET; | 397 | v4->sin_family = AF_INET; |
396 | #if HAVE_SOCKADDR_IN_SIN_LEN | 398 | #if HAVE_SOCKADDR_IN_SIN_LEN |
397 | v4->sin_len = (u_char) sizeof (struct sockaddr_in); | 399 | v4->sin_len = (u_char) sizeof (struct sockaddr_in); |
398 | #endif | 400 | #endif |
399 | memcpy (&v4->sin_addr, | 401 | memcpy (&v4->sin_addr, |
400 | &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) - | 402 | &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) - |
401 | sizeof (struct in_addr)], | 403 | sizeof (struct in_addr)], |
402 | sizeof (struct in_addr)); | 404 | sizeof (struct in_addr)); |
403 | v4->sin_port = v6->sin6_port; | 405 | v4->sin_port = v6->sin6_port; |
404 | uaddr = v4; | 406 | uaddr = v4; |
405 | addrlen = sizeof (struct sockaddr_in); | 407 | addrlen = sizeof (struct sockaddr_in); |
406 | } | 408 | } |
407 | else | 409 | else |
408 | { | 410 | { |
409 | uaddr = GNUNET_malloc (addrlen); | 411 | uaddr = GNUNET_malloc (addrlen); |
410 | memcpy (uaddr, addr, addrlen); | 412 | memcpy (uaddr, addr, addrlen); |
411 | } | 413 | } |
412 | gcp = NULL; | 414 | gcp = NULL; |
413 | gc.uid = 0; | 415 | gc.uid = 0; |
414 | gc.gid = 0; | 416 | gc.gid = 0; |
415 | if (sa->sa_family == AF_UNIX) | 417 | if (sa->sa_family == AF_UNIX) |
416 | { | 418 | { |
417 | #if HAVE_GETPEEREID | 419 | #if HAVE_GETPEEREID |
418 | /* most BSDs */ | 420 | /* most BSDs */ |
419 | if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), | 421 | if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid)) |
420 | &gc.uid, | 422 | gcp = &gc; |
421 | &gc.gid)) | ||
422 | gcp = &gc; | ||
423 | #else | 423 | #else |
424 | #ifdef SO_PEERCRED | 424 | #ifdef SO_PEERCRED |
425 | /* largely traditional GNU/Linux */ | 425 | /* largely traditional GNU/Linux */ |
426 | olen = sizeof (uc); | 426 | olen = sizeof (uc); |
427 | if ( (0 == | 427 | if ((0 == |
428 | getsockopt (GNUNET_NETWORK_get_fd (sock), | 428 | getsockopt (GNUNET_NETWORK_get_fd (sock), |
429 | SOL_SOCKET, SO_PEERCRED, &uc, &olen)) && | 429 | SOL_SOCKET, SO_PEERCRED, &uc, &olen)) && |
430 | (olen == sizeof (uc)) ) | 430 | (olen == sizeof (uc))) |
431 | { | 431 | { |
432 | gc.uid = uc.uid; | 432 | gc.uid = uc.uid; |
433 | gc.gid = uc.gid; | 433 | gc.gid = uc.gid; |
434 | gcp = &gc; | 434 | gcp = &gc; |
435 | } | 435 | } |
436 | #else | 436 | #else |
437 | #if HAVE_GETPEERUCRED | 437 | #if HAVE_GETPEERUCRED |
438 | /* this is for Solaris 10 */ | 438 | /* this is for Solaris 10 */ |
439 | ucred_t *uc; | 439 | ucred_t *uc; |
440 | 440 | ||
441 | uc = NULL; | 441 | uc = NULL; |
442 | if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc)) | 442 | if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc)) |
443 | { | 443 | { |
444 | gc.uid = ucred_geteuid (uc); | 444 | gc.uid = ucred_geteuid (uc); |
445 | gc.gid = ucred_getegid (uc); | 445 | gc.gid = ucred_getegid (uc); |
446 | gcp = &gc; | 446 | gcp = &gc; |
447 | } | 447 | } |
448 | ucred_free (uc); | 448 | ucred_free (uc); |
449 | #endif | 449 | #endif |
450 | #endif | 450 | #endif |
451 | #endif | 451 | #endif |
452 | } | 452 | } |
453 | 453 | ||
454 | if ((access != NULL) && | 454 | if ((access != NULL) && |
455 | (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) | 455 | (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) |
456 | { | 456 | { |
457 | if (aret == GNUNET_NO) | 457 | if (aret == GNUNET_NO) |
458 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 458 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
459 | _("Access denied to `%s'\n"), | 459 | _("Access denied to `%s'\n"), GNUNET_a2s (uaddr, addrlen)); |
460 | GNUNET_a2s (uaddr, addrlen)); | 460 | GNUNET_break (GNUNET_OK == |
461 | GNUNET_break (GNUNET_OK == | 461 | GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR)); |
462 | GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR)); | 462 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
463 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 463 | GNUNET_free (uaddr); |
464 | GNUNET_free (uaddr); | 464 | return NULL; |
465 | return NULL; | 465 | } |
466 | } | ||
467 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 466 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
468 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 467 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
469 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); | 468 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); |
470 | ret->addr = uaddr; | 469 | ret->addr = uaddr; |
471 | ret->addrlen = addrlen; | 470 | ret->addrlen = addrlen; |
472 | ret->sock = sock; | 471 | ret->sock = sock; |
@@ -521,8 +520,7 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | |||
521 | * @param tc unused | 520 | * @param tc unused |
522 | */ | 521 | */ |
523 | static void | 522 | static void |
524 | destroy_continuation (void *cls, | 523 | destroy_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
525 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
526 | { | 524 | { |
527 | struct GNUNET_CONNECTION_Handle *sock = cls; | 525 | struct GNUNET_CONNECTION_Handle *sock = cls; |
528 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 526 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
@@ -531,80 +529,77 @@ destroy_continuation (void *cls, | |||
531 | sock->destroy_task = GNUNET_SCHEDULER_NO_TASK; | 529 | sock->destroy_task = GNUNET_SCHEDULER_NO_TASK; |
532 | GNUNET_assert (sock->dns_active == NULL); | 530 | GNUNET_assert (sock->dns_active == NULL); |
533 | if (0 != (sock->ccs & COCO_TRANSMIT_READY)) | 531 | if (0 != (sock->ccs & COCO_TRANSMIT_READY)) |
534 | { | 532 | { |
535 | #if DEBUG_CONNECTION | 533 | #if DEBUG_CONNECTION |
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
537 | "Destroy waits for CCS-TR to be done (%p)\n", sock); | 535 | "Destroy waits for CCS-TR to be done (%p)\n", sock); |
538 | #endif | 536 | #endif |
539 | sock->ccs |= COCO_DESTROY_CONTINUATION; | 537 | sock->ccs |= COCO_DESTROY_CONTINUATION; |
540 | return; | 538 | return; |
541 | } | 539 | } |
542 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 540 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) |
543 | { | 541 | { |
544 | #if DEBUG_CONNECTION | 542 | #if DEBUG_CONNECTION |
545 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
546 | "Destroy waits for write_task to be done (%p)\n", sock); | 544 | "Destroy waits for write_task to be done (%p)\n", sock); |
547 | #endif | 545 | #endif |
548 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 546 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
549 | sock->destroy_task | 547 | sock->destroy_task |
550 | = GNUNET_SCHEDULER_add_after (sock->write_task, | 548 | = GNUNET_SCHEDULER_add_after (sock->write_task, |
551 | &destroy_continuation, sock); | 549 | &destroy_continuation, sock); |
552 | return; | 550 | return; |
553 | } | 551 | } |
554 | if (0 != (sock->ccs & COCO_RECEIVE_AGAIN)) | 552 | if (0 != (sock->ccs & COCO_RECEIVE_AGAIN)) |
555 | { | 553 | { |
556 | sock->ccs |= COCO_DESTROY_CONTINUATION; | 554 | sock->ccs |= COCO_DESTROY_CONTINUATION; |
557 | return; | 555 | return; |
558 | } | 556 | } |
559 | if (sock->sock != NULL) | 557 | if (sock->sock != NULL) |
560 | { | 558 | { |
561 | #if DEBUG_CONNECTION | 559 | #if DEBUG_CONNECTION |
562 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 560 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket (%p)\n", sock); |
563 | "Shutting down socket (%p)\n", sock); | ||
564 | #endif | 561 | #endif |
565 | if (sock->persist != GNUNET_YES) | 562 | if (sock->persist != GNUNET_YES) |
566 | { | ||
567 | if ( (GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR)) && | ||
568 | (errno != ENOTCONN) && | ||
569 | (errno != ECONNRESET) ) | ||
570 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "shutdown"); | ||
571 | } | ||
572 | } | ||
573 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | ||
574 | { | 563 | { |
575 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 564 | if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR)) |
576 | sock->destroy_task | 565 | && (errno != ENOTCONN) && (errno != ECONNRESET)) |
577 | = GNUNET_SCHEDULER_add_after (sock->read_task, | 566 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "shutdown"); |
578 | &destroy_continuation, sock); | ||
579 | return; | ||
580 | } | 567 | } |
568 | } | ||
569 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | ||
570 | { | ||
571 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | ||
572 | sock->destroy_task | ||
573 | = GNUNET_SCHEDULER_add_after (sock->read_task, | ||
574 | &destroy_continuation, sock); | ||
575 | return; | ||
576 | } | ||
581 | #if DEBUG_CONNECTION | 577 | #if DEBUG_CONNECTION |
582 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", sock); |
583 | "Destroy actually runs (%p)!\n", sock); | ||
584 | #endif | 579 | #endif |
585 | while (NULL != (pos = sock->ap_head)) | 580 | while (NULL != (pos = sock->ap_head)) |
586 | { | 581 | { |
587 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); | 582 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); |
588 | GNUNET_SCHEDULER_cancel (pos->task); | 583 | GNUNET_SCHEDULER_cancel (pos->task); |
589 | GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos); | 584 | GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos); |
590 | GNUNET_free (pos); | 585 | GNUNET_free (pos); |
591 | } | 586 | } |
592 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); | 587 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); |
593 | GNUNET_assert (sock->ccs == COCO_NONE); | 588 | GNUNET_assert (sock->ccs == COCO_NONE); |
594 | if (NULL != (notify = sock->nth.notify_ready)) | 589 | if (NULL != (notify = sock->nth.notify_ready)) |
595 | { | 590 | { |
596 | sock->nth.notify_ready = NULL; | 591 | sock->nth.notify_ready = NULL; |
597 | notify (sock->nth.notify_ready_cls, 0, NULL); | 592 | notify (sock->nth.notify_ready_cls, 0, NULL); |
598 | } | 593 | } |
599 | 594 | ||
600 | if (sock->sock != NULL) | 595 | if (sock->sock != NULL) |
601 | { | 596 | { |
602 | if (sock->persist != GNUNET_YES) | 597 | if (sock->persist != GNUNET_YES) |
603 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); | 598 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); |
604 | else | 599 | else |
605 | GNUNET_free (sock->sock); /* at least no memory leak (we deliberately | 600 | GNUNET_free (sock->sock); /* at least no memory leak (we deliberately |
606 | leak the socket in this special case) ... */ | 601 | * leak the socket in this special case) ... */ |
607 | } | 602 | } |
608 | GNUNET_free_non_null (sock->addr); | 603 | GNUNET_free_non_null (sock->addr); |
609 | GNUNET_free_non_null (sock->hostname); | 604 | GNUNET_free_non_null (sock->hostname); |
610 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 605 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
@@ -639,12 +634,13 @@ static void | |||
639 | connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) | 634 | connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) |
640 | { | 635 | { |
641 | #if DEBUG_CONNECTION | 636 | #if DEBUG_CONNECTION |
642 | GNUNET_log ((0 != strncmp (h->hostname, | 637 | GNUNET_log ((0 != strncmp (h->hostname, |
643 | "localhost:", | 638 | "localhost:", |
644 | 10)) | 639 | 10)) |
645 | ? GNUNET_ERROR_TYPE_INFO | 640 | ? GNUNET_ERROR_TYPE_INFO |
646 | : GNUNET_ERROR_TYPE_WARNING, | 641 | : GNUNET_ERROR_TYPE_WARNING, |
647 | _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), | 642 | _ |
643 | ("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), | ||
648 | h->hostname, h->port); | 644 | h->hostname, h->port); |
649 | #endif | 645 | #endif |
650 | /* connect failed / timed out */ | 646 | /* connect failed / timed out */ |
@@ -655,43 +651,40 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
655 | 651 | ||
656 | /* trigger jobs that used to wait on "connect_task" */ | 652 | /* trigger jobs that used to wait on "connect_task" */ |
657 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) | 653 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) |
658 | { | 654 | { |
659 | #if DEBUG_CONNECTION | 655 | #if DEBUG_CONNECTION |
660 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 656 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
661 | "connect_fail_continuation triggers receive_again (%p)\n", | 657 | "connect_fail_continuation triggers receive_again (%p)\n", h); |
662 | h); | ||
663 | #endif | 658 | #endif |
664 | h->ccs -= COCO_RECEIVE_AGAIN; | 659 | h->ccs -= COCO_RECEIVE_AGAIN; |
665 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); | 660 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); |
666 | } | 661 | } |
667 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) | 662 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) |
668 | { | 663 | { |
669 | #if DEBUG_CONNECTION | 664 | #if DEBUG_CONNECTION |
670 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 665 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
671 | "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n", | 666 | "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n", |
672 | h); | 667 | h); |
673 | #endif | 668 | #endif |
674 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); | 669 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); |
675 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); | 670 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); |
676 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 671 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
677 | h->ccs -= COCO_TRANSMIT_READY; | 672 | h->ccs -= COCO_TRANSMIT_READY; |
678 | GNUNET_assert (h->nth.notify_ready != NULL); | 673 | GNUNET_assert (h->nth.notify_ready != NULL); |
679 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); | 674 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); |
680 | h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); | 675 | h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); |
681 | } | 676 | } |
682 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) | 677 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) |
683 | { | 678 | { |
684 | #if DEBUG_CONNECTION | 679 | #if DEBUG_CONNECTION |
685 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 680 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
686 | "connect_fail_continuation runs destroy_continuation (%p)\n", | 681 | "connect_fail_continuation runs destroy_continuation (%p)\n", |
687 | h); | 682 | h); |
688 | #endif | 683 | #endif |
689 | h->ccs -= COCO_DESTROY_CONTINUATION; | 684 | h->ccs -= COCO_DESTROY_CONTINUATION; |
690 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); | 685 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); |
691 | h->destroy_task | 686 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); |
692 | = GNUNET_SCHEDULER_add_now (&destroy_continuation, | 687 | } |
693 | h); | ||
694 | } | ||
695 | } | 688 | } |
696 | 689 | ||
697 | 690 | ||
@@ -710,46 +703,43 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *h) | |||
710 | #endif | 703 | #endif |
711 | /* trigger jobs that waited for the connection */ | 704 | /* trigger jobs that waited for the connection */ |
712 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) | 705 | if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) |
713 | { | 706 | { |
714 | #if DEBUG_CONNECTION | 707 | #if DEBUG_CONNECTION |
715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 708 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
716 | "connect_success_continuation runs receive_again (%p)\n", | 709 | "connect_success_continuation runs receive_again (%p)\n", h); |
717 | h); | ||
718 | #endif | 710 | #endif |
719 | h->ccs -= COCO_RECEIVE_AGAIN; | 711 | h->ccs -= COCO_RECEIVE_AGAIN; |
720 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); | 712 | h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); |
721 | } | 713 | } |
722 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) | 714 | if (0 != (h->ccs & COCO_TRANSMIT_READY)) |
723 | { | 715 | { |
724 | #if DEBUG_CONNECTION | 716 | #if DEBUG_CONNECTION |
725 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 717 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
726 | "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n", | 718 | "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n", |
727 | h); | 719 | h); |
728 | #endif | 720 | #endif |
729 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); | 721 | GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); |
730 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); | 722 | GNUNET_SCHEDULER_cancel (h->nth.timeout_task); |
731 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 723 | h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
732 | h->ccs -= COCO_TRANSMIT_READY; | 724 | h->ccs -= COCO_TRANSMIT_READY; |
733 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); | 725 | GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); |
734 | GNUNET_assert (h->nth.notify_ready != NULL); | 726 | GNUNET_assert (h->nth.notify_ready != NULL); |
735 | h->write_task = | 727 | h->write_task = |
736 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining | 728 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining |
737 | (h->nth.transmit_timeout), h->sock, | 729 | (h->nth.transmit_timeout), h->sock, |
738 | &transmit_ready, h); | 730 | &transmit_ready, h); |
739 | } | 731 | } |
740 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) | 732 | if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) |
741 | { | 733 | { |
742 | #if DEBUG_CONNECTION | 734 | #if DEBUG_CONNECTION |
743 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 735 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
744 | "connect_success_continuation runs destroy_continuation (%p)\n", | 736 | "connect_success_continuation runs destroy_continuation (%p)\n", |
745 | h); | 737 | h); |
746 | #endif | 738 | #endif |
747 | h->ccs -= COCO_DESTROY_CONTINUATION; | 739 | h->ccs -= COCO_DESTROY_CONTINUATION; |
748 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); | 740 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); |
749 | h->destroy_task | 741 | h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); |
750 | = GNUNET_SCHEDULER_add_now (&destroy_continuation, | 742 | } |
751 | h); | ||
752 | } | ||
753 | } | 743 | } |
754 | 744 | ||
755 | 745 | ||
@@ -775,18 +765,17 @@ connect_probe_continuation (void *cls, | |||
775 | len = sizeof (error); | 765 | len = sizeof (error); |
776 | errno = 0; | 766 | errno = 0; |
777 | error = 0; | 767 | error = 0; |
778 | if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || | 768 | if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || |
779 | (GNUNET_OK != | 769 | (GNUNET_OK != |
780 | GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, | 770 | GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, |
781 | &error, &len)) || | 771 | &error, &len)) || (error != 0)) |
782 | (error != 0) ) | 772 | { |
783 | { | 773 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); |
784 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); | 774 | GNUNET_free (ap); |
785 | GNUNET_free (ap); | 775 | if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO)) |
786 | if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO)) | 776 | connect_fail_continuation (h); |
787 | connect_fail_continuation (h); | 777 | return; |
788 | return; | 778 | } |
789 | } | ||
790 | GNUNET_assert (h->sock == NULL); | 779 | GNUNET_assert (h->sock == NULL); |
791 | h->sock = ap->sock; | 780 | h->sock = ap->sock; |
792 | GNUNET_assert (h->addr == NULL); | 781 | GNUNET_assert (h->addr == NULL); |
@@ -796,12 +785,12 @@ connect_probe_continuation (void *cls, | |||
796 | GNUNET_free (ap); | 785 | GNUNET_free (ap); |
797 | /* cancel all other attempts */ | 786 | /* cancel all other attempts */ |
798 | while (NULL != (pos = h->ap_head)) | 787 | while (NULL != (pos = h->ap_head)) |
799 | { | 788 | { |
800 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); | 789 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); |
801 | GNUNET_SCHEDULER_cancel (pos->task); | 790 | GNUNET_SCHEDULER_cancel (pos->task); |
802 | GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos); | 791 | GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos); |
803 | GNUNET_free (pos); | 792 | GNUNET_free (pos); |
804 | } | 793 | } |
805 | connect_success_continuation (h); | 794 | connect_success_continuation (h); |
806 | } | 795 | } |
807 | 796 | ||
@@ -823,12 +812,12 @@ try_connect_using_address (void *cls, | |||
823 | struct GNUNET_TIME_Relative delay; | 812 | struct GNUNET_TIME_Relative delay; |
824 | 813 | ||
825 | if (addr == NULL) | 814 | if (addr == NULL) |
826 | { | 815 | { |
827 | h->dns_active = NULL; | 816 | h->dns_active = NULL; |
828 | if (NULL == h->ap_head) | 817 | if (NULL == h->ap_head) |
829 | connect_fail_continuation (h); | 818 | connect_fail_continuation (h); |
830 | return; | 819 | return; |
831 | } | 820 | } |
832 | if (h->sock != NULL) | 821 | if (h->sock != NULL) |
833 | return; /* already connected */ | 822 | return; /* already connected */ |
834 | GNUNET_assert (h->addr == NULL); | 823 | GNUNET_assert (h->addr == NULL); |
@@ -845,25 +834,24 @@ try_connect_using_address (void *cls, | |||
845 | ap->h = h; | 834 | ap->h = h; |
846 | 835 | ||
847 | switch (ap->addr->sa_family) | 836 | switch (ap->addr->sa_family) |
848 | { | 837 | { |
849 | case AF_INET: | 838 | case AF_INET: |
850 | ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port); | 839 | ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port); |
851 | break; | 840 | break; |
852 | case AF_INET6: | 841 | case AF_INET6: |
853 | ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port); | 842 | ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port); |
854 | break; | 843 | break; |
855 | default: | 844 | default: |
856 | GNUNET_break (0); | 845 | GNUNET_break (0); |
857 | GNUNET_free (ap); | 846 | GNUNET_free (ap); |
858 | return; /* not supported by us */ | 847 | return; /* not supported by us */ |
859 | } | 848 | } |
860 | ap->sock = | 849 | ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0); |
861 | GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0); | ||
862 | if (ap->sock == NULL) | 850 | if (ap->sock == NULL) |
863 | { | 851 | { |
864 | GNUNET_free (ap); | 852 | GNUNET_free (ap); |
865 | return; /* not supported by OS */ | 853 | return; /* not supported by OS */ |
866 | } | 854 | } |
867 | #if DEBUG_CONNECTION | 855 | #if DEBUG_CONNECTION |
868 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 856 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
869 | _("Trying to connect to `%s' (%p)\n"), | 857 | _("Trying to connect to `%s' (%p)\n"), |
@@ -873,13 +861,13 @@ try_connect_using_address (void *cls, | |||
873 | ap->addr, | 861 | ap->addr, |
874 | ap->addrlen)) && | 862 | ap->addrlen)) && |
875 | (errno != EINPROGRESS)) | 863 | (errno != EINPROGRESS)) |
876 | { | 864 | { |
877 | /* maybe refused / unsupported address, try next */ | 865 | /* maybe refused / unsupported address, try next */ |
878 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); | 866 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); |
879 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); | 867 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); |
880 | GNUNET_free (ap); | 868 | GNUNET_free (ap); |
881 | return; | 869 | return; |
882 | } | 870 | } |
883 | GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap); | 871 | GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap); |
884 | delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; | 872 | delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; |
885 | if (h->nth.notify_ready != NULL) | 873 | if (h->nth.notify_ready != NULL) |
@@ -891,8 +879,8 @@ try_connect_using_address (void *cls, | |||
891 | GNUNET_TIME_absolute_get_remaining | 879 | GNUNET_TIME_absolute_get_remaining |
892 | (h->receive_timeout)); | 880 | (h->receive_timeout)); |
893 | ap->task = | 881 | ap->task = |
894 | GNUNET_SCHEDULER_add_write_net (delay, ap->sock, | 882 | GNUNET_SCHEDULER_add_write_net (delay, ap->sock, |
895 | &connect_probe_continuation, ap); | 883 | &connect_probe_continuation, ap); |
896 | } | 884 | } |
897 | 885 | ||
898 | 886 | ||
@@ -917,7 +905,7 @@ GNUNET_CONNECTION_create_from_connect (const struct | |||
917 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 905 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
918 | ret->cfg = cfg; | 906 | ret->cfg = cfg; |
919 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 907 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
920 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); | 908 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); |
921 | ret->port = port; | 909 | ret->port = port; |
922 | ret->hostname = GNUNET_strdup (hostname); | 910 | ret->hostname = GNUNET_strdup (hostname); |
923 | ret->dns_active = GNUNET_RESOLVER_ip_get (ret->hostname, | 911 | ret->dns_active = GNUNET_RESOLVER_ip_get (ret->hostname, |
@@ -939,8 +927,8 @@ GNUNET_CONNECTION_create_from_connect (const struct | |||
939 | */ | 927 | */ |
940 | struct GNUNET_CONNECTION_Handle * | 928 | struct GNUNET_CONNECTION_Handle * |
941 | GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | 929 | GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct |
942 | GNUNET_CONFIGURATION_Handle *cfg, | 930 | GNUNET_CONFIGURATION_Handle |
943 | const char *unixpath) | 931 | *cfg, const char *unixpath) |
944 | { | 932 | { |
945 | #ifdef AF_UNIX | 933 | #ifdef AF_UNIX |
946 | struct GNUNET_CONNECTION_Handle *ret; | 934 | struct GNUNET_CONNECTION_Handle *ret; |
@@ -953,9 +941,7 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | |||
953 | slen = strlen (unixpath); | 941 | slen = strlen (unixpath); |
954 | if (slen >= sizeof (un->sun_path)) | 942 | if (slen >= sizeof (un->sun_path)) |
955 | slen = sizeof (un->sun_path) - 1; | 943 | slen = sizeof (un->sun_path) - 1; |
956 | memcpy (un->sun_path, | 944 | memcpy (un->sun_path, unixpath, slen); |
957 | unixpath, | ||
958 | slen); | ||
959 | un->sun_path[slen] = '\0'; | 945 | un->sun_path[slen] = '\0'; |
960 | slen = sizeof (struct sockaddr_un); | 946 | slen = sizeof (struct sockaddr_un); |
961 | #if HAVE_SOCKADDR_IN_SIN_LEN | 947 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -967,28 +953,27 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | |||
967 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); | 953 | ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); |
968 | ret->cfg = cfg; | 954 | ret->cfg = cfg; |
969 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; | 955 | ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; |
970 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); | 956 | ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); |
971 | ret->port = 0; | 957 | ret->port = 0; |
972 | ret->hostname = NULL; | 958 | ret->hostname = NULL; |
973 | ret->addr = (struct sockaddr*) un; | 959 | ret->addr = (struct sockaddr *) un; |
974 | ret->addrlen = slen; | 960 | ret->addrlen = slen; |
975 | ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | 961 | ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); |
976 | if (NULL == ret->sock) | 962 | if (NULL == ret->sock) |
977 | { | 963 | { |
978 | GNUNET_free (ret->addr); | 964 | GNUNET_free (ret->addr); |
979 | GNUNET_free (ret->write_buffer); | 965 | GNUNET_free (ret->write_buffer); |
980 | GNUNET_free (ret); | 966 | GNUNET_free (ret); |
981 | return NULL; | 967 | return NULL; |
982 | } | 968 | } |
983 | if (GNUNET_OK != GNUNET_NETWORK_socket_connect (ret->sock, | 969 | if (GNUNET_OK != GNUNET_NETWORK_socket_connect (ret->sock, |
984 | ret->addr, | 970 | ret->addr, ret->addrlen)) |
985 | ret->addrlen)) | 971 | { |
986 | { | 972 | /* Just return; we expect everything to work eventually so don't fail HARD */ |
987 | /* Just return; we expect everything to work eventually so don't fail HARD */ | 973 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock)); |
988 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock)); | 974 | ret->sock = NULL; |
989 | ret->sock = NULL; | 975 | return ret; |
990 | return ret; | 976 | } |
991 | } | ||
992 | connect_success_continuation (ret); | 977 | connect_success_continuation (ret); |
993 | return ret; | 978 | return ret; |
994 | #else | 979 | #else |
@@ -1018,22 +1003,22 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, | |||
1018 | 1003 | ||
1019 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); | 1004 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); |
1020 | if (s == NULL) | 1005 | if (s == NULL) |
1021 | { | 1006 | { |
1022 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING | | 1007 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING | |
1023 | GNUNET_ERROR_TYPE_BULK, "socket"); | 1008 | GNUNET_ERROR_TYPE_BULK, "socket"); |
1024 | return NULL; | 1009 | return NULL; |
1025 | } | 1010 | } |
1026 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) | 1011 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) |
1027 | && (errno != EINPROGRESS)) | 1012 | && (errno != EINPROGRESS)) |
1028 | { | 1013 | { |
1029 | /* maybe refused / unsupported address, try next */ | 1014 | /* maybe refused / unsupported address, try next */ |
1030 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); | 1015 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect"); |
1031 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1016 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1032 | _("Attempt to connect to `%s' failed\n"), | 1017 | _("Attempt to connect to `%s' failed\n"), |
1033 | GNUNET_a2s (serv_addr, addrlen)); | 1018 | GNUNET_a2s (serv_addr, addrlen)); |
1034 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); | 1019 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); |
1035 | return NULL; | 1020 | return NULL; |
1036 | } | 1021 | } |
1037 | ret = GNUNET_CONNECTION_create_from_existing (s); | 1022 | ret = GNUNET_CONNECTION_create_from_existing (s); |
1038 | ret->addr = GNUNET_malloc (addrlen); | 1023 | ret->addr = GNUNET_malloc (addrlen); |
1039 | memcpy (ret->addr, serv_addr, addrlen); | 1024 | memcpy (ret->addr, serv_addr, addrlen); |
@@ -1079,27 +1064,26 @@ GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock) | |||
1079 | */ | 1064 | */ |
1080 | void | 1065 | void |
1081 | GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, | 1066 | GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, |
1082 | int finish_pending_write) | 1067 | int finish_pending_write) |
1083 | { | 1068 | { |
1084 | if (GNUNET_NO == finish_pending_write) | 1069 | if (GNUNET_NO == finish_pending_write) |
1070 | { | ||
1071 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | ||
1085 | { | 1072 | { |
1086 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 1073 | GNUNET_SCHEDULER_cancel (sock->write_task); |
1087 | { | 1074 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; |
1088 | GNUNET_SCHEDULER_cancel (sock->write_task); | 1075 | sock->write_buffer_off = 0; |
1089 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1090 | sock->write_buffer_off = 0; | ||
1091 | } | ||
1092 | sock->nth.notify_ready = NULL; | ||
1093 | } | 1076 | } |
1077 | sock->nth.notify_ready = NULL; | ||
1078 | } | ||
1094 | if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL)) | 1079 | if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL)) |
1095 | { | 1080 | { |
1096 | GNUNET_RESOLVER_request_cancel (sock->dns_active); | 1081 | GNUNET_RESOLVER_request_cancel (sock->dns_active); |
1097 | sock->dns_active = NULL; | 1082 | sock->dns_active = NULL; |
1098 | } | 1083 | } |
1099 | 1084 | ||
1100 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); | 1085 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); |
1101 | sock->destroy_task | 1086 | sock->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock); |
1102 | = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock); | ||
1103 | } | 1087 | } |
1104 | 1088 | ||
1105 | 1089 | ||
@@ -1128,6 +1112,7 @@ static void | |||
1128 | signal_error (struct GNUNET_CONNECTION_Handle *sh, int errcode) | 1112 | signal_error (struct GNUNET_CONNECTION_Handle *sh, int errcode) |
1129 | { | 1113 | { |
1130 | GNUNET_CONNECTION_Receiver receiver; | 1114 | GNUNET_CONNECTION_Receiver receiver; |
1115 | |||
1131 | GNUNET_assert (NULL != (receiver = sh->receiver)); | 1116 | GNUNET_assert (NULL != (receiver = sh->receiver)); |
1132 | sh->receiver = NULL; | 1117 | sh->receiver = NULL; |
1133 | receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode); | 1118 | receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode); |
@@ -1148,60 +1133,60 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1148 | GNUNET_CONNECTION_Receiver receiver; | 1133 | GNUNET_CONNECTION_Receiver receiver; |
1149 | 1134 | ||
1150 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; | 1135 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; |
1151 | if ( (GNUNET_YES == sh->ignore_shutdown) && | 1136 | if ((GNUNET_YES == sh->ignore_shutdown) && |
1152 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1137 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1153 | { | 1138 | { |
1154 | /* ignore shutdown request, go again immediately */ | 1139 | /* ignore shutdown request, go again immediately */ |
1155 | #if DEBUG_CONNECTION | 1140 | #if DEBUG_CONNECTION |
1156 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1157 | "Ignoring shutdown signal per configuration\n"); | 1142 | "Ignoring shutdown signal per configuration\n"); |
1158 | #endif | 1143 | #endif |
1159 | sh->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining | 1144 | sh->read_task = |
1160 | (sh->receive_timeout), | 1145 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining |
1161 | sh->sock, | 1146 | (sh->receive_timeout), sh->sock, |
1162 | &receive_ready, sh); | 1147 | &receive_ready, sh); |
1163 | return; | 1148 | return; |
1164 | } | 1149 | } |
1165 | now = GNUNET_TIME_absolute_get (); | 1150 | now = GNUNET_TIME_absolute_get (); |
1166 | if ((now.abs_value > sh->receive_timeout.abs_value) || | 1151 | if ((now.abs_value > sh->receive_timeout.abs_value) || |
1167 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) || | 1152 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) || |
1168 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1153 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1169 | { | 1154 | { |
1170 | #if DEBUG_CONNECTION | 1155 | #if DEBUG_CONNECTION |
1171 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 1156 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
1172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1173 | "Receive from `%s' encounters error: time out by %llums... (%p)\n", | 1158 | "Receive from `%s' encounters error: time out by %llums... (%p)\n", |
1174 | GNUNET_a2s (sh->addr, sh->addrlen), | 1159 | GNUNET_a2s (sh->addr, sh->addrlen), |
1175 | GNUNET_TIME_absolute_get_duration (sh->receive_timeout). | 1160 | GNUNET_TIME_absolute_get_duration (sh->receive_timeout). |
1176 | rel_value, sh); | 1161 | rel_value, sh); |
1177 | #endif | 1162 | #endif |
1178 | signal_timeout (sh); | 1163 | signal_timeout (sh); |
1179 | return; | 1164 | return; |
1180 | } | 1165 | } |
1181 | if (sh->sock == NULL) | 1166 | if (sh->sock == NULL) |
1182 | { | 1167 | { |
1183 | /* connect failed for good */ | 1168 | /* connect failed for good */ |
1184 | #if DEBUG_CONNECTION | 1169 | #if DEBUG_CONNECTION |
1185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1170 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1186 | "Receive encounters error, socket closed... (%p)\n", sh); | 1171 | "Receive encounters error, socket closed... (%p)\n", sh); |
1187 | #endif | 1172 | #endif |
1188 | signal_error (sh, ECONNREFUSED); | 1173 | signal_error (sh, ECONNREFUSED); |
1189 | return; | 1174 | return; |
1190 | } | 1175 | } |
1191 | GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock)); | 1176 | GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock)); |
1192 | RETRY: | 1177 | RETRY: |
1193 | ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max); | 1178 | ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max); |
1194 | if (ret == -1) | 1179 | if (ret == -1) |
1195 | { | 1180 | { |
1196 | if (errno == EINTR) | 1181 | if (errno == EINTR) |
1197 | goto RETRY; | 1182 | goto RETRY; |
1198 | #if DEBUG_CONNECTION | 1183 | #if DEBUG_CONNECTION |
1199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1184 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1200 | "Error receiving: %s\n", STRERROR (errno)); | 1185 | "Error receiving: %s\n", STRERROR (errno)); |
1201 | #endif | 1186 | #endif |
1202 | signal_error (sh, errno); | 1187 | signal_error (sh, errno); |
1203 | return; | 1188 | return; |
1204 | } | 1189 | } |
1205 | #if DEBUG_CONNECTION | 1190 | #if DEBUG_CONNECTION |
1206 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1207 | "receive_ready read %u/%u bytes from `%s' (%p)!\n", | 1192 | "receive_ready read %u/%u bytes from `%s' (%p)!\n", |
@@ -1232,32 +1217,32 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1232 | 1217 | ||
1233 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; | 1218 | sh->read_task = GNUNET_SCHEDULER_NO_TASK; |
1234 | if (sh->sock == NULL) | 1219 | if (sh->sock == NULL) |
1235 | { | 1220 | { |
1236 | /* not connected and no longer trying */ | 1221 | /* not connected and no longer trying */ |
1237 | #if DEBUG_CONNECTION | 1222 | #if DEBUG_CONNECTION |
1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1223 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1239 | "Receive encounters error, socket closed (%p)...\n", sh); | 1224 | "Receive encounters error, socket closed (%p)...\n", sh); |
1240 | #endif | 1225 | #endif |
1241 | signal_error (sh, ECONNREFUSED); | 1226 | signal_error (sh, ECONNREFUSED); |
1242 | return; | 1227 | return; |
1243 | } | 1228 | } |
1244 | now = GNUNET_TIME_absolute_get (); | 1229 | now = GNUNET_TIME_absolute_get (); |
1245 | if ((now.abs_value > sh->receive_timeout.abs_value) || | 1230 | if ((now.abs_value > sh->receive_timeout.abs_value) || |
1246 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) | 1231 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) |
1247 | { | 1232 | { |
1248 | #if DEBUG_CONNECTION | 1233 | #if DEBUG_CONNECTION |
1249 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1234 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1250 | "Receive encounters error: time out (%p)...\n", sh); | 1235 | "Receive encounters error: time out (%p)...\n", sh); |
1251 | #endif | 1236 | #endif |
1252 | signal_timeout (sh); | 1237 | signal_timeout (sh); |
1253 | return; | 1238 | return; |
1254 | } | 1239 | } |
1255 | GNUNET_assert (sh->sock != NULL); | 1240 | GNUNET_assert (sh->sock != NULL); |
1256 | /* connect succeeded, wait for data! */ | 1241 | /* connect succeeded, wait for data! */ |
1257 | sh->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining | 1242 | sh->read_task = |
1258 | (sh->receive_timeout), | 1243 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining |
1259 | sh->sock, | 1244 | (sh->receive_timeout), sh->sock, |
1260 | &receive_ready, sh); | 1245 | &receive_ready, sh); |
1261 | } | 1246 | } |
1262 | 1247 | ||
1263 | 1248 | ||
@@ -1291,17 +1276,17 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, | |||
1291 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); | 1276 | sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); |
1292 | sock->max = max; | 1277 | sock->max = max; |
1293 | if (sock->sock != NULL) | 1278 | if (sock->sock != NULL) |
1294 | { | 1279 | { |
1295 | memset (&tc, 0, sizeof (tc)); | 1280 | memset (&tc, 0, sizeof (tc)); |
1296 | tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE; | 1281 | tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE; |
1297 | receive_again (sock, &tc); | 1282 | receive_again (sock, &tc); |
1298 | return; | 1283 | return; |
1299 | } | 1284 | } |
1300 | if ((sock->dns_active == NULL) && (sock->ap_head == NULL)) | 1285 | if ((sock->dns_active == NULL) && (sock->ap_head == NULL)) |
1301 | { | 1286 | { |
1302 | receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT); | 1287 | receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT); |
1303 | return; | 1288 | return; |
1304 | } | 1289 | } |
1305 | sock->ccs += COCO_RECEIVE_AGAIN; | 1290 | sock->ccs += COCO_RECEIVE_AGAIN; |
1306 | } | 1291 | } |
1307 | 1292 | ||
@@ -1314,7 +1299,7 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, | |||
1314 | */ | 1299 | */ |
1315 | void | 1300 | void |
1316 | GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, | 1301 | GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, |
1317 | int do_ignore) | 1302 | int do_ignore) |
1318 | { | 1303 | { |
1319 | sock->ignore_shutdown = do_ignore; | 1304 | sock->ignore_shutdown = do_ignore; |
1320 | } | 1305 | } |
@@ -1332,15 +1317,15 @@ void * | |||
1332 | GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) | 1317 | GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) |
1333 | { | 1318 | { |
1334 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | 1319 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) |
1335 | { | 1320 | { |
1336 | GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task)); | 1321 | GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task)); |
1337 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; | 1322 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; |
1338 | } | 1323 | } |
1339 | else | 1324 | else |
1340 | { | 1325 | { |
1341 | GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN)); | 1326 | GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN)); |
1342 | sock->ccs -= COCO_RECEIVE_AGAIN; | 1327 | sock->ccs -= COCO_RECEIVE_AGAIN; |
1343 | } | 1328 | } |
1344 | sock->receiver = NULL; | 1329 | sock->receiver = NULL; |
1345 | return sock->receiver_cls; | 1330 | return sock->receiver_cls; |
1346 | } | 1331 | } |
@@ -1371,18 +1356,17 @@ process_notify (struct GNUNET_CONNECTION_Handle *sock) | |||
1371 | return GNUNET_NO; | 1356 | return GNUNET_NO; |
1372 | sock->nth.notify_ready = NULL; | 1357 | sock->nth.notify_ready = NULL; |
1373 | if (sock->write_buffer_size - sock->write_buffer_off < size) | 1358 | if (sock->write_buffer_size - sock->write_buffer_off < size) |
1374 | { | 1359 | { |
1375 | /* need to compact */ | 1360 | /* need to compact */ |
1376 | memmove (sock->write_buffer, | 1361 | memmove (sock->write_buffer, |
1377 | &sock->write_buffer[sock->write_buffer_pos], used); | 1362 | &sock->write_buffer[sock->write_buffer_pos], used); |
1378 | sock->write_buffer_off -= sock->write_buffer_pos; | 1363 | sock->write_buffer_off -= sock->write_buffer_pos; |
1379 | sock->write_buffer_pos = 0; | 1364 | sock->write_buffer_pos = 0; |
1380 | } | 1365 | } |
1381 | avail = sock->write_buffer_size - sock->write_buffer_off; | 1366 | avail = sock->write_buffer_size - sock->write_buffer_off; |
1382 | GNUNET_assert (avail >= size); | 1367 | GNUNET_assert (avail >= size); |
1383 | size = notify (sock->nth.notify_ready_cls, | 1368 | size = notify (sock->nth.notify_ready_cls, |
1384 | avail, | 1369 | avail, &sock->write_buffer[sock->write_buffer_off]); |
1385 | &sock->write_buffer[sock->write_buffer_off]); | ||
1386 | GNUNET_assert (size <= avail); | 1370 | GNUNET_assert (size <= avail); |
1387 | sock->write_buffer_off += size; | 1371 | sock->write_buffer_off += size; |
1388 | return GNUNET_YES; | 1372 | return GNUNET_YES; |
@@ -1401,15 +1385,13 @@ process_notify (struct GNUNET_CONNECTION_Handle *sock) | |||
1401 | * @param tc scheduler context | 1385 | * @param tc scheduler context |
1402 | */ | 1386 | */ |
1403 | static void | 1387 | static void |
1404 | transmit_timeout (void *cls, | 1388 | transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1405 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1406 | { | 1389 | { |
1407 | struct GNUNET_CONNECTION_Handle *sock = cls; | 1390 | struct GNUNET_CONNECTION_Handle *sock = cls; |
1408 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 1391 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
1409 | 1392 | ||
1410 | #if DEBUG_CONNECTION | 1393 | #if DEBUG_CONNECTION |
1411 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1394 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "transmit_timeout running (%p)\n", sock); |
1412 | "transmit_timeout running (%p)\n", sock); | ||
1413 | #endif | 1395 | #endif |
1414 | sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1396 | sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1415 | #if DEBUG_CONNECTION | 1397 | #if DEBUG_CONNECTION |
@@ -1436,8 +1418,7 @@ transmit_timeout (void *cls, | |||
1436 | * @param tc scheduler context | 1418 | * @param tc scheduler context |
1437 | */ | 1419 | */ |
1438 | static void | 1420 | static void |
1439 | connect_error (void *cls, | 1421 | connect_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1440 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1441 | { | 1422 | { |
1442 | struct GNUNET_CONNECTION_Handle *sock = cls; | 1423 | struct GNUNET_CONNECTION_Handle *sock = cls; |
1443 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 1424 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
@@ -1445,10 +1426,7 @@ connect_error (void *cls, | |||
1445 | #if DEBUG_CONNECTION | 1426 | #if DEBUG_CONNECTION |
1446 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1447 | "Transmission request of size %u fails (%s/%u), connection failed (%p).\n", | 1428 | "Transmission request of size %u fails (%s/%u), connection failed (%p).\n", |
1448 | sock->nth.notify_size, | 1429 | sock->nth.notify_size, sock->hostname, sock->port, sock); |
1449 | sock->hostname, | ||
1450 | sock->port, | ||
1451 | sock); | ||
1452 | #endif | 1430 | #endif |
1453 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; | 1431 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; |
1454 | notify = sock->nth.notify_ready; | 1432 | notify = sock->nth.notify_ready; |
@@ -1468,19 +1446,18 @@ transmit_error (struct GNUNET_CONNECTION_Handle *sock) | |||
1468 | GNUNET_CONNECTION_TransmitReadyNotify notify; | 1446 | GNUNET_CONNECTION_TransmitReadyNotify notify; |
1469 | 1447 | ||
1470 | if (NULL != sock->sock) | 1448 | if (NULL != sock->sock) |
1471 | { | 1449 | { |
1472 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); | 1450 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); |
1473 | GNUNET_break (GNUNET_OK == | 1451 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); |
1474 | GNUNET_NETWORK_socket_close (sock->sock)); | 1452 | sock->sock = NULL; |
1475 | sock->sock = NULL; | 1453 | } |
1476 | } | ||
1477 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | 1454 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) |
1478 | { | 1455 | { |
1479 | GNUNET_SCHEDULER_cancel (sock->read_task); | 1456 | GNUNET_SCHEDULER_cancel (sock->read_task); |
1480 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; | 1457 | sock->read_task = GNUNET_SCHEDULER_NO_TASK; |
1481 | signal_timeout (sock); | 1458 | signal_timeout (sock); |
1482 | return; | 1459 | return; |
1483 | } | 1460 | } |
1484 | if (sock->nth.notify_ready == NULL) | 1461 | if (sock->nth.notify_ready == NULL) |
1485 | return; /* nobody to tell about it */ | 1462 | return; /* nobody to tell about it */ |
1486 | notify = sock->nth.notify_ready; | 1463 | notify = sock->nth.notify_ready; |
@@ -1506,102 +1483,99 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1506 | size_t have; | 1483 | size_t have; |
1507 | 1484 | ||
1508 | #if DEBUG_CONNECTION | 1485 | #if DEBUG_CONNECTION |
1509 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", sock); |
1510 | "transmit_ready running (%p).\n", sock); | ||
1511 | #endif | 1487 | #endif |
1512 | GNUNET_assert (sock->write_task != GNUNET_SCHEDULER_NO_TASK); | 1488 | GNUNET_assert (sock->write_task != GNUNET_SCHEDULER_NO_TASK); |
1513 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; | 1489 | sock->write_task = GNUNET_SCHEDULER_NO_TASK; |
1514 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); | 1490 | GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); |
1515 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 1491 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
1516 | { | 1492 | { |
1517 | if (sock->ignore_shutdown == GNUNET_YES) | 1493 | if (sock->ignore_shutdown == GNUNET_YES) |
1518 | goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */ | 1494 | goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */ |
1519 | #if DEBUG_CONNECTION | 1495 | #if DEBUG_CONNECTION |
1520 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1521 | "Transmit to `%s' fails, shutdown happened (%p).\n", | 1497 | "Transmit to `%s' fails, shutdown happened (%p).\n", |
1522 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | 1498 | GNUNET_a2s (sock->addr, sock->addrlen), sock); |
1523 | #endif | 1499 | #endif |
1524 | notify = sock->nth.notify_ready; | 1500 | notify = sock->nth.notify_ready; |
1525 | if (NULL != notify) | 1501 | if (NULL != notify) |
1526 | { | ||
1527 | sock->nth.notify_ready = NULL; | ||
1528 | notify (sock->nth.notify_ready_cls, 0, NULL); | ||
1529 | } | ||
1530 | return; | ||
1531 | } | ||
1532 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | ||
1533 | { | 1502 | { |
1534 | #if DEBUG_CONNECTION | ||
1535 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1536 | "Transmit to `%s' fails, time out reached (%p).\n", | ||
1537 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | ||
1538 | #endif | ||
1539 | notify = sock->nth.notify_ready; | ||
1540 | GNUNET_assert (NULL != notify); | ||
1541 | sock->nth.notify_ready = NULL; | 1503 | sock->nth.notify_ready = NULL; |
1542 | notify (sock->nth.notify_ready_cls, 0, NULL); | 1504 | notify (sock->nth.notify_ready_cls, 0, NULL); |
1543 | return; | ||
1544 | } | 1505 | } |
1506 | return; | ||
1507 | } | ||
1508 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | ||
1509 | { | ||
1510 | #if DEBUG_CONNECTION | ||
1511 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1512 | "Transmit to `%s' fails, time out reached (%p).\n", | ||
1513 | GNUNET_a2s (sock->addr, sock->addrlen), sock); | ||
1514 | #endif | ||
1515 | notify = sock->nth.notify_ready; | ||
1516 | GNUNET_assert (NULL != notify); | ||
1517 | sock->nth.notify_ready = NULL; | ||
1518 | notify (sock->nth.notify_ready_cls, 0, NULL); | ||
1519 | return; | ||
1520 | } | ||
1545 | GNUNET_assert (NULL != sock->sock); | 1521 | GNUNET_assert (NULL != sock->sock); |
1546 | if (tc->write_ready == NULL) | 1522 | if (tc->write_ready == NULL) |
1547 | { | 1523 | { |
1548 | /* special circumstances (in particular, | 1524 | /* special circumstances (in particular, |
1549 | PREREQ_DONE after connect): not yet ready to write, | 1525 | * PREREQ_DONE after connect): not yet ready to write, |
1550 | but no "fatal" error either. Hence retry. */ | 1526 | * but no "fatal" error either. Hence retry. */ |
1551 | goto SCHEDULE_WRITE; | 1527 | goto SCHEDULE_WRITE; |
1552 | } | 1528 | } |
1553 | if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)) | 1529 | if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)) |
1554 | { | 1530 | { |
1555 | #if DEBUG_CONNECTION | 1531 | #if DEBUG_CONNECTION |
1556 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1532 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1557 | _ | 1533 | _ |
1558 | ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"), | 1534 | ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"), |
1559 | sock); | 1535 | sock); |
1560 | #endif | 1536 | #endif |
1561 | transmit_error (sock); | 1537 | transmit_error (sock); |
1562 | return; /* connect failed for good, we're finished */ | 1538 | return; /* connect failed for good, we're finished */ |
1563 | } | 1539 | } |
1564 | GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos); | 1540 | GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos); |
1565 | if ( (sock->nth.notify_ready != NULL) && | 1541 | if ((sock->nth.notify_ready != NULL) && |
1566 | (sock->write_buffer_size < sock->nth.notify_size) ) | 1542 | (sock->write_buffer_size < sock->nth.notify_size)) |
1567 | { | 1543 | { |
1568 | sock->write_buffer = GNUNET_realloc(sock->write_buffer, | 1544 | sock->write_buffer = GNUNET_realloc (sock->write_buffer, |
1569 | sock->nth.notify_size); | 1545 | sock->nth.notify_size); |
1570 | sock->write_buffer_size = sock->nth.notify_size; | 1546 | sock->write_buffer_size = sock->nth.notify_size; |
1571 | } | 1547 | } |
1572 | process_notify (sock); | 1548 | process_notify (sock); |
1573 | have = sock->write_buffer_off - sock->write_buffer_pos; | 1549 | have = sock->write_buffer_off - sock->write_buffer_pos; |
1574 | if (have == 0) | 1550 | if (have == 0) |
1575 | { | 1551 | { |
1576 | /* no data ready for writing, terminate write loop */ | 1552 | /* no data ready for writing, terminate write loop */ |
1577 | return; | 1553 | return; |
1578 | } | 1554 | } |
1579 | GNUNET_assert (have <= sock->write_buffer_size); | 1555 | GNUNET_assert (have <= sock->write_buffer_size); |
1580 | GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size); | 1556 | GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size); |
1581 | GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); | 1557 | GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); |
1582 | RETRY: | 1558 | RETRY: |
1583 | ret = GNUNET_NETWORK_socket_send (sock->sock, | 1559 | ret = GNUNET_NETWORK_socket_send (sock->sock, |
1584 | &sock->write_buffer[sock-> | 1560 | &sock->write_buffer[sock->write_buffer_pos], |
1585 | write_buffer_pos], | ||
1586 | have); | 1561 | have); |
1587 | if (ret == -1) | 1562 | if (ret == -1) |
1588 | { | 1563 | { |
1589 | if (errno == EINTR) | 1564 | if (errno == EINTR) |
1590 | goto RETRY; | 1565 | goto RETRY; |
1591 | #if 0 | 1566 | #if 0 |
1592 | int en = errno; | 1567 | int en = errno; |
1593 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1568 | |
1594 | _("Failed to send to `%s': %s\n"), | 1569 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1595 | GNUNET_a2s (sock->addr, | 1570 | _("Failed to send to `%s': %s\n"), |
1596 | sock->addrlen), | 1571 | GNUNET_a2s (sock->addr, sock->addrlen), STRERROR (en)); |
1597 | STRERROR (en)); | ||
1598 | #endif | 1572 | #endif |
1599 | #if DEBUG_CONNECTION | 1573 | #if DEBUG_CONNECTION |
1600 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); | 1574 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); |
1601 | #endif | 1575 | #endif |
1602 | transmit_error (sock); | 1576 | transmit_error (sock); |
1603 | return; | 1577 | return; |
1604 | } | 1578 | } |
1605 | #if DEBUG_CONNECTION | 1579 | #if DEBUG_CONNECTION |
1606 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1580 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1607 | "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n", | 1581 | "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n", |
@@ -1610,11 +1584,11 @@ RETRY: | |||
1610 | #endif | 1584 | #endif |
1611 | sock->write_buffer_pos += ret; | 1585 | sock->write_buffer_pos += ret; |
1612 | if (sock->write_buffer_pos == sock->write_buffer_off) | 1586 | if (sock->write_buffer_pos == sock->write_buffer_off) |
1613 | { | 1587 | { |
1614 | /* transmitted all pending data */ | 1588 | /* transmitted all pending data */ |
1615 | sock->write_buffer_pos = 0; | 1589 | sock->write_buffer_pos = 0; |
1616 | sock->write_buffer_off = 0; | 1590 | sock->write_buffer_off = 0; |
1617 | } | 1591 | } |
1618 | if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready)) | 1592 | if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready)) |
1619 | return; /* all data sent! */ | 1593 | return; /* all data sent! */ |
1620 | /* not done writing, schedule more */ | 1594 | /* not done writing, schedule more */ |
@@ -1624,14 +1598,15 @@ SCHEDULE_WRITE: | |||
1624 | "Re-scheduling transmit_ready (more to do) (%p).\n", sock); | 1598 | "Re-scheduling transmit_ready (more to do) (%p).\n", sock); |
1625 | #endif | 1599 | #endif |
1626 | have = sock->write_buffer_off - sock->write_buffer_pos; | 1600 | have = sock->write_buffer_off - sock->write_buffer_pos; |
1627 | GNUNET_assert ( (sock->nth.notify_ready != NULL) || (have > 0) ); | 1601 | GNUNET_assert ((sock->nth.notify_ready != NULL) || (have > 0)); |
1628 | if (sock->write_task == GNUNET_SCHEDULER_NO_TASK) | 1602 | if (sock->write_task == GNUNET_SCHEDULER_NO_TASK) |
1629 | sock->write_task = | 1603 | sock->write_task = |
1630 | GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == NULL) | 1604 | GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == NULL) |
1631 | ? GNUNET_TIME_UNIT_FOREVER_REL | 1605 | ? GNUNET_TIME_UNIT_FOREVER_REL |
1632 | : GNUNET_TIME_absolute_get_remaining (sock->nth.transmit_timeout), | 1606 | : |
1633 | sock->sock, | 1607 | GNUNET_TIME_absolute_get_remaining |
1634 | &transmit_ready, sock); | 1608 | (sock->nth.transmit_timeout), |
1609 | sock->sock, &transmit_ready, sock); | ||
1635 | } | 1610 | } |
1636 | 1611 | ||
1637 | 1612 | ||
@@ -1657,10 +1632,10 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle | |||
1657 | notify, void *notify_cls) | 1632 | notify, void *notify_cls) |
1658 | { | 1633 | { |
1659 | if (sock->nth.notify_ready != NULL) | 1634 | if (sock->nth.notify_ready != NULL) |
1660 | { | 1635 | { |
1661 | GNUNET_assert (0); | 1636 | GNUNET_assert (0); |
1662 | return NULL; | 1637 | return NULL; |
1663 | } | 1638 | } |
1664 | GNUNET_assert (notify != NULL); | 1639 | GNUNET_assert (notify != NULL); |
1665 | GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1640 | GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1666 | GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size); | 1641 | GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size); |
@@ -1674,39 +1649,37 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle | |||
1674 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task); | 1649 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task); |
1675 | if ((sock->sock == NULL) && | 1650 | if ((sock->sock == NULL) && |
1676 | (sock->ap_head == NULL) && (sock->dns_active == NULL)) | 1651 | (sock->ap_head == NULL) && (sock->dns_active == NULL)) |
1677 | { | 1652 | { |
1678 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) | 1653 | if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) |
1679 | GNUNET_SCHEDULER_cancel (sock->write_task); | 1654 | GNUNET_SCHEDULER_cancel (sock->write_task); |
1680 | sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock); | 1655 | sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock); |
1681 | return &sock->nth; | 1656 | return &sock->nth; |
1682 | } | 1657 | } |
1683 | if (GNUNET_SCHEDULER_NO_TASK != sock->write_task) | 1658 | if (GNUNET_SCHEDULER_NO_TASK != sock->write_task) |
1684 | return &sock->nth; | 1659 | return &sock->nth; |
1685 | if (sock->sock != NULL) | 1660 | if (sock->sock != NULL) |
1686 | { | 1661 | { |
1687 | #if DEBUG_CONNECTION | 1662 | #if DEBUG_CONNECTION |
1688 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1689 | "Scheduling transmit_ready (%p).\n", sock); | 1664 | "Scheduling transmit_ready (%p).\n", sock); |
1690 | #endif | 1665 | #endif |
1691 | sock->write_task = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining | 1666 | sock->write_task = |
1692 | (sock->nth. | 1667 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining |
1693 | transmit_timeout), | 1668 | (sock->nth.transmit_timeout), |
1694 | sock->sock, | 1669 | sock->sock, &transmit_ready, sock); |
1695 | &transmit_ready, | 1670 | } |
1696 | sock); | ||
1697 | } | ||
1698 | else | 1671 | else |
1699 | { | 1672 | { |
1700 | #if DEBUG_CONNECTION | 1673 | #if DEBUG_CONNECTION |
1701 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1674 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1702 | "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", | 1675 | "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", |
1703 | sock); | 1676 | sock); |
1704 | #endif | 1677 | #endif |
1705 | sock->ccs |= COCO_TRANSMIT_READY; | 1678 | sock->ccs |= COCO_TRANSMIT_READY; |
1706 | sock->nth.timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, | 1679 | sock->nth.timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, |
1707 | &transmit_timeout, | 1680 | &transmit_timeout, |
1708 | sock); | 1681 | sock); |
1709 | } | 1682 | } |
1710 | return &sock->nth; | 1683 | return &sock->nth; |
1711 | } | 1684 | } |
1712 | 1685 | ||
@@ -1723,24 +1696,23 @@ GNUNET_CONNECTION_notify_transmit_ready_cancel (struct | |||
1723 | { | 1696 | { |
1724 | GNUNET_assert (h->notify_ready != NULL); | 1697 | GNUNET_assert (h->notify_ready != NULL); |
1725 | if (0 != (h->sh->ccs & COCO_TRANSMIT_READY)) | 1698 | if (0 != (h->sh->ccs & COCO_TRANSMIT_READY)) |
1726 | { | 1699 | { |
1727 | #if DEBUG_CONNECTION | 1700 | #if DEBUG_CONNECTION |
1728 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1701 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1729 | "notify_transmit_ready_cancel cancels timeout_task (%p)\n", | 1702 | "notify_transmit_ready_cancel cancels timeout_task (%p)\n", h); |
1730 | h); | ||
1731 | #endif | 1703 | #endif |
1732 | GNUNET_SCHEDULER_cancel (h->timeout_task); | 1704 | GNUNET_SCHEDULER_cancel (h->timeout_task); |
1733 | h->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1705 | h->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1734 | h->sh->ccs -= COCO_TRANSMIT_READY; | 1706 | h->sh->ccs -= COCO_TRANSMIT_READY; |
1735 | } | 1707 | } |
1736 | else | 1708 | else |
1709 | { | ||
1710 | if (h->sh->write_task != GNUNET_SCHEDULER_NO_TASK) | ||
1737 | { | 1711 | { |
1738 | if (h->sh->write_task != GNUNET_SCHEDULER_NO_TASK) | 1712 | GNUNET_SCHEDULER_cancel (h->sh->write_task); |
1739 | { | 1713 | h->sh->write_task = GNUNET_SCHEDULER_NO_TASK; |
1740 | GNUNET_SCHEDULER_cancel (h->sh->write_task); | ||
1741 | h->sh->write_task = GNUNET_SCHEDULER_NO_TASK; | ||
1742 | } | ||
1743 | } | 1714 | } |
1715 | } | ||
1744 | h->notify_ready = NULL; | 1716 | h->notify_ready = NULL; |
1745 | } | 1717 | } |
1746 | 1718 | ||