Skip to contentSkip to conversation

OpenVPN 2.1_rc7, multihome and 64 bit

PATCH In review Tim Davies 3 participants 7 messages Apr 25, 2008 – May 9, 2008

lore
Share & tools
lore

Tim Davies

author
#0 lore raw

PATCH 1/1 OpenVPN 2.1_rc7, multihome and 64 bit

After attempting to use OpenVPN 2.1_rc7 on a 64 bit Centos 5 platform, I came across a peculiar error when enabling multihome. Basically no UDP packets were allowed to send due to an incorrect size being set.

The problem seems to be in socket.c, where sizeof(opi) is incorrect. The structure is defined as:

struct openvpn_pktinfo
{
struct cmsghdr cmsghdr;
struct in_pktinfo in_pktinfo;
};

On a 64 bit platform, sizeof(struct cmsghdr) is 16, and sizeof(struct in_pktinfo) is 12. Due to structure padding, sizeof(struct openvpn_pktinfo) is 32, not 28.

The attached patch fixed the problem, although I'm not sure it's the best way to go about it.

Tim.

socket.c +4 -4
diff -ur openvpn-2.1_rc7/socket.c openvpn-2.1_rc7-work/socket.c
@@ -2145,7 +2145,7 @@
   mesg.msg_name = &from->dest.sa;
   mesg.msg_namelen = fromlen;
   mesg.msg_control = &opi;
-  mesg.msg_controllen = sizeof (opi);
+  mesg.msg_controllen = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo);
   buf->len = recvmsg (sock->sd, &mesg, 0);
   if (buf->len >= 0)
     {
@@ -2156,7 +2156,7 @@
 	  && CMSG_NXTHDR (&mesg, cmsg) == NULL
 	  && cmsg->cmsg_level == SOL_IP 
 	  && cmsg->cmsg_type == IP_PKTINFO
-	  && cmsg->cmsg_len >= sizeof (opi))
+	  && cmsg->cmsg_len >= sizeof(struct cmsghdr) + sizeof(struct in_pktinfo))
 	{
 	  struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
 	  from->pi.ipi_ifindex = pkti->ipi_ifindex;
@@ -2231,10 +2231,10 @@
   mesg.msg_name = &to->dest.sa;
   mesg.msg_namelen = sizeof (to->dest.sa);
   mesg.msg_control = &opi;
-  mesg.msg_controllen = sizeof (opi);
+  mesg.msg_controllen = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo);
   mesg.msg_flags = 0;
   cmsg = CMSG_FIRSTHDR (&mesg);
-  cmsg->cmsg_len = sizeof (opi);
+  cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo);
   cmsg->cmsg_level = SOL_IP;
   cmsg->cmsg_type = IP_PKTINFO;
   pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
#1 lore raw

Interesting. I wonder if a better solution might be to bracket the struct openvpn_pktinfo definition with

#pragma pack(1)
...
#pragma pack()

James

Quoted 26 lines · Tim Davies

After attempting to use OpenVPN 2.1_rc7 on a 64 bit Centos 5 platform, I came across a peculiar error when enabling multihome. Basically no UDP packets were allowed to send due to an incorrect size being set.

The problem seems to be in socket.c, where sizeof(opi) is incorrect. The structure is defined as:

struct openvpn_pktinfo
{
struct cmsghdr cmsghdr;
struct in_pktinfo in_pktinfo;
};

On a 64 bit platform, sizeof(struct cmsghdr) is 16, and sizeof(struct in_pktinfo) is 12. Due to structure padding, sizeof(struct openvpn_pktinfo) is 32, not 28.

The attached patch fixed the problem, although I'm not sure it's the best way to go about it.

Tim.
------------------------------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
------------------------------------------------------------------------

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#2 lore raw

James Yonan <[email protected]...>:

Quoted 6 lines

Interesting. I wonder if a better solution might be to bracket the struct openvpn_pktinfo definition with

#pragma pack(1)
...
#pragma pack()

Yes, although gcc is allergic to #pragma's. The gcc way of expressing it is:

          struct __attribute__ ((__packed__)) my_packed_struct
            {
               char c;
               int  i;
               struct my_unpacked_struct s;
            };

(from "info gcc" -> "C Extensions" -> "Type Attributes").

Marko

#3 lore raw
Quoted 20 lines · Marko Rauhamaa

James Yonan <[email protected]...>:

Quoted 6 lines

Interesting. I wonder if a better solution might be to bracket the struct openvpn_pktinfo definition with

#pragma pack(1)
...
#pragma pack()

Yes, although gcc is allergic to #pragma's. The gcc way of expressing it is:

          struct __attribute__ ((__packed__)) my_packed_struct
            {
               char c;
               int  i;
               struct my_unpacked_struct s;
            };
Quoted 5 lines

(from "info gcc" -> "C Extensions" -> "Type Attributes").

Marko

gcc does support #pragma pack:

http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

James

#4 lore raw

James Yonan <[email protected]...>:

Quoted 4 lines
Quoted 1 line · Marko Rauhamaa

Yes, although gcc is allergic to #pragma's. [...]

gcc does support #pragma pack:

Yes, but:

GCC supports several types of pragmas, primarily in order to compile code originally written for other compilers. Note that in general we do not recommend the use of pragmas; *Note Function Attributes::, for further explanation.

("info gcc" 5.48 Pragmas Accepted by GCC)

Marko

#5 lore raw
In reply to Tim Davies
Quoted 10 lines · Tim Davies

After attempting to use OpenVPN 2.1_rc7 on a 64 bit Centos 5 platform, I came across a peculiar error when enabling multihome. Basically no UDP packets were allowed to send due to an incorrect size being set.

The problem seems to be in socket.c, where sizeof(opi) is incorrect. The structure is defined as:

struct openvpn_pktinfo
{
struct cmsghdr cmsghdr;
struct in_pktinfo in_pktinfo;
};

Quoted 4 lines

On a 64 bit platform, sizeof(struct cmsghdr) is 16, and sizeof(struct in_pktinfo) is 12. Due to structure padding, sizeof(struct openvpn_pktinfo) is 32, not 28.

The attached patch fixed the problem, although I'm not sure it's the best way to go about it.

I've merged a patch into the subversion directory for the 2.1 series that addresses this using #pragma pack(1)

http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn/

It will be included in 2.1-rc8. Let me know if it fixes the problem.

James

author
#6 lore raw

I've just tested this and it seems to work well. Thanks.

Quoted 25 lines · James Yonan
Quoted 10 lines · Tim Davies

After attempting to use OpenVPN 2.1_rc7 on a 64 bit Centos 5 platform, I came across a peculiar error when enabling multihome. Basically no UDP packets were allowed to send due to an incorrect size being set.

The problem seems to be in socket.c, where sizeof(opi) is incorrect. The structure is defined as:

struct openvpn_pktinfo
{
struct cmsghdr cmsghdr;
struct in_pktinfo in_pktinfo;
};

Quoted 4 lines

On a 64 bit platform, sizeof(struct cmsghdr) is 16, and sizeof(struct in_pktinfo) is 12. Due to structure padding, sizeof(struct openvpn_pktinfo) is 32, not 28.

The attached patch fixed the problem, although I'm not sure it's the best way to go about it.

I've merged a patch into the subversion directory for the 2.1 series that addresses this using #pragma pack(1)

http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn/

It will be included in 2.1-rc8. Let me know if it fixes the problem.

James