This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: bug: struct cmsghdr does not match system on cygwin64
- From: Kenton Varda <kenton at sandstorm dot io>
- To: cygwin <cygwin at cygwin dot com>, marco dot atzeri at gmail dot com
- Date: Mon, 29 Dec 2014 12:48:15 -0800
- Subject: Re: bug: struct cmsghdr does not match system on cygwin64
- Authentication-results: sourceware.org; auth=none
- References: <CAOP=4wh3i=gHtCTPwksmrP=3_aQTMiFw8_0Vg08hrCPg53m8fg at mail dot gmail dot com>
Marco Atzeri wrote:
> If I am not wrong, for 64bit,
> on windows sizeof (SIZE_T) =4
> while on cygwin sizeof(size_t)=8
sizeof(SIZE_T) == 8 on Win64. The purpose of SIZE_T is to be the same
size as a pointer:
http://msdn.microsoft.com/en-us/library/cc441980.aspx
To be clear, I am actually observing everything after cmsg_len being
shifted 4 bytes in real code that works on other platforms.
Specifically, the Cap'n Proto unit tests fail on Cygwin but pass on
Linux and OSX after this commit:
https://github.com/kentonv/capnproto/commit/68ad32202ed43e42a15de3da90a86b7efdcf8f12
-Kenton
On Sun, Dec 28, 2014 at 9:03 PM, Kenton Varda <kenton@sandstorm.io> wrote:
> Hello Cygwin,
>
> Cygwin defines 'struct cmsghdr' (see recvmsg(2)) as follows (cygwin/socket.h):
>
> struct cmsghdr
> {
> socklen_t cmsg_len; /* Length of cmsghdr + data */
> int cmsg_level; /* Protocol */
> int cmsg_type; /* Protocol type */
> };
>
> Unfortunately, Winsock defines its equivalent type as follows (ws2def.h):
>
> typedef struct _WSACMSGHDR {
> SIZE_T cmsg_len;
> INT cmsg_level;
> INT cmsg_type;
> /* followed by UCHAR cmsg_data[] */
> } WSACMSGHDR, *PWSACMSGHDR, FAR *LPWSACMSGHDR;
>
> As you can see, on a 64-bit build, the cmsg_len is 64 bits in the
> Winsock struct. However, Cygwin's socklen_t is always 32 bits,
> therefore cmsg_len is 32 bits in the Cygwin struct.
>
> Cygwin's recvmsg() calls WSARecvMsg() passing the control message
> buffer pointer verbatim, expecting the system to fill the buffer
> correctly. The system dutifully fills the buffer with control messages
> that are not legible using Cygwin's definition of the struct, leaving
> the calling application with apparent garbage data.
>
> sendmsg() likely has a similar problem, though I haven't checked.
>
> It seems like the best solution is to change the type of cmsg_len to
> size_t. While this would technically violate standards (I think?), it
> turns out the Linux headers define it this way, so presumably no one
> will mind.
>
> The other option is to perform some sort of translation of the control
> message buffer inside sendmsg() and recvmsg(), but that would
> obviously be painful and error-prone.
>
> AFAICT, this bug breaks all users of the IP_PKTINFO and IPV6_PKTINFO
> socket options on cygwin64.
>
> -Kenton
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple