[Openvpn-devel,M] Change in openvpn[master]: dco-win: add SET_MODE ioctl call

Message ID df8e347886fc35208153a5319e7dbe25ba937e66-HTML@gerrit.openvpn.net
State New
Headers show
Series [Openvpn-devel,M] Change in openvpn[master]: dco-win: add SET_MODE ioctl call | expand

Commit Message

plaisthos (Code Review) Sept. 6, 2024, 11:27 a.m. UTC
Attention is currently required from: flichtenheld, plaisthos.

Hello plaisthos, flichtenheld,

I'd like you to do a code review.
Please visit

    http://gerrit.openvpn.net/c/openvpn/+/734?usp=email

to review the following change.


Change subject: dco-win: add SET_MODE ioctl call
......................................................................

dco-win: add SET_MODE ioctl call

This is used to set client (OVPN_MODE_P2P, default)
or server (OVPN_MODE_MP) mode. Requires dco driver version >= 2.

Change-Id: Ifec08fea26ff6fd9e22f18cab0ac71c1dda8fe8e
Signed-off-by: Lev Stipakov <lev@openvpn.net>
---
M src/openvpn/dco_win.c
M src/openvpn/ovpn_dco_win.h
2 files changed, 56 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/34/734/1

Patch

diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c
index cf825b3..592cc71 100644
--- a/src/openvpn/dco_win.c
+++ b/src/openvpn/dco_win.c
@@ -93,15 +93,59 @@ 
     return (version->Major > 1) || (version->Minor >= 4);
 }
 
+static inline
+bool
+dco_version_supports_mp(OVPN_VERSION *version)
+{
+    return version->Major >= 2;
+}
+
+bool
+dco_set_mode(dco_context_t *dco, int mode)
+{
+    msg(D_DCO_DEBUG, "%s: mode %d", __func__, mode);
+
+    OVPN_MODE ovpn_mode;
+    switch (mode)
+    {
+        case CM_TOP:
+            ovpn_mode = OVPN_MODE_MP;
+            break;
+
+        case CM_P2P:
+            ovpn_mode = OVPN_MODE_P2P;
+            break;
+
+        default:
+            ASSERT(false);
+    }
+
+    DWORD bytes_returned = 0;
+    if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_SET_MODE, &ovpn_mode,
+                         sizeof(ovpn_mode), NULL, 0, &bytes_returned, NULL))
+    {
+        msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_SET_MODE) failed");
+        return -1;
+    }
+    return 0;
+}
+
 bool
 ovpn_dco_init(int mode, dco_context_t *dco)
 {
+    int res = true;
+
     dco_get_version(&dco->version);
+
     dco->supports_data_v3 = dco_version_supports_data_v3(&dco->version);
+    if (dco_version_supports_mp(&dco->version))
+    {
+        res = dco_set_mode(dco, mode);
+    }
 
-    msg(D_DCO_DEBUG, "dco data_v3: %d", dco->supports_data_v3);
+    msg(D_DCO_DEBUG, "dco mode: %d, data_v3: %d", mode, dco->supports_data_v3);
 
-    return true;
+    return res;
 }
 
 int
diff --git a/src/openvpn/ovpn_dco_win.h b/src/openvpn/ovpn_dco_win.h
index 9e437f0..8163b8b 100644
--- a/src/openvpn/ovpn_dco_win.h
+++ b/src/openvpn/ovpn_dco_win.h
@@ -114,6 +114,15 @@ 
     LONG Patch;
 } OVPN_VERSION, * POVPN_VERSION;
 
+typedef enum {
+    OVPN_MODE_P2P,
+    OVPN_MODE_MP
+} OVPN_MODE;
+
+typedef struct _OVPN_SET_MODE {
+    OVPN_MODE Mode;
+} OVPN_SET_MODE, * POVPN_SET_MODE;
+
 #define OVPN_IOCTL_NEW_PEER     CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define OVPN_IOCTL_GET_STATS    CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define OVPN_IOCTL_NEW_KEY      CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
@@ -123,3 +132,4 @@ 
 #define OVPN_IOCTL_DEL_PEER     CTL_CODE(FILE_DEVICE_UNKNOWN, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define OVPN_IOCTL_GET_VERSION  CTL_CODE(FILE_DEVICE_UNKNOWN, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define OVPN_IOCTL_NEW_KEY_V2   CTL_CODE(FILE_DEVICE_UNKNOWN, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define OVPN_IOCTL_SET_MODE     CTL_CODE(FILE_DEVICE_UNKNOWN, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)