aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_unix.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-05-02 10:50:27 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-05-02 10:50:27 +0000
commit45063a766d9a922d7f2b762ede305679e728cbfc (patch)
treef65310dc11769701f0f8ac3435835e189e8f559a /src/transport/plugin_transport_unix.c
parent9b49646d47d94a1538879a0533a3762c71c5590d (diff)
downloadgnunet-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.c106
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
479struct gsi_ctx 506struct gsi_ctx
@@ -756,6 +783,7 @@ unix_plugin_select_read (struct Plugin * plugin)
756static void 783static void
757unix_plugin_select_write (struct Plugin * plugin) 784unix_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/**