Skip to contentSkip to conversation

fix building for WIN32

PATCH NAK Heiko Hund 4 participants 15 messages Aug 10, 2011 – Sep 2, 2011

lore
Share & tools
lore

Heiko Hund

author
#0 lore raw

cover fix building for WIN32

Hi,

git master currently fails when cross compiling for WIN32 in Debian testing. Two IPv6 related things were introduced in commits

512cda46b0f65f388e24436cd28d44bdc90fe985 and
8335caf929f21b317a0243a12285e1f04361db25

that are incompatible with Windows. IN6_ARE_ADDR_EQUAL and struct in6_addr.s6_addr32 are not available there.

While MinGW added both features to ws2tcpip.h, the Microsoft Platform SDK headers do not include them and they are (correctly) missing in the MinGW-w64 headers as well.

Following are two patches that try to fix these issues.

Heiko Hund (2):
define IN6_ARE_ADDR_EQUAL macro for WIN32 don't use struct in6_addr s6_addr32 member anymore

 socket.c |   16 +++++++---------
 win32.h  |   13 +++++++++++++
 2 files changed, 20 insertions(+), 9 deletions(-)

Regards
Heiko

Signature · 1 line
1.7.5.4
author
#1 lore raw

PATCH 1/2 define IN6_ARE_ADDR_EQUAL macro for WIN32

Windows headers do not define the IN6_ARE_ADDR_EQUAL macro. It needs to be defined locally when building for WIN32 with IPv6 enabled.

---
 win32.h |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)
win32.h +13 -0
index d0ecc85..907aaa2 100644
@@ -41,6 +41,19 @@
  * development environment.
  */
 
+#ifdef USE_PF_INET6
+
+/* MSVC headers do not define this macro, so do it here */
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+    ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
+  && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
+  && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
+  && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
+#endif
+
+#endif
+
 void init_win32 (void);
 void uninit_win32 (void);
 
Signature · 1 line
1.7.5.4
#2 lore raw

Re: [Openvpn-devel] [PATCH 1/2] define IN6_ARE_ADDR_EQUAL macro for WIN32

win32.h line 53

Quoted 7 lines · Heiko Hund
win32.h +7 -0
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+    ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
+  && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
+  && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
+  && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
+#endif

A little more readable:

 #define IN6_ARE_ADDR_EQUAL(a, b)   \
             (!memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)))

(almost the same as in MingW's <ws2tcpip.h>).

--gv

author
#3 lore raw

Re: [Openvpn-devel] [PATCH 1/2] define IN6_ARE_ADDR_EQUAL macro for WIN32

Quoted 10 lines · On Wednesday 10 August 2011 15:47:36 Gisle Vanem wrote:

win32.h line 53

Quoted 7 lines · Heiko Hund
win32.h +7 -0
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+    ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
+  && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
+  && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
+  && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
+#endif

A little more readable:

Quoted 5 lines
  #define IN6_ARE_ADDR_EQUAL(a, b)   \
              (!memcmp ((const void*)(a), (const void*)(b), sizeof (struct

in6_addr)))

(almost the same as in MingW's <ws2tcpip.h>).

The version I posted is taken from eglibc 2.13 on Debian testing, by the way.

Heiko

Signature · 8 lines
Heiko Hund | Software Engineer | Phone +49-721-25516-237 | Fax -200
Astaro a Sophos Company | Amalienbadstr. 41 Bau 52 | 76227 Karlsruhe | Germany
Commercial Register: Mannheim HRA 702710 | Headquarter Location: Karlsruhe
 
Represented by the General Partner Astaro Verwaltungs GmbH
Amalienbadstraße 41 Bau 52 | 76227 Karlsruhe | Germany 
Commercial Register: Mannheim HRB 708248 | Executive Board: Gert Hansen,
Markus Hennig, Jan Hichert, Günter Junk, Dr. Frank Nellissen
#4 lore raw

Re: [Openvpn-devel] [PATCH 1/2] define IN6_ARE_ADDR_EQUAL macro for WIN32

In reply to Gisle Vanem

Hi,

Quoted 11 lines · Gisle Vanem

win32.h line 53

Quoted 7 lines · Heiko Hund
win32.h +7 -0
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+    ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
+  && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
+  && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
+  && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
+#endif

A little more readable:

Quoted 2 lines
  #define IN6_ARE_ADDR_EQUAL(a, b)   \
              (!memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)))

... and guaranteed to be safe regarding alignment... so I like the second one better.

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]...
author
#5 lore raw

PATCH 1/2 define IN6_ARE_ADDR_EQUAL macro for WIN32

In reply to Heiko Hund

Windows headers do not define the IN6_ARE_ADDR_EQUAL macro. It needs to be defined locally when building for WIN32 with IPv6 enabled.

---
 win32.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)
win32.h +10 -0
index d0ecc85..87d8ecc 100644
@@ -41,6 +41,16 @@
  * development environment.
  */
 
+#ifdef USE_PF_INET6
+
+/* MSVC headers do not define this macro, so do it here */
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+  (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0)
+#endif
+
+#endif
+
 void init_win32 (void);
 void uninit_win32 (void);
 
Signature · 1 line
1.7.5.4
#6 lore raw

Re: [Openvpn-devel] [PATCH 1/2] define IN6_ARE_ADDR_EQUAL macro for WIN32

Hi,

win32.h line 52

Quoted 9 lines · Heiko Hund
win32.h +9 -0
+#ifdef USE_PF_INET6
+
+/* MSVC headers do not define this macro, so do it here */
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+  (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0)
+#endif
+
+#endif

ACK!

(This way is easier to read).

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]...
author
#7 lore raw

[Openvpn-devel] [PATCH-UPDATE] define IN6_ARE_ADDR_EQUAL macro for WIN32

In reply to Heiko Hund

Windows headers do not define the IN6_ARE_ADDR_EQUAL macro. It needs to be defined locally when building for WIN32.

Update: remove check for USE_PF_INET6 since commit eb23089183745853fac9414d45a559a478ef51d6 removed the definition of this macro. IPv6 is now always compiled in.

---
 win32.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
win32.h +6 -0
index 528af6c..5b18e3c 100644
@@ -41,6 +41,12 @@
  * development environment.
  */
 
+/* MSVC headers do not define this macro, so do it here */
+#ifndef IN6_ARE_ADDR_EQUAL
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+  (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0)
+#endif
+
 void init_win32 (void);
 void uninit_win32 (void);
 
Signature · 1 line
1.7.5.4
#8 lore raw

Re: [Openvpn-devel] [PATCH-UPDATE] define IN6_ARE_ADDR_EQUAL macro for WIN32

Hi,

Quoted 8 lines · Heiko Hund

Windows headers do not define the IN6_ARE_ADDR_EQUAL macro. It needs to be defined locally when building for WIN32.

Update: remove check for USE_PF_INET6 since commit eb23089183745853fac9414d45a559a478ef51d6 removed the definition of this macro. IPv6 is now always compiled in.

ACK.

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]...
author
#9 lore raw

PATCH 2/2 don't use struct in6_addr s6_addr32 member anymore

In reply to Heiko Hund

The s6_addr32 member of struct in6_addr is not available when building for WIN32. To work around this, a local union is defined that allows accessing 32 bit chunks of the IPv6 address passed to add_in6_addr().

---
 socket.c |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)
socket.c +7 -9
index 6b855c0..887569c 100644
@@ -2622,13 +2622,6 @@ print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
 /* add some offset to an ipv6 address
  * (add in steps of 32 bits, taking overflow into next round)
  */
-#ifndef s6_addr32
-# ifdef TARGET_SOLARIS
-#  define s6_addr32 _S6_un._S6_u32
-# else
-#  define s6_addr32 __u6_addr.__u6_addr32
-# endif
-#endif
 #ifndef UINT32_MAX
 # define UINT32_MAX (4294967295U)
 #endif
@@ -2637,10 +2630,15 @@ struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add )
     int i;
     uint32_t h;
 
+    union {
+      uint8_t  *addr;
+      uint32_t *addr32;
+    } in6 = { .addr = base.s6_addr };
+
     for( i=3; i>=0 && add > 0 ; i-- )
     {
-	h = ntohl( base.s6_addr32[i] );
-	base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX );
+	h = ntohl( in6.addr32[i] );
+	in6.addr32[i] = htonl( (h+add) & UINT32_MAX );
 	/* 32-bit overrun? 
 	 * caveat: can't do "h+add > UINT32_MAX" with 32bit math!
          */
Signature · 1 line
1.7.5.4
#10 lore raw

Re: [Openvpn-devel] [PATCH 2/2] don't use struct in6_addr s6_addr32 member anymore

Hi,

Quoted 3 lines · Heiko Hund

The s6_addr32 member of struct in6_addr is not available when building for WIN32. To work around this, a local union is defined that allows accessing 32 bit chunks of the IPv6 address passed to add_in6_addr().

NAK, that's massively ugly.

I've changed the code to do 8-bit rounds. While somewhat slower, the code is actually more readable that way, and since this is only called once per connecting client, the few microseconds are well-spent.

My patch attached again. David?

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]...

From 1e3c114d655f65dfc3528b1d8884a026ba8bad6b Mon Sep 17 00:00:00 2001
From: Gert Doering <[email protected]...>
Date: Sat, 28 May 2011 22:50:40 +0200
Subject: [PATCH] Replace 32-bit-based add_in6_addr() implementation by an 8-bit based one
- windows has no 32-bit accessor to the union inside "struct in6_addr", and the 8-bit accessor is the only common denominator across BSD, Solaris, Linux and Windows...

---
 socket.c |   34 ++++++++++++++++------------------
 1 files changed, 16 insertions(+), 18 deletions(-)
socket.c +16 -18
index 6b855c0..7903c26 100644
@@ -2619,32 +2619,30 @@ print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
   return BSTR (&out);
 }
 
+#ifndef UINT8_MAX
+# define UINT8_MAX 0xff
+#endif
+
 /* add some offset to an ipv6 address
- * (add in steps of 32 bits, taking overflow into next round)
+ * (add in steps of 8 bits, taking overflow into next round)
  */
-#ifndef s6_addr32
-# ifdef TARGET_SOLARIS
-#  define s6_addr32 _S6_un._S6_u32
-# else
-#  define s6_addr32 __u6_addr.__u6_addr32
-# endif
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX (4294967295U)
-#endif
 struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add )
 {
     int i;
-    uint32_t h;
 
-    for( i=3; i>=0 && add > 0 ; i-- )
+    for( i=15; i>=0 && add > 0 ; i-- )
     {
-	h = ntohl( base.s6_addr32[i] );
-	base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX );
-	/* 32-bit overrun? 
-	 * caveat: can't do "h+add > UINT32_MAX" with 32bit math!
+	register int carry;
+	register uint32_t h;
+
+	h = (unsigned char) base.s6_addr[i];
+	base.s6_addr[i] = (h+add) & UINT8_MAX;
+
+	/* using explicit carry for the 8-bit additions will catch
+         * 8-bit and(!) 32-bit overruns nicely
          */
-	add = ( h > UINT32_MAX - add )?  1: 0;
+	carry = ((h & 0xff)  + (add & 0xff)) >> 8;
+	add = (add>>8) + carry;
     }
     return base;
 }
Signature · 1 line
1.7.3.4
author
#11 lore raw

Re: [Openvpn-devel] [PATCH 2/2] don't use struct in6_addr s6_addr32 member anymore

Quoted 6 lines · On Wednesday 10 August 2011 22:36:47 Gert Doering wrote:
Quoted 3 lines · Heiko Hund

The s6_addr32 member of struct in6_addr is not available when building for WIN32. To work around this, a local union is defined that allows accessing 32 bit chunks of the IPv6 address passed to add_in6_addr().

NAK, that's massively ugly.

o_O

Quoted 3 lines

I've changed the code to do 8-bit rounds. While somewhat slower, the code is actually more readable that way, and since this is only called once per connecting client, the few microseconds are well-spent.

ACK, as it fixes the issue

Heiko

Signature · 8 lines
Heiko Hund | Software Engineer | Phone +49-721-25516-237 | Fax -200
Astaro a Sophos Company | Amalienbadstr. 41 Bau 52 | 76227 Karlsruhe | Germany
Commercial Register: Mannheim HRA 702710 | Headquarter Location: Karlsruhe
 
Represented by the General Partner Astaro Verwaltungs GmbH
Amalienbadstraße 41 Bau 52 | 76227 Karlsruhe | Germany 
Commercial Register: Mannheim HRB 708248 | Executive Board: Gert Hansen,
Markus Hennig, Jan Hichert, Günter Junk, Dr. Frank Nellissen
#12 lore raw

Re: [Openvpn-devel] [PATCH 2/2] don't use struct in6_addr s6_addr32 member anymore

In reply to Heiko Hund

Hello,
I think this should be done by autoconf.
And hand added into win32 for MSVC.
Alon.

Quoted 59 lines · Heiko Hund

The s6_addr32 member of struct in6_addr is not available when building for WIN32. To work around this, a local union is defined that allows accessing 32 bit chunks of the IPv6 address passed to add_in6_addr().

---
 socket.c |   16 +++++++---------

 1 files changed, 7 insertions(+), 9 deletions(-)
socket.c +7 -10
index 6b855c0..887569c 100644
@@ -2622,13 +2622,6 @@ print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
  /* add some offset to an ipv6 address
  * (add in steps of 32 bits, taking overflow into next round)
  */
-#ifndef s6_addr32
-# ifdef TARGET_SOLARIS
-#  define s6_addr32 _S6_un._S6_u32
-# else
-#  define s6_addr32 __u6_addr.__u6_addr32
-# endif
-#endif
  #ifndef UINT32_MAX
  # define UINT32_MAX (4294967295U)
  #endif
@@ -2637,10 +2630,15 @@ struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add )
     int i;
     uint32_t h;
 
+    union {
+      uint8_t  *addr;
+      uint32_t *addr32;
+    } in6 = { .addr = base.s6_addr };
+
     for( i=3; i>=0 && add > 0 ; i-- )
     {
-       h = ntohl( base.s6_addr32[i] );
-       base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX );
+       h = ntohl( in6.addr32[i] );
+       in6.addr32[i] = htonl( (h+add) & UINT32_MAX );
        /* 32-bit overrun?
         * caveat: can't do "h+add > UINT32_MAX" with 32bit math!
          */
--

1.7.5.4

------------------------------------------------------------------------------
uberSVN's rich system and user administration capabilities and model configuration take the hassle out of deploying and managing Subversion and the tools developers use with it. Learn more about uberSVN and get a free download at:  http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#13 lore raw

Re: [Openvpn-devel] [PATCH 2/2] don't use struct in6_addr s6_addr32 member anymore

Hi,

Quoted 2 lines · Alon Bar-Lev

I think this should be done by autoconf.
And hand added into win32 for MSVC.

Any sort of conditional code here is causing more pain than just using the 8-bit accessors in a straightforward way with no #ifdefs.

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]...
#14 lore raw
In reply to Heiko Hund

Hi,

Quoted 1 line · Heiko Hund

struct in6_addr.s6_addr32 are not available there.

I've sent a fix for that one to the list some two months ago, but it's stuck somewhere in the commit queue...

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]...