[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r25683 - gnunet/src/vpn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r25683 - gnunet/src/vpn |
Date: |
Thu, 3 Jan 2013 17:11:03 +0100 |
Author: cfuchs
Date: 2013-01-03 17:11:02 +0100 (Thu, 03 Jan 2013)
New Revision: 25683
Modified:
gnunet/src/vpn/gnunet-helper-vpn-windows.c
Log:
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
Modified: gnunet/src/vpn/gnunet-helper-vpn-windows.c
===================================================================
--- gnunet/src/vpn/gnunet-helper-vpn-windows.c 2013-01-03 14:58:20 UTC (rev
25682)
+++ gnunet/src/vpn/gnunet-helper-vpn-windows.c 2013-01-03 16:11:02 UTC (rev
25683)
@@ -146,6 +146,7 @@
{
int iostate;
BOOL status; // BOOL is winbool, NOT boolean!
+ BOOL path_open;
DWORD flags;
OVERLAPPED overlapped;
@@ -155,11 +156,12 @@
};
/**
- * Operlapped IO states for its objects
+ * Operlapped IO states for facility objects
*/
-#define IOSTATE_INITIAL 0
+#define IOSTATE_FAILED -1 /* overlapped I/O has failed, stop
processing */
+#define IOSTATE_READY 0 /* overlapped I/O is ready for work */
#define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */
-#define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately
without queueing */
+#define IOSTATE_WAITING 3 /* overlapped I/O has finished, but is
waiting for it's write-partner */
#if WINVER < 0x0600
@@ -697,6 +699,127 @@
}
+static boolean
+attempt_std_in ( struct overlapped_facility * std_in,
+ struct overlapped_facility * tap_write)
+{
+ return TRUE;
+}
+
+static boolean
+attempt_tap_read (HANDLE tap_handle,
+ struct overlapped_facility * tap_read,
+ struct overlapped_facility * std_out)
+{
+
+ if (IOSTATE_READY == tap_read->iostate)
+ {
+ if (!ResetEvent (tap_read->overlapped.hEvent))
+ {
+ return FALSE;
+ }
+ tap_read->status = ReadFile (tap_handle,
+ &tap_read->buffer[MAX_SIZE],
+ MAX_SIZE,
+ &tap_read->buffer_size,
+ &tap_read->overlapped);
+
+ /* Check how the task is handled */
+ if (tap_read->status)
+ {/* async event processed immediately*/
+
+ /* reset event manually*/
+ if (!SetEvent (tap_read->overlapped.hEvent))
+ return FALSE;
+
+ /* we successfully read something from the TAP and now need to
+ * send it our via STDOUT. Is that possible at the moment? */
+ if (IOSTATE_READY == std_out->iostate && 0 < tap_read->buffer_size)
+ { /* hand over this buffers content */
+ memcpy (std_out->buffer,
+ tap_read->buffer,
+ MAX_SIZE);
+ std_out->buffer_size = tap_read->buffer_size;
+ std_out->iostate = IOSTATE_READY;
+ }
+ else if (0 < tap_read->buffer_size)
+ { /* If we have have read our buffer, wait for our write-partner*/
+ tap_read->iostate = IOSTATE_WAITING;
+ // TODO: shall we attempt to fill our bufferm or should we wait
for our write-partner to finish?
+ }
+ }
+ else /* operation was either queued or failed*/
+ {
+ int err = GetLastError ();
+ if (ERROR_IO_PENDING == err)
+ { /* operation queued */
+ tap_read->iostate = IOSTATE_QUEUED;
+ }
+ else
+ { /* error occurred, let the rest of the elements finish */
+ tap_read->path_open = FALSE;
+ tap_read->iostate = IOSTATE_FAILED;
+ }
+ }
+ }
+ // We are queued and should check if the read has finished
+ else if (IOSTATE_QUEUED == tap_read->iostate )
+ {
+ // there was an operation going on already, check if that has completed
now.
+ tap_read->status = GetOverlappedResult (tap_handle,
+ &tap_read->overlapped,
+ &tap_read->buffer_size,
+ FALSE);
+ if (tap_read->status)
+ {/* successful return for a queued operation */
+ if (!ResetEvent (tap_read->overlapped.hEvent))
+ return FALSE;
+
+ /* we successfully read something from the TAP and now need to
+ * send it our via STDOUT. Is that possible at the moment? */
+ if (IOSTATE_READY == std_out->iostate && 0 < tap_read->buffer_size )
+ { /* hand over this buffers content */
+ memcpy (std_out->buffer,
+ tap_read->buffer,
+ MAX_SIZE);
+ std_out->buffer_size = tap_read->buffer_size;
+ std_out->iostate = IOSTATE_READY;
+ tap_read->iostate = IOSTATE_READY;
+ }
+ else if (0 < tap_read->buffer_size)
+ { /* If we have have read our buffer, wait for our write-partner*/
+ tap_read->iostate = IOSTATE_WAITING;
+ // TODO: shall we attempt to fill our bufferm or should we wait
for our write-partner to finish?
+ }
+ }
+ else
+ { /* operation still pending/queued or failed? */
+ int err = GetLastError ();
+ if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err )
+ { /* error occurred, let the rest of the elements finish */
+ tap_read->path_open = FALSE;
+ tap_read->iostate = IOSTATE_FAILED;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static boolean
+attempt_tap_write (HANDLE tap_handle,
+ struct overlapped_facility * tap_write,
+ struct overlapped_facility * std_in)
+{
+ return TRUE;
+}
+
+static boolean
+attempt_std_out ( struct overlapped_facility * std_out,
+ struct overlapped_facility * tap_read)
+{
+ return TRUE;
+}
+
/**
* Initialize a overlapped structure
*
@@ -711,9 +834,10 @@
BOOL signaled)
{
+ elem->path_open = TRUE;
elem->status = initial_state;
elem->iostate = 0;
- elem->buffer_size = MAX_SIZE;
+ elem->buffer_size = 0;
elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL);
if (NULL == elem->overlapped.hEvent)
return FALSE;
@@ -727,13 +851,8 @@
* @param fd_tun tunnel FD
*/
static void
-run (HANDLE handle)
+run (HANDLE tap_handle)
{
- /* read refers to reading from fd_tun, writing to stdout */
- int read_open = 1;
- /* write refers to reading from stdin, writing to fd_tun */
- int write_open = 1;
-
/* IO-Facility for reading from our virtual interface */
struct overlapped_facility tap_read;
/* IO-Facility for writing to our virtual interface */
@@ -750,12 +869,9 @@
* DHCP and such are all features we will never use in gnunet afaik.
* But for openvpn those are essential.
*/
- if (!tun_up (handle))
+ if (!tun_up (tap_handle))
goto teardown;
- if (!)
- goto teardown;
-
/* Initialize our overlapped IO structures*/
if (initialize_overlapped_facility (&tap_read, TRUE, FALSE)
&& initialize_overlapped_facility (&tap_write, FALSE, TRUE)
@@ -776,29 +892,34 @@
// tunnel_point_to_point
// openvpn.c:62
- while ((1 == read_open) || (1 == write_open))
+ while (std_in.path_open
+ || std_out.path_open
+ || tap_read.path_open
+ || tap_write.path_open)
{
+ /* perform READ from stdin if possible */
+ if ((std_in.path_open && tap_write.path_open)
+ || IOSTATE_QUEUED == std_in.iostate)
+ if (!attempt_std_in (&std_in, &tap_write))
+ break;
- /* READ from stdin is possible */
- if (std_in.status)
- {
+ /* perform READ from tap if possible */
+ if ((tap_read.path_open && std_out.path_open)
+ || IOSTATE_QUEUED == tap_read.iostate )
+ if (!attempt_tap_read (tap_handle, &tap_read, &std_out))
+ break;
- }
- /* READ from tap is possible */
- if (tap_read.status)
- {
+ /* perform WRITE to tap if possible */
+ if ( IOSTATE_READY == tap_write.iostate && tap_write.path_open )
+ if (!attempt_tap_write (tap_handle, &tap_write, &std_in))
+ break;
- }
- /* WRITE to tap is possible */
- if (tap_write.status)
- {
-
- }
- /* WRITE to STDOUT is possible */
- if (std_out.status)
- {
-
- }
+ /* perform WRITE to STDOUT if possible */
+ if ( IOSTATE_READY == std_out.iostate && std_out.path_open)
+ if (!attempt_std_out (&std_out, &tap_read))
+ break;
+
+ // check if any path is blocked
}
teardown:
;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r25683 - gnunet/src/vpn,
gnunet <=