Skip to contentSkip to conversation

Fix Building Using MSVC

PATCH In review Eric Thorpe 4 participants 7 messages Mar 13, 2017 – Mar 16, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix Building Using MSVC

This patch enables the building of OpenVPN for the 2.4 and master branches using MSVC (Visual Studio 2013 / MSVC v120), which currently doesn't work with 2.4 or a clone of master. 2013 is being used as it reduces the complexity of the redistributable requirements and has mostly complete C99 support. Further changes will be necessary for 2015 support when the switch is made.

Note the changes to config-msvc-version.h.in are more of a work around. It was a simpler approach when compared to modifying msvc-generate.js to handle m4 syntax, and so it may be dropped if there is an intention to update the javascript generator.

Signed-off by: Eric Thorpe <[email protected]...>
---

config-msvc-version.h.in +6 -2
index 4bc89e7..7977cb8 100644
@@ -1,8 +1,12 @@
 #define PACKAGE_NAME "@PRODUCT_NAME@"
-#define PACKAGE_STRING "@PRODUCT_NAME@ @PRODUCT_VERSION@"
+#define PACKAGE_STRING "@PRODUCT_NAME@ @[email protected]...@PRODUCT_VERSION_MINOR@@PRODUCT_VERSION_PATCH@"
 #define PACKAGE_TARNAME "@PRODUCT_TARNAME@"
 #define PACKAGE "@PRODUCT_TARNAME@"
-#define PACKAGE_VERSION "@PRODUCT_VERSION@"
+#define PRODUCT_VERSION_MAJOR "@PRODUCT_VERSION_MAJOR@"
+#define PRODUCT_VERSION_MINOR "@PRODUCT_VERSION_MINOR@"
+#define PRODUCT_VERSION_PATCH "@PRODUCT_VERSION_PATCH@"
+#define PACKAGE_VERSION "@[email protected]...@[email protected]...@PRODUCT_VERSION_PATCH@"
+#define PRODUCT_VERSION "@[email protected]...@[email protected]...@PRODUCT_VERSION_PATCH@"
 #define PRODUCT_BUGREPORT "@PRODUCT_BUGREPORT@"
 #define OPENVPN_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@
 #define TAP_WIN_COMPONENT_ID "@PRODUCT_TAP_WIN_COMPONENT_ID@"
config-msvc.h +1 -0
index 3e71c85..9b97e71 100644
@@ -126,6 +126,7 @@ typedef __int64 int64_t;
 typedef __int32 int32_t;
 typedef __int16 int16_t;
 typedef __int8 int8_t;
+typedef uint16_t in_port_t;
 
 #ifdef HAVE_CONFIG_MSVC_LOCAL_H
 #include <config-msvc-local.h>
src/openvpn/crypto_openssl.c +5 -0
index 5549d70..bed39f3 100644
@@ -287,7 +287,12 @@ show_available_ciphers()
 
     /* If we ever exceed this, we must be more selective */
     const size_t cipher_list_len = 1000;
+#ifdef _MSC_VER
+    //While GCC will allow you to use a const, MSVC won't (at least with a simple declaration). Use a compile time constant for now
+    const EVP_CIPHER *cipher_list[1000];
+#else
     const EVP_CIPHER *cipher_list[cipher_list_len];
+#endif
     size_t num_ciphers = 0;
 #ifndef ENABLE_SMALL
     printf("The following ciphers and cipher modes are available for 

use\n"

src/openvpn/openvpn.vcxproj +8 -1
index 8dfbea5..e8a48e2 100644
@@ -99,13 +99,16 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="argv.c" />
     <ClCompile Include="base64.c" />
+    <ClCompile Include="block_dns.c" />
     <ClCompile Include="buffer.c" />
     <ClCompile Include="clinat.c" />
     <ClCompile Include="comp-lz4.c" />
     <ClCompile Include="comp.c" />
     <ClCompile Include="compstub.c" />
     <ClCompile Include="console.c" />
+    <ClCompile Include="console_builtin.c" />
     <ClCompile Include="crypto.c" />
     <ClCompile Include="crypto_openssl.c" />
     <ClCompile Include="cryptoapi.c" />
@@ -164,12 +167,15 @@
     <ClCompile Include="ssl_verify.c" />
     <ClCompile Include="ssl_verify_openssl.c" />
     <ClCompile Include="status.c" />
+    <ClCompile Include="tls_crypt.c" />
     <ClCompile Include="tun.c" />
     <ClCompile Include="win32.c" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="argv.h" />
     <ClInclude Include="base64.h" />
     <ClInclude Include="basic.h" />
+    <ClInclude Include="block_dns.h" />
     <ClInclude Include="buffer.h" />
     <ClInclude Include="circ_list.h" />
     <ClInclude Include="clinat.h" />
@@ -249,6 +255,7 @@
     <ClInclude Include="ssl_verify_openssl.h" />
     <ClInclude Include="status.h" />
     <ClInclude Include="syshead.h" />
+    <ClInclude Include="tls_crypt.h" />
     <ClInclude Include="tun.h" />
     <ClInclude Include="win32.h" />
   </ItemGroup>
@@ -268,4 +275,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
src/openvpn/openvpn.vcxproj.filters +25 -1
index 8b6a269..30df5ec 100644
@@ -216,6 +216,18 @@
     <ClCompile Include="comp-lz4.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="argv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="block_dns.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="console_builtin.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tls_crypt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="base64.h">
@@ -464,10 +476,22 @@
     <ClInclude Include="win32.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="compstub.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="argv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="block_dns.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tls_crypt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="openvpn_win32_resources.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
src/openvpn/ssl_openssl.h +4 -0
index c64c65f..a974e7e 100644
@@ -49,7 +49,11 @@
  */
 struct tls_root_ctx {
     SSL_CTX *ctx;
+#ifdef _MSC_VER
+    struct timeval crl_last_mtime;
+#else
     struct timespec crl_last_mtime;
+#endif
     off_t crl_last_size;
 };
 
#1 lore raw

Hi,

thanks for your patch. I'm not exactly happy with it for a number of reasons, but it's a good way to get started.

Details...

On Tue, Mar 14, 2017 at 09:26:52AM +1100, Eric Thorpe wrote:
[..]

config-msvc-version.h.in

Quoted 4 lines
config-msvc-version.h.in +0 -0
index 4bc89e7..7977cb8 100644

I can't comment on these changes, but I assume that's "funny macro handling" related... and since it's MSVC only, the risk of breaking anything else is small.

config-msvc.h typedef __int64 int64_t; · line 129

Quoted 9 lines
config-msvc.h +1 -0
index 3e71c85..9b97e71 100644
@@ -126,6 +126,7 @@ typedef __int64 int64_t;
  typedef __int32 int32_t;
  typedef __int16 int16_t;
  typedef __int8 int8_t;
+typedef uint16_t in_port_t;

The indenting of that chunk looks a bit weird (extra space at the beginning of the context lines) but that's easily sorted manually.

Quoted 13 lines
config-msvc.h +0 -0
  #ifdef HAVE_CONFIG_MSVC_LOCAL_H
  #include <config-msvc-local.h>
src/openvpn/crypto_openssl.c +2 -0
index 5549d70..bed39f3 100644
@@ -287,7 +287,12 @@ show_available_ciphers()
 
      /* If we ever exceed this, we must be more selective */
      const size_t cipher_list_len = 1000;
+#ifdef _MSC_VER
+    //While GCC will allow you to use a const, MSVC won't (at least 

with a simple declaration). Use a compile time constant for now

src/openvpn/crypto_openssl.c show_available_ciphers() · line 296

Quoted 5 lines
src/openvpn/crypto_openssl.c +3 -0
+    const EVP_CIPHER *cipher_list[1000];
+#else
      const EVP_CIPHER *cipher_list[cipher_list_len];
+#endif
      size_t num_ciphers = 0;

I don't think we should do this. If we have a length, use it. If the compiler is too daft to understand consts, maybe we should go for "#define CIPHER_LIST_LEN 1000" instead - indeed, more changes, but no magic numbers. Or abandon the definition, use [1000], and sizeof() in the out of bounds check below.

Steffan, your code, what would you say?

Style-wise: please do not use C++ comments, and break long lines.

src/openvpn/openvpn.vcxproj line 104

Quoted 9 lines
src/openvpn/openvpn.vcxproj +2 -0
@@ -99,13 +99,16 @@
      </Link>
    </ItemDefinitionGroup>
    <ItemGroup>
+    <ClCompile Include="argv.c" />
      <ClCompile Include="base64.c" />
+    <ClCompile Include="block_dns.c" />

Yeah. Oversight when we added new modules - these are easy enough :-)

Quoted 5 lines
src/openvpn/ssl_openssl.h +0 -0
index c64c65f..a974e7e 100644

src/openvpn/ssl_openssl.h line 58

Quoted 10 lines
src/openvpn/ssl_openssl.h +4 -0
@@ -49,7 +49,11 @@
   */
  struct tls_root_ctx {
      SSL_CTX *ctx;
+#ifdef _MSC_VER
+    struct timeval crl_last_mtime;
+#else
      struct timespec crl_last_mtime;
+#endif
      off_t crl_last_size;
  };

We should not do this. It's not your fault for finding this, but having looked at the code to understand why this would be fixing things, I wonder why we're using a "struct timespec" in the first place, or why we're having a structure "with subseconds" in there when all we use is the "seconds" bit *because* "windows has no nanoseconds"...

src/openvpn/ssl.c

    /*
     * Store the CRL if this is the first time or if the file was changed since
     * the last load.
     * Note: Windows does not support tv_nsec.
     */
    if ((ssl_ctx->crl_last_size == crl_stat.st_size)
        && (ssl_ctx->crl_last_mtime.tv_sec == crl_stat.st_mtime))
...
    ssl_ctx->crl_last_mtime.tv_sec = crl_stat.st_mtime;
    ssl_ctx->crl_last_size = crl_stat.st_size;

Antonio, this is your code - how shall we handle this?

Today, we only use seconds, so "struct timeval" on all platforms would be good enough. Some platforms' "struct stat" actually has a st_mtim which is a "struct timespec" (and st_mtime is defined as st_mtim.tv_sec), so if we ever go for subsecond accuracy, timespec is the right thing to do - OTOH, that will need at least one extra configure test, given how various OSes <sys/stat.h> weasle around "struct timespec"...

#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0) >= 700 || \
defined(_NETBSD_SOURCE)
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last data modification */
struct timespec st_ctim; /* time of last file status change */
struct timespec st_birthtim; /* time of creation */
#else

        time_t    st_atime;             /* time of last access */
        long      st_atimensec;         /* nsec of last access */
        time_t    st_mtime;             /* time of last data modification */
        long      st_mtimensec;         /* nsec of last data modification */

...

So, it might be worth considering just dropping the notion of interest in subseconds, and go for a plain "time_t" for "crl_last_mtime"... (slightly more code changes, but less portability hassle).

Again, Antonio, your call...

Eric, could you re-send the patch without the crypto_openssl.c and ssl_openssl.h hunks? I could merge the rest while Steffan and Antonio ponder these changes...

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#2 lore raw

Hi,

Quoted 26 lines · Gert Doering
Quoted 13 lines · Eric Thorpe
  #ifdef HAVE_CONFIG_MSVC_LOCAL_H
  #include <config-msvc-local.h>
src/openvpn/crypto_openssl.c +2 -0
index 5549d70..bed39f3 100644
@@ -287,7 +287,12 @@ show_available_ciphers()
 
      /* If we ever exceed this, we must be more selective */
      const size_t cipher_list_len = 1000;
+#ifdef _MSC_VER
+    //While GCC will allow you to use a const, MSVC won't (at least 

with a simple declaration). Use a compile time constant for now

src/openvpn/crypto_openssl.c show_available_ciphers() · line 296

Quoted 5 lines
src/openvpn/crypto_openssl.c +3 -0
+    const EVP_CIPHER *cipher_list[1000];
+#else
      const EVP_CIPHER *cipher_list[cipher_list_len];
+#endif
      size_t num_ciphers = 0;

I don't think we should do this. If we have a length, use it. If the compiler is too daft to understand consts, maybe we should go for "#define CIPHER_LIST_LEN 1000" instead - indeed, more changes, but no magic numbers. Or abandon the definition, use [1000], and sizeof() in the out of bounds check below.

Quoted 1 line

Steffan, your code, what would you say?

Hm, this is somewhat chewing on our decision that 'we now only support compilers that do C99', but I can see that this is easily fixed so I can live with just begin pragmatic. In that case, let's go for the sizeof(). Adding a define of course works, but I find it somewhat clunky.

-Steffan

#3 lore raw
In reply to Gert Doering

Hi,

Patch below with the requested hunks removed.

Signed-off by: Eric Thorpe <[email protected]...>

config-msvc-version.h.in +6 -2
index 4bc89e7..7977cb8 100644
@@ -1,8 +1,12 @@
 #define PACKAGE_NAME "@PRODUCT_NAME@"
-#define PACKAGE_STRING "@PRODUCT_NAME@ @PRODUCT_VERSION@"
+#define PACKAGE_STRING "@PRODUCT_NAME@ @[email protected]...@PRODUCT_VERSION_MINOR@@PRODUCT_VERSION_PATCH@"
 #define PACKAGE_TARNAME "@PRODUCT_TARNAME@"
 #define PACKAGE "@PRODUCT_TARNAME@"
-#define PACKAGE_VERSION "@PRODUCT_VERSION@"
+#define PRODUCT_VERSION_MAJOR "@PRODUCT_VERSION_MAJOR@"
+#define PRODUCT_VERSION_MINOR "@PRODUCT_VERSION_MINOR@"
+#define PRODUCT_VERSION_PATCH "@PRODUCT_VERSION_PATCH@"
+#define PACKAGE_VERSION "@[email protected]...@[email protected]...@PRODUCT_VERSION_PATCH@"
+#define PRODUCT_VERSION "@[email protected]...@[email protected]...@PRODUCT_VERSION_PATCH@"
 #define PRODUCT_BUGREPORT "@PRODUCT_BUGREPORT@"
 #define OPENVPN_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@
 #define TAP_WIN_COMPONENT_ID "@PRODUCT_TAP_WIN_COMPONENT_ID@"
config-msvc.h +1 -0
index 3e71c85..9b97e71 100644
@@ -126,6 +126,7 @@ typedef __int64 int64_t;
 typedef __int32 int32_t;
 typedef __int16 int16_t;
 typedef __int8 int8_t;
+typedef uint16_t in_port_t;
 
 #ifdef HAVE_CONFIG_MSVC_LOCAL_H
 #include <config-msvc-local.h>
src/openvpn/openvpn.vcxproj +8 -1
index 8dfbea5..e8a48e2 100644
@@ -99,13 +99,16 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="argv.c" />
     <ClCompile Include="base64.c" />
+    <ClCompile Include="block_dns.c" />
     <ClCompile Include="buffer.c" />
     <ClCompile Include="clinat.c" />
     <ClCompile Include="comp-lz4.c" />
     <ClCompile Include="comp.c" />
     <ClCompile Include="compstub.c" />
     <ClCompile Include="console.c" />
+    <ClCompile Include="console_builtin.c" />
     <ClCompile Include="crypto.c" />
     <ClCompile Include="crypto_openssl.c" />
     <ClCompile Include="cryptoapi.c" />
@@ -164,12 +167,15 @@
     <ClCompile Include="ssl_verify.c" />
     <ClCompile Include="ssl_verify_openssl.c" />
     <ClCompile Include="status.c" />
+    <ClCompile Include="tls_crypt.c" />
     <ClCompile Include="tun.c" />
     <ClCompile Include="win32.c" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="argv.h" />
     <ClInclude Include="base64.h" />
     <ClInclude Include="basic.h" />
+    <ClInclude Include="block_dns.h" />
     <ClInclude Include="buffer.h" />
     <ClInclude Include="circ_list.h" />
     <ClInclude Include="clinat.h" />
@@ -249,6 +255,7 @@
     <ClInclude Include="ssl_verify_openssl.h" />
     <ClInclude Include="status.h" />
     <ClInclude Include="syshead.h" />
+    <ClInclude Include="tls_crypt.h" />
     <ClInclude Include="tun.h" />
     <ClInclude Include="win32.h" />
   </ItemGroup>
@@ -268,4 +275,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
src/openvpn/openvpn.vcxproj.filters +25 -1
index 8b6a269..30df5ec 100644
@@ -216,6 +216,18 @@
     <ClCompile Include="comp-lz4.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="argv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="block_dns.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="console_builtin.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tls_crypt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="base64.h">
@@ -464,10 +476,22 @@
     <ClInclude Include="win32.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="compstub.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="argv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="block_dns.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tls_crypt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="openvpn_win32_resources.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
Quoted 141 lines · Gert Doering

Hi,

thanks for your patch. I'm not exactly happy with it for a number of reasons, but it's a good way to get started.

Details...

On Tue, Mar 14, 2017 at 09:26:52AM +1100, Eric Thorpe wrote:
[..]

config-msvc-version.h.in

Quoted 4 lines
config-msvc-version.h.in +0 -0
index 4bc89e7..7977cb8 100644

I can't comment on these changes, but I assume that's "funny macro handling" related... and since it's MSVC only, the risk of breaking anything else is small.

config-msvc.h typedef __int64 int64_t; · line 129

Quoted 9 lines
config-msvc.h +1 -0
index 3e71c85..9b97e71 100644
@@ -126,6 +126,7 @@ typedef __int64 int64_t;
   typedef __int32 int32_t;
   typedef __int16 int16_t;
   typedef __int8 int8_t;
+typedef uint16_t in_port_t;

The indenting of that chunk looks a bit weird (extra space at the beginning of the context lines) but that's easily sorted manually.

Quoted 13 lines
config-msvc.h +0 -0
   #ifdef HAVE_CONFIG_MSVC_LOCAL_H
   #include <config-msvc-local.h>
src/openvpn/crypto_openssl.c +2 -0
index 5549d70..bed39f3 100644
@@ -287,7 +287,12 @@ show_available_ciphers()
 
       /* If we ever exceed this, we must be more selective */
       const size_t cipher_list_len = 1000;
+#ifdef _MSC_VER
+    //While GCC will allow you to use a const, MSVC won't (at least

with a simple declaration). Use a compile time constant for now

src/openvpn/crypto_openssl.c

Quoted 5 lines
src/openvpn/crypto_openssl.c +3 -0
+    const EVP_CIPHER *cipher_list[1000];
+#else
       const EVP_CIPHER *cipher_list[cipher_list_len];
+#endif
       size_t num_ciphers = 0;

I don't think we should do this. If we have a length, use it. If the compiler is too daft to understand consts, maybe we should go for "#define CIPHER_LIST_LEN 1000" instead - indeed, more changes, but no magic numbers. Or abandon the definition, use [1000], and sizeof() in the out of bounds check below.

Steffan, your code, what would you say?

Style-wise: please do not use C++ comments, and break long lines.

src/openvpn/openvpn.vcxproj line 104

Quoted 9 lines
src/openvpn/openvpn.vcxproj +2 -0
@@ -99,13 +99,16 @@
       </Link>
     </ItemDefinitionGroup>
     <ItemGroup>
+    <ClCompile Include="argv.c" />
       <ClCompile Include="base64.c" />
+    <ClCompile Include="block_dns.c" />

Yeah. Oversight when we added new modules - these are easy enough :-)

Quoted 5 lines
src/openvpn/ssl_openssl.h +0 -0
index c64c65f..a974e7e 100644

src/openvpn/ssl_openssl.h line 58

Quoted 10 lines
src/openvpn/ssl_openssl.h +4 -0
@@ -49,7 +49,11 @@
    */
   struct tls_root_ctx {
       SSL_CTX *ctx;
+#ifdef _MSC_VER
+    struct timeval crl_last_mtime;
+#else
       struct timespec crl_last_mtime;
+#endif
       off_t crl_last_size;
   };

We should not do this. It's not your fault for finding this, but having looked at the code to understand why this would be fixing things, I wonder why we're using a "struct timespec" in the first place, or why we're having a structure "with subseconds" in there when all we use is the "seconds" bit *because* "windows has no nanoseconds"...

src/openvpn/ssl.c

     /*
      * Store the CRL if this is the first time or if the file was changed since
      * the last load.
      * Note: Windows does not support tv_nsec.
      */
     if ((ssl_ctx->crl_last_size == crl_stat.st_size)
         && (ssl_ctx->crl_last_mtime.tv_sec == crl_stat.st_mtime))
...
     ssl_ctx->crl_last_mtime.tv_sec = crl_stat.st_mtime;
     ssl_ctx->crl_last_size = crl_stat.st_size;

Antonio, this is your code - how shall we handle this?

Today, we only use seconds, so "struct timeval" on all platforms would be good enough. Some platforms' "struct stat" actually has a st_mtim which is a "struct timespec" (and st_mtime is defined as st_mtim.tv_sec), so if we ever go for subsecond accuracy, timespec is the right thing to do - OTOH, that will need at least one extra configure test, given how various OSes <sys/stat.h> weasle around "struct timespec"...

#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0) >= 700 || \
defined(_NETBSD_SOURCE)
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last data modification */
struct timespec st_ctim; /* time of last file status change */
struct timespec st_birthtim; /* time of creation */
#else

         time_t    st_atime;             /* time of last access */
         long      st_atimensec;         /* nsec of last access */
         time_t    st_mtime;             /* time of last data modification */
         long      st_mtimensec;         /* nsec of last data modification */

...

So, it might be worth considering just dropping the notion of interest in subseconds, and go for a plain "time_t" for "crl_last_mtime"... (slightly more code changes, but less portability hassle).

Again, Antonio, your call...

Eric, could you re-send the patch without the crypto_openssl.c and ssl_openssl.h hunks? I could merge the rest while Steffan and Antonio ponder these changes...

gert

#4 lore raw

ACK, thanks.

Your patch has been applied to the master and release/2.4 branch.

I've taken the commit message from v1 so there's a bit more explanation.

Also, I had to fix quite a bit of whitespace changes - lines in the config-msvc-version.h patch got wrapped, and all context lines got a extra blank in front. So whatever client you used to send the patch with, please use "git send-email" instead :-)

Patch from Antonio for the "timespec" issue is coming in...

commit 5ab106db7b091c6409fd0a7e43f557a7931c200f (master) commit 3fa863100033e7d6d0cbb19361a52efbe097e69d (release/2.4)

Author: Eric Thorpe
Date:   Thu Mar 16 09:40:31 2017 +1100
     Fix Building Using MSVC

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg14268.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#5 lore raw
In reply to Gert Doering
Quoted 57 lines · Gert Doering
Quoted 5 lines
src/openvpn/ssl_openssl.h +0 -0
index c64c65f..a974e7e 100644

src/openvpn/ssl_openssl.h line 58

Quoted 10 lines
src/openvpn/ssl_openssl.h +4 -0
@@ -49,7 +49,11 @@
   */
  struct tls_root_ctx {
      SSL_CTX *ctx;
+#ifdef _MSC_VER
+    struct timeval crl_last_mtime;
+#else
      struct timespec crl_last_mtime;
+#endif
      off_t crl_last_size;
  };

We should not do this. It's not your fault for finding this, but having looked at the code to understand why this would be fixing things, I wonder why we're using a "struct timespec" in the first place, or why we're having a structure "with subseconds" in there when all we use is the "seconds" bit *because* "windows has no nanoseconds"...

src/openvpn/ssl.c

    /*
     * Store the CRL if this is the first time or if the file was changed since
     * the last load.
     * Note: Windows does not support tv_nsec.
     */
    if ((ssl_ctx->crl_last_size == crl_stat.st_size)
        && (ssl_ctx->crl_last_mtime.tv_sec == crl_stat.st_mtime))
...
    ssl_ctx->crl_last_mtime.tv_sec = crl_stat.st_mtime;
    ssl_ctx->crl_last_size = crl_stat.st_size;

Antonio, this is your code - how shall we handle this?

Today, we only use seconds, so "struct timeval" on all platforms would be good enough. Some platforms' "struct stat" actually has a st_mtim which is a "struct timespec" (and st_mtime is defined as st_mtim.tv_sec), so if we ever go for subsecond accuracy, timespec is the right thing to do - OTOH, that will need at least one extra configure test, given how various OSes <sys/stat.h> weasle around "struct timespec"...

#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0) >= 700 || \
defined(_NETBSD_SOURCE)
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last data modification */
struct timespec st_ctim; /* time of last file status change */
struct timespec st_birthtim; /* time of creation */
#else

        time_t    st_atime;             /* time of last access */
        long      st_atimensec;         /* nsec of last access */
        time_t    st_mtime;             /* time of last data modification */
        long      st_mtimensec;         /* nsec of last data modification */
Quoted 8 lines

...

So, it might be worth considering just dropping the notion of interest in subseconds, and go for a plain "time_t" for "crl_last_mtime"... (slightly more code changes, but less portability hassle).

Again, Antonio, your call...

thanks for pointing this out.
IMHO we could go for time_t and get rid of timespec at all.
struct timespec was version in the first version of my patch, but it lost sense once it was discovered that we can't easily support subsecond units on every platform.

If there is no objection, I'll send a patch for this.

Cheers,

Signature · 1 line
Antonio Quartulli
#6 lore raw

Hi,

Quoted 1 line · Antonio Quartulli

If there is no objection, I'll send a patch for this.

Please do. We only check seconds today anyway - plus file size(!), so I'm not really seeing a scenario where a CRL file gets refreshed more than once per second but the file size staying the same...

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...