aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-03 16:11:02 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-03 16:11:02 +0000
commitb53d7bfde8da84afaa7ee8888d15f1cc6cffd866 (patch)
tree054c60c339f25f78c92b99d500e19e6832081eab /src/vpn
parent213bc87131772ae2b808428a6e5ff65a1d963e24 (diff)
downloadgnunet-b53d7bfde8da84afaa7ee8888d15f1cc6cffd866.tar.gz
gnunet-b53d7bfde8da84afaa7ee8888d15f1cc6cffd866.zip
There are now four states for the OI facilities:
* ready (to do work), * queued (waiting for async-io to return), * waiting (a read-facilities wait for its output partner to get process) * failed (if a socket error occured) added attempt_tap_read machine. reworked run() for overlapped IO
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c193
1 files changed, 157 insertions, 36 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index 39aa84d9d..98e82dad9 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -146,6 +146,7 @@ struct overlapped_facility
146{ 146{
147 int iostate; 147 int iostate;
148 BOOL status; // BOOL is winbool, NOT boolean! 148 BOOL status; // BOOL is winbool, NOT boolean!
149 BOOL path_open;
149 DWORD flags; 150 DWORD flags;
150 151
151 OVERLAPPED overlapped; 152 OVERLAPPED overlapped;
@@ -155,11 +156,12 @@ struct overlapped_facility
155}; 156};
156 157
157/** 158/**
158 * Operlapped IO states for its objects 159 * Operlapped IO states for facility objects
159 */ 160 */
160#define IOSTATE_INITIAL 0 161#define IOSTATE_FAILED -1 /* overlapped I/O has failed, stop processing */
162#define IOSTATE_READY 0 /* overlapped I/O is ready for work */
161#define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */ 163#define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */
162#define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately without queueing */ 164#define IOSTATE_WAITING 3 /* overlapped I/O has finished, but is waiting for it's write-partner */
163 165
164#if WINVER < 0x0600 166#if WINVER < 0x0600
165 167
@@ -697,6 +699,127 @@ tun_up (HANDLE handle)
697 699
698} 700}
699 701
702static boolean
703attempt_std_in ( struct overlapped_facility * std_in,
704 struct overlapped_facility * tap_write)
705{
706 return TRUE;
707}
708
709static boolean
710attempt_tap_read (HANDLE tap_handle,
711 struct overlapped_facility * tap_read,
712 struct overlapped_facility * std_out)
713{
714
715 if (IOSTATE_READY == tap_read->iostate)
716 {
717 if (!ResetEvent (tap_read->overlapped.hEvent))
718 {
719 return FALSE;
720 }
721 tap_read->status = ReadFile (tap_handle,
722 &tap_read->buffer[MAX_SIZE],
723 MAX_SIZE,
724 &tap_read->buffer_size,
725 &tap_read->overlapped);
726
727 /* Check how the task is handled */
728 if (tap_read->status)
729 {/* async event processed immediately*/
730
731 /* reset event manually*/
732 if (!SetEvent (tap_read->overlapped.hEvent))
733 return FALSE;
734
735 /* we successfully read something from the TAP and now need to
736 * send it our via STDOUT. Is that possible at the moment? */
737 if (IOSTATE_READY == std_out->iostate && 0 < tap_read->buffer_size)
738 { /* hand over this buffers content */
739 memcpy (std_out->buffer,
740 tap_read->buffer,
741 MAX_SIZE);
742 std_out->buffer_size = tap_read->buffer_size;
743 std_out->iostate = IOSTATE_READY;
744 }
745 else if (0 < tap_read->buffer_size)
746 { /* If we have have read our buffer, wait for our write-partner*/
747 tap_read->iostate = IOSTATE_WAITING;
748 // TODO: shall we attempt to fill our bufferm or should we wait for our write-partner to finish?
749 }
750 }
751 else /* operation was either queued or failed*/
752 {
753 int err = GetLastError ();
754 if (ERROR_IO_PENDING == err)
755 { /* operation queued */
756 tap_read->iostate = IOSTATE_QUEUED;
757 }
758 else
759 { /* error occurred, let the rest of the elements finish */
760 tap_read->path_open = FALSE;
761 tap_read->iostate = IOSTATE_FAILED;
762 }
763 }
764 }
765 // We are queued and should check if the read has finished
766 else if (IOSTATE_QUEUED == tap_read->iostate )
767 {
768 // there was an operation going on already, check if that has completed now.
769 tap_read->status = GetOverlappedResult (tap_handle,
770 &tap_read->overlapped,
771 &tap_read->buffer_size,
772 FALSE);
773 if (tap_read->status)
774 {/* successful return for a queued operation */
775 if (!ResetEvent (tap_read->overlapped.hEvent))
776 return FALSE;
777
778 /* we successfully read something from the TAP and now need to
779 * send it our via STDOUT. Is that possible at the moment? */
780 if (IOSTATE_READY == std_out->iostate && 0 < tap_read->buffer_size )
781 { /* hand over this buffers content */
782 memcpy (std_out->buffer,
783 tap_read->buffer,
784 MAX_SIZE);
785 std_out->buffer_size = tap_read->buffer_size;
786 std_out->iostate = IOSTATE_READY;
787 tap_read->iostate = IOSTATE_READY;
788 }
789 else if (0 < tap_read->buffer_size)
790 { /* If we have have read our buffer, wait for our write-partner*/
791 tap_read->iostate = IOSTATE_WAITING;
792 // TODO: shall we attempt to fill our bufferm or should we wait for our write-partner to finish?
793 }
794 }
795 else
796 { /* operation still pending/queued or failed? */
797 int err = GetLastError ();
798 if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err )
799 { /* error occurred, let the rest of the elements finish */
800 tap_read->path_open = FALSE;
801 tap_read->iostate = IOSTATE_FAILED;
802 }
803 }
804 }
805 return TRUE;
806}
807
808static boolean
809attempt_tap_write (HANDLE tap_handle,
810 struct overlapped_facility * tap_write,
811 struct overlapped_facility * std_in)
812{
813 return TRUE;
814}
815
816static boolean
817attempt_std_out ( struct overlapped_facility * std_out,
818 struct overlapped_facility * tap_read)
819{
820 return TRUE;
821}
822
700/** 823/**
701 * Initialize a overlapped structure 824 * Initialize a overlapped structure
702 * 825 *
@@ -711,9 +834,10 @@ initialize_overlapped_facility (struct overlapped_facility * elem,
711 BOOL signaled) 834 BOOL signaled)
712{ 835{
713 836
837 elem->path_open = TRUE;
714 elem->status = initial_state; 838 elem->status = initial_state;
715 elem->iostate = 0; 839 elem->iostate = 0;
716 elem->buffer_size = MAX_SIZE; 840 elem->buffer_size = 0;
717 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); 841 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL);
718 if (NULL == elem->overlapped.hEvent) 842 if (NULL == elem->overlapped.hEvent)
719 return FALSE; 843 return FALSE;
@@ -727,13 +851,8 @@ initialize_overlapped_facility (struct overlapped_facility * elem,
727 * @param fd_tun tunnel FD 851 * @param fd_tun tunnel FD
728 */ 852 */
729static void 853static void
730run (HANDLE handle) 854run (HANDLE tap_handle)
731{ 855{
732 /* read refers to reading from fd_tun, writing to stdout */
733 int read_open = 1;
734 /* write refers to reading from stdin, writing to fd_tun */
735 int write_open = 1;
736
737 /* IO-Facility for reading from our virtual interface */ 856 /* IO-Facility for reading from our virtual interface */
738 struct overlapped_facility tap_read; 857 struct overlapped_facility tap_read;
739 /* IO-Facility for writing to our virtual interface */ 858 /* IO-Facility for writing to our virtual interface */
@@ -750,10 +869,7 @@ run (HANDLE handle)
750 * DHCP and such are all features we will never use in gnunet afaik. 869 * DHCP and such are all features we will never use in gnunet afaik.
751 * But for openvpn those are essential. 870 * But for openvpn those are essential.
752 */ 871 */
753 if (!tun_up (handle)) 872 if (!tun_up (tap_handle))
754 goto teardown;
755
756 if (!)
757 goto teardown; 873 goto teardown;
758 874
759 /* Initialize our overlapped IO structures*/ 875 /* Initialize our overlapped IO structures*/
@@ -776,29 +892,34 @@ run (HANDLE handle)
776 // tunnel_point_to_point 892 // tunnel_point_to_point
777 // openvpn.c:62 893 // openvpn.c:62
778 894
779 while ((1 == read_open) || (1 == write_open)) 895 while (std_in.path_open
896 || std_out.path_open
897 || tap_read.path_open
898 || tap_write.path_open)
780 { 899 {
781 900 /* perform READ from stdin if possible */
782 /* READ from stdin is possible */ 901 if ((std_in.path_open && tap_write.path_open)
783 if (std_in.status) 902 || IOSTATE_QUEUED == std_in.iostate)
784 { 903 if (!attempt_std_in (&std_in, &tap_write))
785 904 break;
786 } 905
787 /* READ from tap is possible */ 906 /* perform READ from tap if possible */
788 if (tap_read.status) 907 if ((tap_read.path_open && std_out.path_open)
789 { 908 || IOSTATE_QUEUED == tap_read.iostate )
790 909 if (!attempt_tap_read (tap_handle, &tap_read, &std_out))
791 } 910 break;
792 /* WRITE to tap is possible */ 911
793 if (tap_write.status) 912 /* perform WRITE to tap if possible */
794 { 913 if ( IOSTATE_READY == tap_write.iostate && tap_write.path_open )
795 914 if (!attempt_tap_write (tap_handle, &tap_write, &std_in))
796 } 915 break;
797 /* WRITE to STDOUT is possible */ 916
798 if (std_out.status) 917 /* perform WRITE to STDOUT if possible */
799 { 918 if ( IOSTATE_READY == std_out.iostate && std_out.path_open)
800 919 if (!attempt_std_out (&std_out, &tap_read))
801 } 920 break;
921
922 // check if any path is blocked
802 } 923 }
803teardown: 924teardown:
804 ; 925 ;