Windows support
David Woodhouse
dwmw2 at infradead.org
Mon Feb 10 11:28:11 EST 2014
I've now managed to get this actually passing packets, albeit
sporadically.
Nikos, I wonder if GnuTLS should be accepting EWOULDBLOCK on a read from
a non-blocking socket and treating it the same as EAGAIN? See
http://git.infradead.org/users/dwmw2/openconnect.git/commitdiff/b5df97e74b
I've committed the code to find and open the tun device (using the
latest one from OpenVPN, which does actually support tun mode).
What I haven't committed is anything to actually read/write the tun
device. That's in the patch below, but it's only barely function. The
problem is that Windows is crap and you can't just open the tun device,
get a file descriptor for it, and select() on that. We're probably going
to have to do the reads from the tun device in a thread and then wake
the main thread (perhaps via a socketpair).
The alternative is to revamp the whole of the event processing to allow
us to make it work with real Windows events, and I think that's just a
step too far.
So this patch works, except that it keeps blocking on reading from the
tun device when there isn't a packet to be read. I've only tested it
with Legacy IP, not IPv6.
The other issue is that I haven't worked out how to configure the
device. The 'netsh' command lines that vpnc and openvpn attempt to use
are failing here with a confusing 'Element not found' error. I went
through the GUI to *manually* configure the device with the IP addresses
for my test connection, but we need to find a correct fix.
diff --git a/tun.c b/tun.c
index 1fcb19f..5ad0a96 100644
--- a/tun.c
+++ b/tun.c
@@ -723,8 +723,8 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
prefix_size = sizeof(int);
#endif
- if (FD_ISSET(vpninfo->tun_fd, &vpninfo->select_rfds)) {
- while (1) {
+ if (1 || FD_ISSET(vpninfo->tun_fd, &vpninfo->select_rfds)) {
+ while (!work_done) {
int len = vpninfo->ip_info.mtu;
if (!out_pkt) {
@@ -734,8 +734,23 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
break;
}
}
-
+#ifdef _WIN32
+ { DWORD got;
+ printf("reading...\n");
+ if (!ReadFile(vpninfo->tun_fh, out_pkt->data - prefix_size, len + prefix_size, &got, NULL)) {
+ DWORD err = GetLastError();
+ vpn_progress(vpninfo, PRG_ERR,
+ _("Failed to read from to TAP device: %lx\n"), err);
+ break;
+ }
+ else printf("got %d: %02x %02x %02x %02x %02x %02x %02x %02x\n", got,
+ out_pkt->data[0], out_pkt->data[1], out_pkt->data[2], out_pkt->data[3],
+ out_pkt->data[4], out_pkt->data[5], out_pkt->data[6], out_pkt->data[7]);
+ len = got;
+ }
+#else
len = read(vpninfo->tun_fd, out_pkt->data - prefix_size, len + prefix_size);
+#endif
if (len <= prefix_size)
break;
out_pkt->len = len - prefix_size;
@@ -794,7 +809,19 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
}
#endif
vpninfo->incoming_queue = this->next;
+#ifdef _WIN32
+ {
+ DWORD wrote;
+ if (!WriteFile(vpninfo->tun_fh, data, len, &wrote, NULL)) {
+ DWORD err = GetLastError();
+
+ vpn_progress(vpninfo, PRG_ERR,
+ _("Failed to write to TAP device: %lx\n"), err);
+ }
+ else printf("wrote %d\n", wrote);
+ }
+#else
if (write(vpninfo->tun_fd, data, len) < 0) {
/* Handle death of "script" socket */
if (vpninfo->script_tun && errno == ENOTCONN) {
@@ -805,6 +832,7 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
_("Failed to write incoming packet: %s\n"),
strerror(errno));
}
+#endif
free(this);
}
/* Work is not done if we just got rid of packets off the queue */
--
dwmw2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20140210/2674fb05/attachment.bin>
More information about the openconnect-devel
mailing list