aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-10 12:36:06 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-10 12:36:06 +0000
commit763db022115084a225f62f8795a897c1512b8709 (patch)
treef274da38acbb6238535882bdff5723fda9368622 /src/vpn
parent7c9dad282dc26d582da100d34a463d6aec13fbce (diff)
downloadgnunet-763db022115084a225f62f8795a897c1512b8709.tar.gz
gnunet-763db022115084a225f62f8795a897c1512b8709.zip
consolidated read and write functions, as we can read from a named pipe
the same way as we can read from our TAP. added high-level description of attempt_read
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c241
1 files changed, 91 insertions, 150 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index f7000e8fa..c67e654e2 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -678,7 +678,12 @@ init_tun ()
678 678
679 return handle; 679 return handle;
680} 680}
681 681/**
682 * Brings a TAP device up and sets it to connected state.
683 *
684 * @param handle the handle to our TAP device
685 * @return True if the operation succeeded, else false
686 */
682static boolean 687static boolean
683tun_up (HANDLE handle) 688tun_up (HANDLE handle)
684{ 689{
@@ -699,142 +704,69 @@ tun_up (HANDLE handle)
699 704
700} 705}
701 706
707/**
708 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
709 *
710 * 1.
711 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the
712 * input handle. Then it goes into IOSTATE_QUEUED state.
713 * In case the read succeeded instantly the input facility enters 3.
714 *
715 * 2.
716 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already.
717 * If it has finished, go to state 3.
718 * If it has failed, set IOSTATE_FAILED
719 *
720 * 3.
721 * If the output facility is in state IOSTATE_READY, the read-buffer is copied to the output buffer.
722 * The input facility enters state IOSTATE_READY
723 * The output facility enters state IOSTATE_READY
724 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING
725 *
726 * IOSTATE_WAITING is reset by the output facility, once it has completed.
727 *
728 * @param input_facility input named pipe or file to work with.
729 * @param output_facility output pipe or file to hand over data to.
730 * @return false if an event reset was impossible (OS error), else true
731 */
702static boolean 732static boolean
703attempt_std_in (struct io_facility * std_in, 733attempt_read (struct io_facility * input_facility,
704 struct io_facility * tap_write) 734 struct io_facility * output_facility)
705{
706
707 if (IOSTATE_READY == std_in->facility_state)
708 {
709 if (!ResetEvent (std_in->overlapped.hEvent))
710 {
711 return FALSE;
712 }
713/* std_in->status = ReadFile (std_in->handle,
714 &std_in->buffer[MAX_SIZE],
715 MAX_SIZE,
716 &std_in->buffer_size,
717 &std_in->overlapped);
718*/
719 /* Check how the task is handled */
720 if (std_in->status)
721 {/* async event processed immediately*/
722
723 /* reset event manually*/
724 if (!SetEvent (std_in->overlapped.hEvent))
725 return FALSE;
726
727 /* we successfully read something from the TAP and now need to
728 * send it our via STDOUT. Is that possible at the moment? */
729 if (IOSTATE_READY == tap_write->facility_state && 0 < std_in->buffer_size)
730 { /* hand over this buffers content */
731 memcpy (tap_write->buffer,
732 std_in->buffer,
733 MAX_SIZE);
734 tap_write->buffer_size = std_in->buffer_size;
735 tap_write->facility_state = IOSTATE_READY;
736 }
737 else if (0 < std_in->buffer_size)
738 { /* If we have have read our buffer, wait for our write-partner*/
739 std_in->facility_state = IOSTATE_WAITING;
740 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
741 }
742 }
743 else /* operation was either queued or failed*/
744 {
745 int err = GetLastError ();
746 if (ERROR_IO_PENDING == err)
747 { /* operation queued */
748 std_in->facility_state = IOSTATE_QUEUED;
749 }
750 else
751 { /* error occurred, let the rest of the elements finish */
752 std_in->path_open = FALSE;
753 std_in->facility_state = IOSTATE_FAILED;
754 }
755 }
756 }
757 // We are queued and should check if the read has finished
758 else if (IOSTATE_QUEUED == std_in->facility_state)
759 {
760 // there was an operation going on already, check if that has completed now.
761 std_in->status = GetOverlappedResult (std_in->handle,
762 &std_in->overlapped,
763 &std_in->buffer_size,
764 FALSE);
765 if (std_in->status)
766 {/* successful return for a queued operation */
767 if (!ResetEvent (std_in->overlapped.hEvent))
768 return FALSE;
769
770 /* we successfully read something from the TAP and now need to
771 * send it our via STDOUT. Is that possible at the moment? */
772 if (IOSTATE_READY == tap_write->facility_state && 0 < std_in->buffer_size)
773 { /* hand over this buffers content */
774 memcpy (tap_write->buffer,
775 std_in->buffer,
776 MAX_SIZE);
777 tap_write->buffer_size = std_in->buffer_size;
778 tap_write->facility_state = IOSTATE_READY;
779 std_in->facility_state = IOSTATE_READY;
780 }
781 else if (0 < std_in->buffer_size)
782 { /* If we have have read our buffer, wait for our write-partner*/
783 std_in->facility_state = IOSTATE_WAITING;
784 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
785 }
786 }
787 else
788 { /* operation still pending/queued or failed? */
789 int err = GetLastError ();
790 if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err)
791 { /* error occurred, let the rest of the elements finish */
792 std_in->path_open = FALSE;
793 std_in->facility_state = IOSTATE_FAILED;
794 }
795 }
796 }
797 return TRUE;
798}
799
800static boolean
801attempt_tap_read (struct io_facility * tap_read,
802 struct io_facility * std_out)
803{ 735{
804 736
805 if (IOSTATE_READY == tap_read->facility_state) 737 if (IOSTATE_READY == input_facility->facility_state)
806 { 738 {
807 if (!ResetEvent (tap_read->overlapped.hEvent)) 739 if (!ResetEvent (input_facility->overlapped.hEvent))
808 { 740 {
809 return FALSE; 741 return FALSE;
810 } 742 }
811 tap_read->status = ReadFile (tap_read->handle, 743 input_facility->status = ReadFile (input_facility->handle,
812 &tap_read->buffer[MAX_SIZE], 744 &input_facility->buffer[MAX_SIZE],
813 MAX_SIZE, 745 MAX_SIZE,
814 &tap_read->buffer_size, 746 &input_facility->buffer_size,
815 &tap_read->overlapped); 747 &input_facility->overlapped);
816 748
817 /* Check how the task is handled */ 749 /* Check how the task is handled */
818 if (tap_read->status) 750 if (input_facility->status)
819 {/* async event processed immediately*/ 751 {/* async event processed immediately*/
820 752
821 /* reset event manually*/ 753 /* reset event manually*/
822 if (!SetEvent (tap_read->overlapped.hEvent)) 754 if (!SetEvent (input_facility->overlapped.hEvent))
823 return FALSE; 755 return FALSE;
824 756
825 /* we successfully read something from the TAP and now need to 757 /* we successfully read something from the TAP and now need to
826 * send it our via STDOUT. Is that possible at the moment? */ 758 * send it our via STDOUT. Is that possible at the moment? */
827 if (IOSTATE_READY == std_out->facility_state && 0 < tap_read->buffer_size) 759 if (IOSTATE_READY == output_facility->facility_state && 0 < input_facility->buffer_size)
828 { /* hand over this buffers content */ 760 { /* hand over this buffers content */
829 memcpy (std_out->buffer, 761 memcpy (output_facility->buffer,
830 tap_read->buffer, 762 input_facility->buffer,
831 MAX_SIZE); 763 MAX_SIZE);
832 std_out->buffer_size = tap_read->buffer_size; 764 output_facility->buffer_size = input_facility->buffer_size;
833 std_out->facility_state = IOSTATE_READY; 765 output_facility->facility_state = IOSTATE_READY;
834 } 766 }
835 else if (0 < tap_read->buffer_size) 767 else if (0 < input_facility->buffer_size)
836 { /* If we have have read our buffer, wait for our write-partner*/ 768 { /* If we have have read our buffer, wait for our write-partner*/
837 tap_read->facility_state = IOSTATE_WAITING; 769 input_facility->facility_state = IOSTATE_WAITING;
838 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 770 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
839 } 771 }
840 } 772 }
@@ -843,42 +775,42 @@ attempt_tap_read (struct io_facility * tap_read,
843 int err = GetLastError (); 775 int err = GetLastError ();
844 if (ERROR_IO_PENDING == err) 776 if (ERROR_IO_PENDING == err)
845 { /* operation queued */ 777 { /* operation queued */
846 tap_read->facility_state = IOSTATE_QUEUED; 778 input_facility->facility_state = IOSTATE_QUEUED;
847 } 779 }
848 else 780 else
849 { /* error occurred, let the rest of the elements finish */ 781 { /* error occurred, let the rest of the elements finish */
850 tap_read->path_open = FALSE; 782 input_facility->path_open = FALSE;
851 tap_read->facility_state = IOSTATE_FAILED; 783 input_facility->facility_state = IOSTATE_FAILED;
852 } 784 }
853 } 785 }
854 } 786 }
855 // We are queued and should check if the read has finished 787 // We are queued and should check if the read has finished
856 else if (IOSTATE_QUEUED == tap_read->facility_state) 788 else if (IOSTATE_QUEUED == input_facility->facility_state)
857 { 789 {
858 // there was an operation going on already, check if that has completed now. 790 // there was an operation going on already, check if that has completed now.
859 tap_read->status = GetOverlappedResult (tap_read->handle, 791 input_facility->status = GetOverlappedResult (input_facility->handle,
860 &tap_read->overlapped, 792 &input_facility->overlapped,
861 &tap_read->buffer_size, 793 &input_facility->buffer_size,
862 FALSE); 794 FALSE);
863 if (tap_read->status) 795 if (input_facility->status)
864 {/* successful return for a queued operation */ 796 {/* successful return for a queued operation */
865 if (!ResetEvent (tap_read->overlapped.hEvent)) 797 if (!ResetEvent (input_facility->overlapped.hEvent))
866 return FALSE; 798 return FALSE;
867 799
868 /* we successfully read something from the TAP and now need to 800 /* we successfully read something from the TAP and now need to
869 * send it our via STDOUT. Is that possible at the moment? */ 801 * send it our via STDOUT. Is that possible at the moment? */
870 if (IOSTATE_READY == std_out->facility_state && 0 < tap_read->buffer_size) 802 if (IOSTATE_READY == output_facility->facility_state && 0 < input_facility->buffer_size)
871 { /* hand over this buffers content */ 803 { /* hand over this buffers content */
872 memcpy (std_out->buffer, 804 memcpy (output_facility->buffer,
873 tap_read->buffer, 805 input_facility->buffer,
874 MAX_SIZE); 806 MAX_SIZE);
875 std_out->buffer_size = tap_read->buffer_size; 807 output_facility->buffer_size = input_facility->buffer_size;
876 std_out->facility_state = IOSTATE_READY; 808 output_facility->facility_state = IOSTATE_READY;
877 tap_read->facility_state = IOSTATE_READY; 809 input_facility->facility_state = IOSTATE_READY;
878 } 810 }
879 else if (0 < tap_read->buffer_size) 811 else if (0 < input_facility->buffer_size)
880 { /* If we have have read our buffer, wait for our write-partner*/ 812 { /* If we have have read our buffer, wait for our write-partner*/
881 tap_read->facility_state = IOSTATE_WAITING; 813 input_facility->facility_state = IOSTATE_WAITING;
882 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 814 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
883 } 815 }
884 } 816 }
@@ -887,25 +819,34 @@ attempt_tap_read (struct io_facility * tap_read,
887 int err = GetLastError (); 819 int err = GetLastError ();
888 if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err) 820 if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err)
889 { /* error occurred, let the rest of the elements finish */ 821 { /* error occurred, let the rest of the elements finish */
890 tap_read->path_open = FALSE; 822 input_facility->path_open = FALSE;
891 tap_read->facility_state = IOSTATE_FAILED; 823 input_facility->facility_state = IOSTATE_FAILED;
892 } 824 }
893 } 825 }
894 } 826 }
895 return TRUE; 827 return TRUE;
896} 828}
897 829
830/**
831 * Attempts to write to an output facility (tap or named pipe) in overlapped mode.
832 *
833 * TODO: high level description
834 *
835 * @param output_facility output pipe or file to hand over data to.
836 * @param input_facility input named pipe or file to work with.
837 * @return false if an event reset was impossible (OS error), else true
838 */
898static boolean 839static boolean
899attempt_tap_write (struct io_facility * tap_write, 840attempt_write (struct io_facility * output_facility,
900 struct io_facility * std_in) 841 struct io_facility * input_facility)
901{ 842{
902 return TRUE; 843 if (IOSTATE_READY == output_facility->facility_state && output_facility->buffer_size > 0 ){
903} 844
845 }
846 else if (IOSTATE_QUEUED == output_facility->facility_state){
847
848 }
904 849
905static boolean
906attempt_std_out (struct io_facility * std_out,
907 struct io_facility * tap_read)
908{
909 return TRUE; 850 return TRUE;
910} 851}
911 852
@@ -984,7 +925,7 @@ run (HANDLE tap_handle)
984 if (FILE_TYPE_PIPE != GetFileType (parent_std_in_handle) || 925 if (FILE_TYPE_PIPE != GetFileType (parent_std_in_handle) ||
985 FILE_TYPE_PIPE != GetFileType (parent_std_out_handle)) 926 FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))
986 { 927 {
987 fprintf (stderr, "Fatal: stdin/stdout must be pipes!\n"); 928 fprintf (stderr, "Fatal: stdin/stdout must be named pipes!\n");
988 goto teardown; 929 goto teardown;
989 } 930 }
990 931
@@ -995,7 +936,7 @@ run (HANDLE tap_handle)
995 936
996 if (INVALID_HANDLE_VALUE == std_in.handle) 937 if (INVALID_HANDLE_VALUE == std_in.handle)
997 { 938 {
998 fprintf (stderr, "Fatal: Could not reopen stdin for in overlapped mode!\n"); 939 fprintf (stderr, "Fatal: Could not reopen stdin for in overlapped mode, has to be a named pipe!\n");
999 goto teardown; 940 goto teardown;
1000 } 941 }
1001 942
@@ -1006,7 +947,7 @@ run (HANDLE tap_handle)
1006 947
1007 if (INVALID_HANDLE_VALUE == std_out.handle) 948 if (INVALID_HANDLE_VALUE == std_out.handle)
1008 { 949 {
1009 fprintf (stderr, "Fatal: Could not reopen stdout for in overlapped mode!\n"); 950 fprintf (stderr, "Fatal: Could not reopen stdout for in overlapped mode, has to be a named pipe!\n");
1010 goto teardown; 951 goto teardown;
1011 } 952 }
1012 953
@@ -1030,23 +971,23 @@ run (HANDLE tap_handle)
1030 /* perform READ from stdin if possible */ 971 /* perform READ from stdin if possible */
1031 if ((std_in.path_open && tap_write.path_open) 972 if ((std_in.path_open && tap_write.path_open)
1032 || IOSTATE_QUEUED == std_in.facility_state) 973 || IOSTATE_QUEUED == std_in.facility_state)
1033 if (!attempt_std_in (&std_in, &tap_write)) 974 if (!attempt_read (&std_in, &tap_write))
1034 break; 975 break;
1035 976
1036 /* perform READ from tap if possible */ 977 /* perform READ from tap if possible */
1037 if ((tap_read.path_open && std_out.path_open) 978 if ((tap_read.path_open && std_out.path_open)
1038 || IOSTATE_QUEUED == tap_read.facility_state) 979 || IOSTATE_QUEUED == tap_read.facility_state)
1039 if (!attempt_tap_read (&tap_read, &std_out)) 980 if (!attempt_read (&tap_read, &std_out))
1040 break; 981 break;
1041 982
1042 /* perform WRITE to tap if possible */ 983 /* perform WRITE to tap if possible */
1043 if (IOSTATE_READY == tap_write.facility_state && tap_write.path_open) 984 if (IOSTATE_READY == tap_write.facility_state && tap_write.path_open)
1044 if (!attempt_tap_write (&tap_write, &std_in)) 985 if (!attempt_write (&tap_write, &std_in))
1045 break; 986 break;
1046 987
1047 /* perform WRITE to STDOUT if possible */ 988 /* perform WRITE to STDOUT if possible */
1048 if (IOSTATE_READY == std_out.facility_state && std_out.path_open) 989 if (IOSTATE_READY == std_out.facility_state && std_out.path_open)
1049 if (!attempt_std_out (&std_out, &tap_read)) 990 if (!attempt_write (&std_out, &tap_read))
1050 break; 991 break;
1051 992
1052 // check if any path is blocked 993 // check if any path is blocked