diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-02 10:50:27 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-02 10:50:27 +0000 |
commit | 45063a766d9a922d7f2b762ede305679e728cbfc (patch) | |
tree | f65310dc11769701f0f8ac3435835e189e8f559a /src/transport/plugin_transport_unix.c | |
parent | 9b49646d47d94a1538879a0533a3762c71c5590d (diff) | |
download | gnunet-45063a766d9a922d7f2b762ede305679e728cbfc.tar.gz gnunet-45063a766d9a922d7f2b762ede305679e728cbfc.zip |
- refactored sending code
Diffstat (limited to 'src/transport/plugin_transport_unix.c')
-rw-r--r-- | src/transport/plugin_transport_unix.c | 106 |
1 files changed, 81 insertions, 25 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index fa491dfcb..9c29aeb14 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c | |||
@@ -373,7 +373,7 @@ unix_real_send (void *cls, | |||
373 | size_t addrlen, GNUNET_TRANSPORT_TransmitContinuation cont, | 373 | size_t addrlen, GNUNET_TRANSPORT_TransmitContinuation cont, |
374 | void *cont_cls) | 374 | void *cont_cls) |
375 | { | 375 | { |
376 | 376 | struct Plugin *plugin = cls; | |
377 | ssize_t sent; | 377 | ssize_t sent; |
378 | const void *sb; | 378 | const void *sb; |
379 | size_t sbs; | 379 | size_t sbs; |
@@ -381,30 +381,31 @@ unix_real_send (void *cls, | |||
381 | size_t slen; | 381 | size_t slen; |
382 | int retry; | 382 | int retry; |
383 | 383 | ||
384 | GNUNET_assert (NULL != plugin); | ||
385 | |||
384 | if (send_handle == NULL) | 386 | if (send_handle == NULL) |
385 | { | 387 | { |
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 388 | /* We do not have a send handle */ |
387 | "unix_real_send with send_handle NULL!\n"); | 389 | GNUNET_break (0); |
388 | /* failed to open send socket for AF */ | ||
389 | if (cont != NULL) | 390 | if (cont != NULL) |
390 | cont (cont_cls, target, GNUNET_SYSERR); | 391 | cont (cont_cls, target, GNUNET_SYSERR); |
391 | return 0; | 392 | return -1; |
392 | } | 393 | } |
393 | if ((addr == NULL) || (addrlen == 0)) | 394 | if ((addr == NULL) || (addrlen == 0)) |
394 | { | 395 | { |
395 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 396 | /* Can never send if we don't have an address */ |
396 | "unix_real_send called without address, returning!\n"); | 397 | GNUNET_break (0); |
397 | if (cont != NULL) | 398 | if (cont != NULL) |
398 | cont (cont_cls, target, GNUNET_SYSERR); | 399 | cont (cont_cls, target, GNUNET_SYSERR); |
399 | return 0; /* Can never send if we don't have an address!! */ | 400 | return -1; |
400 | } | 401 | } |
401 | 402 | ||
403 | /* Prepare address */ | ||
402 | memset (&un, 0, sizeof (un)); | 404 | memset (&un, 0, sizeof (un)); |
403 | un.sun_family = AF_UNIX; | 405 | un.sun_family = AF_UNIX; |
404 | slen = strlen (addr) + 1; | 406 | slen = strlen (addr) + 1; |
405 | if (slen >= sizeof (un.sun_path)) | 407 | if (slen >= sizeof (un.sun_path)) |
406 | slen = sizeof (un.sun_path) - 1; | 408 | slen = sizeof (un.sun_path) - 1; |
407 | sent = 0; | ||
408 | GNUNET_assert (slen < sizeof (un.sun_path)); | 409 | GNUNET_assert (slen < sizeof (un.sun_path)); |
409 | memcpy (un.sun_path, addr, slen); | 410 | memcpy (un.sun_path, addr, slen); |
410 | un.sun_path[slen] = '\0'; | 411 | un.sun_path[slen] = '\0'; |
@@ -417,11 +418,17 @@ unix_real_send (void *cls, | |||
417 | #endif | 418 | #endif |
418 | sb = (struct sockaddr *) &un; | 419 | sb = (struct sockaddr *) &un; |
419 | sbs = slen; | 420 | sbs = slen; |
421 | |||
422 | /* Send the data */ | ||
423 | sent = 0; | ||
420 | retry = GNUNET_NO; | 424 | retry = GNUNET_NO; |
421 | sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs); | 425 | sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs); |
422 | 426 | ||
423 | if ((GNUNET_SYSERR == sent) && ((errno == EAGAIN) || (errno == ENOBUFS))) | 427 | if ((GNUNET_SYSERR == sent) && ((errno == EAGAIN) || (errno == ENOBUFS))) |
424 | retry = GNUNET_YES; | 428 | { |
429 | /* We have to retry later: retry */ | ||
430 | return 0; | ||
431 | } | ||
425 | 432 | ||
426 | if ((GNUNET_SYSERR == sent) && (errno == EMSGSIZE)) | 433 | if ((GNUNET_SYSERR == sent) && (errno == EMSGSIZE)) |
427 | { | 434 | { |
@@ -436,24 +443,38 @@ unix_real_send (void *cls, | |||
436 | { | 443 | { |
437 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
438 | "Trying to increase socket buffer size from %i to %i for message size %i\n", | 445 | "Trying to increase socket buffer size from %i to %i for message size %i\n", |
439 | size, ((msgbuf_size / 1000) + 2) * 1000, msgbuf_size); | 446 | size, |
447 | ((msgbuf_size / 1000) + 2) * 1000, | ||
448 | msgbuf_size); | ||
440 | size = ((msgbuf_size / 1000) + 2) * 1000; | 449 | size = ((msgbuf_size / 1000) + 2) * 1000; |
441 | if (GNUNET_NETWORK_socket_setsockopt | 450 | if (GNUNET_NETWORK_socket_setsockopt |
442 | ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF, | 451 | ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF, |
443 | &size, sizeof (size)) == GNUNET_OK) | 452 | &size, sizeof (size)) == GNUNET_OK) |
444 | { | 453 | { |
445 | sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs); | 454 | /* Increased buffer size, retry sending */ |
455 | return 0; | ||
446 | } | 456 | } |
447 | else | 457 | else |
448 | { | 458 | { |
459 | /* Could not increase buffer size: error, no retry */ | ||
449 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); | 460 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); |
461 | return -1; | ||
450 | } | 462 | } |
451 | } | 463 | } |
464 | else | ||
465 | { | ||
466 | /* Buffer is bigger than message: error, no retry | ||
467 | * This should never happen!*/ | ||
468 | GNUNET_break (0); | ||
469 | return -1; | ||
470 | } | ||
452 | } | 471 | } |
472 | |||
453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 473 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
454 | "UNIX transmit %u-byte message to %s (%d: %s)\n", | 474 | "UNIX transmit %u-byte message to %s (%d: %s)\n", |
455 | (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent, | 475 | (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent, |
456 | (sent < 0) ? STRERROR (errno) : "ok"); | 476 | (sent < 0) ? STRERROR (errno) : "ok"); |
477 | |||
457 | /* Calling continuation */ | 478 | /* Calling continuation */ |
458 | if (cont != NULL) | 479 | if (cont != NULL) |
459 | { | 480 | { |
@@ -466,14 +487,20 @@ unix_real_send (void *cls, | |||
466 | /* return number of bytes successfully sent */ | 487 | /* return number of bytes successfully sent */ |
467 | if (sent > 0) | 488 | if (sent > 0) |
468 | return sent; | 489 | return sent; |
490 | if (sent == 0) | ||
491 | { | ||
492 | /* That should never happen */ | ||
493 | GNUNET_break (0); | ||
494 | return -1; | ||
495 | } | ||
469 | /* failed and retry: return 0 */ | 496 | /* failed and retry: return 0 */ |
470 | if ((GNUNET_SYSERR == sent) && (retry == GNUNET_YES)) | 497 | if ((GNUNET_SYSERR == sent) && (retry == GNUNET_YES)) |
471 | return 0; | 498 | return 0; |
472 | /* failed and no retry: return -1 */ | 499 | /* failed and no retry: return -1 */ |
473 | if ((GNUNET_SYSERR == sent) && (retry == GNUNET_NO)) | 500 | if ((GNUNET_SYSERR == sent) && (retry == GNUNET_NO)) |
474 | return -1; | 501 | return -1; |
475 | 502 | /* default */ | |
476 | return sent; | 503 | return -1; |
477 | } | 504 | } |
478 | 505 | ||
479 | struct gsi_ctx | 506 | struct gsi_ctx |
@@ -756,6 +783,7 @@ unix_plugin_select_read (struct Plugin * plugin) | |||
756 | static void | 783 | static void |
757 | unix_plugin_select_write (struct Plugin * plugin) | 784 | unix_plugin_select_write (struct Plugin * plugin) |
758 | { | 785 | { |
786 | static int retry_counter; | ||
759 | int sent = 0; | 787 | int sent = 0; |
760 | struct UNIXMessageWrapper * msgw = plugin->msg_head; | 788 | struct UNIXMessageWrapper * msgw = plugin->msg_head; |
761 | 789 | ||
@@ -770,9 +798,26 @@ unix_plugin_select_write (struct Plugin * plugin) | |||
770 | msgw->session->addrlen, | 798 | msgw->session->addrlen, |
771 | msgw->cont, msgw->cont_cls); | 799 | msgw->cont, msgw->cont_cls); |
772 | 800 | ||
773 | /* successfully sent bytes */ | 801 | if (sent == 0) |
774 | if (sent > 0) | 802 | { |
803 | /* failed and retry */ | ||
804 | retry_counter++; | ||
805 | GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", | ||
806 | retry_counter, GNUNET_NO); | ||
807 | return; | ||
808 | } | ||
809 | |||
810 | if (retry_counter > 0 ) | ||
811 | { | ||
812 | /* no retry: reset counter */ | ||
813 | retry_counter = 0; | ||
814 | GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", | ||
815 | retry_counter, GNUNET_NO); | ||
816 | } | ||
817 | |||
818 | if (sent == -1) | ||
775 | { | 819 | { |
820 | /* failed and no retry */ | ||
776 | GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); | 821 | GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); |
777 | 822 | ||
778 | GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); | 823 | GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); |
@@ -785,9 +830,9 @@ unix_plugin_select_write (struct Plugin * plugin) | |||
785 | return; | 830 | return; |
786 | } | 831 | } |
787 | 832 | ||
788 | /* failed and no retry */ | 833 | if (sent > 0) |
789 | if (sent == -1) | ||
790 | { | 834 | { |
835 | /* successfully sent bytes */ | ||
791 | GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); | 836 | GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); |
792 | 837 | ||
793 | GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); | 838 | GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); |
@@ -800,9 +845,6 @@ unix_plugin_select_write (struct Plugin * plugin) | |||
800 | return; | 845 | return; |
801 | } | 846 | } |
802 | 847 | ||
803 | /* failed and retry */ | ||
804 | if (sent == 0) | ||
805 | return; | ||
806 | } | 848 | } |
807 | 849 | ||
808 | /* | 850 | /* |
@@ -823,9 +865,9 @@ unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
823 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 865 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) |
824 | return; | 866 | return; |
825 | 867 | ||
826 | plugin->with_ws = GNUNET_NO; | ||
827 | if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) | 868 | if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) |
828 | { | 869 | { |
870 | /* Ready to send data */ | ||
829 | GNUNET_assert (GNUNET_NETWORK_fdset_isset | 871 | GNUNET_assert (GNUNET_NETWORK_fdset_isset |
830 | (tc->write_ready, plugin->unix_sock.desc)); | 872 | (tc->write_ready, plugin->unix_sock.desc)); |
831 | if (plugin->msg_head != NULL) | 873 | if (plugin->msg_head != NULL) |
@@ -834,6 +876,7 @@ unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
834 | 876 | ||
835 | if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) | 877 | if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) |
836 | { | 878 | { |
879 | /* Ready to receive data */ | ||
837 | GNUNET_assert (GNUNET_NETWORK_fdset_isset | 880 | GNUNET_assert (GNUNET_NETWORK_fdset_isset |
838 | (tc->read_ready, plugin->unix_sock.desc)); | 881 | (tc->read_ready, plugin->unix_sock.desc)); |
839 | unix_plugin_select_read (plugin); | 882 | unix_plugin_select_read (plugin); |
@@ -841,14 +884,27 @@ unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
841 | 884 | ||
842 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) | 885 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) |
843 | GNUNET_SCHEDULER_cancel (plugin->select_task); | 886 | GNUNET_SCHEDULER_cancel (plugin->select_task); |
844 | plugin->select_task = | 887 | |
888 | if (NULL != plugin->msg_head) | ||
889 | { | ||
890 | plugin->select_task = | ||
845 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 891 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
846 | GNUNET_TIME_UNIT_FOREVER_REL, | 892 | GNUNET_TIME_UNIT_FOREVER_REL, |
847 | plugin->rs, | 893 | plugin->rs, |
848 | (plugin->msg_head != NULL) ? plugin->ws : NULL, | 894 | plugin->ws, |
849 | &unix_plugin_select, plugin); | 895 | &unix_plugin_select, plugin); |
850 | if (plugin->msg_head != NULL) | ||
851 | plugin->with_ws = GNUNET_YES; | 896 | plugin->with_ws = GNUNET_YES; |
897 | } | ||
898 | else | ||
899 | { | ||
900 | plugin->select_task = | ||
901 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
902 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
903 | plugin->rs, | ||
904 | NULL, | ||
905 | &unix_plugin_select, plugin); | ||
906 | plugin->with_ws = GNUNET_NO; | ||
907 | } | ||
852 | } | 908 | } |
853 | 909 | ||
854 | /** | 910 | /** |