[Openvpn-devel] dco-win: use run-time dynamic linking for GetOverlappedResultEx

Message ID 20220820084719.243-1-lstipakov@gmail.com
State Accepted
Headers show
Series [Openvpn-devel] dco-win: use run-time dynamic linking for GetOverlappedResultEx | expand

Commit Message

Lev Stipakov Aug. 19, 2022, 10:47 p.m. UTC
From: Lev Stipakov <lev@openvpn.net>

This function is available starting from Windows 8. Calling it
"as is" causes startup error on Windows 7.

dco-win driver available on Windows 10 20H1 and newer. On older
systems installer will not show nor install the driver and dco-win code
won't be reached. It is safe to load GetOverlappedResultEx in runtime
and exit in case of error.

Signed-off-by: Lev Stipakov <lev@openvpn.net>
---
 src/openvpn/dco_win.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Gert Doering Aug. 19, 2022, 11:29 p.m. UTC | #1
Acked-by: Gert Doering <gert@greenie.muc.de>

I have *not* tested this, but we've discussed the patch on IRC, and the
code matches what we want to achieve.  We've had GetProcAddress() dynamic
resolution in the code before (some IPv6 vs XP/Vista stuff, IIRC) and
this all looks reasonable.  GHA claims it compiles, and Lev said he has
tested on Win7+Win10.

(The intention is "have one single openvpn.exe binary for Win7 + Win10/11,
which will do non-dco stuff on Win7 - no driver - and DCO stuff on 
Win10/11" - much simpler than having to build extra Win7 installers, and
we still want to support Win7 "unless it's getting too costly")

Your patch has been applied to the master branch.

commit 2f8053f9a97584b759d11d05a668d38653508617
Author: Lev Stipakov
Date:   Sat Aug 20 11:47:19 2022 +0300

     dco-win: use run-time dynamic linking for GetOverlappedResultEx

     Signed-off-by: Lev Stipakov <lev@openvpn.net>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20220820084719.243-1-lstipakov@gmail.com>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25038.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering
Gert Doering Aug. 19, 2022, 11:45 p.m. UTC | #2
Hi,

On Sat, Aug 20, 2022 at 11:29:55AM +0200, Gert Doering wrote:
> Acked-by: Gert Doering <gert@greenie.muc.de>
> 
> I have *not* tested this, but we've discussed the patch on IRC, and the
> code matches what we want to achieve.  We've had GetProcAddress() dynamic
> resolution in the code before (some IPv6 vs XP/Vista stuff, IIRC) and
> this all looks reasonable.  GHA claims it compiles, and Lev said he has
> tested on Win7+Win10.
> 
> (The intention is "have one single openvpn.exe binary for Win7 + Win10/11,
> which will do non-dco stuff on Win7 - no driver - and DCO stuff on 
> Win10/11" - much simpler than having to build extra Win7 installers, and
> we still want to support Win7 "unless it's getting too costly")
> 
> Your patch has been applied to the master branch.
> 
> commit 2f8053f9a97584b759d11d05a668d38653508617
> Author: Lev Stipakov
> Date:   Sat Aug 20 11:47:19 2022 +0300

For the sake of transparency, I did a mispush of this commit to 
github+gitlab, with the wrong URL: in the commit message (it was intended
to go to my github instance only).  I fixed this about 3 minutes later
for github, but it took a bit for gitlab.

So, if anyone noticed this commit with the ID 532c006b being in the
repo for a few minutes, this was not a malicious person, just fat fingers.

*No code change* between these revisions, just commit message.

gert

Patch

diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c
index 28bcccd4..a2030866 100644
--- a/src/openvpn/dco_win.c
+++ b/src/openvpn/dco_win.c
@@ -107,6 +107,17 @@  dco_start_tun(struct tuntap *tt)
 static int
 dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, volatile int *signal_received)
 {
+    /* GetOverlappedResultEx is available starting from Windows 8 */
+    typedef BOOL (*get_overlapped_result_ex_t) (HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
+    get_overlapped_result_ex_t get_overlapped_result_ex =
+        (get_overlapped_result_ex_t)GetProcAddress(GetModuleHandle("Kernel32.dll"),
+                                                   "GetOverlappedResultEx");
+
+    if (get_overlapped_result_ex == NULL)
+    {
+        msg(M_ERR, "Failed to load GetOverlappedResult()");
+    }
+
     DWORD timeout_msec = timeout * 1000;
     const int poll_interval_ms = 50;
 
@@ -115,7 +126,7 @@  dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, volatile int *signa
         timeout_msec -= poll_interval_ms;
 
         DWORD transferred;
-        if (GetOverlappedResultEx(handle, ov, &transferred, poll_interval_ms, FALSE) != 0)
+        if (get_overlapped_result_ex(handle, ov, &transferred, poll_interval_ms, FALSE) != 0)
         {
             /* TCP connection established by dco */
             return 0;