ws2_32: Add support and tests for WSARecvMsg and IP_PKTINFO.
Mike Kaplinskiy
mike.kaplinskiy at gmail.com
Tue Oct 12 23:12:15 CDT 2010
On Tue, Oct 12, 2010 at 8:01 PM, Erich Hoover <ehoover at mines.edu> wrote:
> Real Name:
> Erich Hoover
> Description:
> While searching for something else I discovered a bug relevant to the
> interface-bound UDP broadcast patches I've been working on. Apparently,
> IP_PKTINFO does work on Windows when used with the special WSARecvMsg
> function (Bug #19493). The attached patch addresses this issue by
> implementing WSARecvMsg through WS2_recvfrom and by converting the Unix
> IP_PKTINFO response to the Windows equivalent.
> ChangeLog:
> ws2_32: Add support and tests for WSARecvMsg and IP_PKTINFO.
>
>
>
>
Sorry I must have missed the RFC when reading my mail. These comments
are purely mine, and may not have any value for getting your patch in
:).
+static inline WSACMSGHDR *create_control_message(int level, int type,
WSACMSGHDR *current, ULONG *maxsize, void *data, int len)
This doesn't seem like a "create", more like a "fill" or "write".
+ int newsize = (int)*maxsize;
+
+ /* Make sure there is at least enough room for this entry */
+ newsize -= sizeof(WSACMSGHDR) + CMSG_ALIGN(len);
+ if (newsize < 0)
+ return 0;
+ *maxsize = (ULONG)newsize;
Just declare it as a ULONG/size_t so you don't have to cast.
+static inline int convert_control_headers(struct msghdr *hdr, ULONG *maxsize)
You shouldn't mix using memory as unix-style CMSGs and windows-style
CMSGs. Just allocate something to store the unix messages, read them
in and convert them into the user-passed buffer. This seems similar to
what we do for address conversion.
+ memset(cmsg_win, 0x00, sizeof(WSACMSGHDR)); /* Don't use garbage
data if no headers are found */
I think in general that is discouraged at wine (don't quote me on
that). You should just initialize the values manually.
+ if (wsa->control && !convert_control_headers(&hdr, wsa->controllen))
+ {
+ /* Insufficient room for control headers */
+ errno = EINVAL;
+ return -1;
+ }
This should probably be in an #ifdef of some sort.
+ msg->dwFlags |= WINE_MSG_HASCTRL;
+ memcpy(buftmp, msg->lpBuffers, msg->dwBufferCount * sizeof(WSABUF));
+ buftmp[msg->dwBufferCount] = msg->Control;
+ ret = WS2_recvfrom( s, buftmp, msg->dwBufferCount, lpNumberOfBytesRecvd,
+ &msg->dwFlags, msg->name, &msg->namelen,
+ lpOverlapped, lpCompletionRoutine );
You shouldn't add internal flags like that. Just rewrite WS2_recvfrom
to allow returning message headers instead of hacking around it.
+static int (WINAPI
*pWSARecvMsg)(SOCKET,LPWSAMSG,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE)
= 0;
+GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
For one reason or another the convention is to get it during your test
function (see AcceptEx & ConnectEx). (This does have some merit as
SIO_GET_EXTENSION_FUNCTION_POINTER can vary with the socket that's
passed)
+ s1addr.sin_family = AF_INET;
+ s1addr.sin_port = htons(9375);
+ s2addr.sin_family = AF_INET;
+ s2addr.sin_port = htons(9375);
You should probably bind to 0 and then use getsockname to get the
actual port you bound to.
+ s1=socket(AF_INET, SOCK_DGRAM, 0);
+ ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n",
WSAGetLastError());
Spaces around = & != would make me happy (and below). Also you don't
error out correctly if socket creation fails.
diff --git a/include/mswsock.h b/include/mswsock.h
index 322ab20..5749e59 100644
--- a/include/mswsock.h
+++ b/include/mswsock.h
This should be a separate patch.
diff --git a/include/ws2ipdef.h b/include/ws2ipdef.h
index 11b3689..ec0b85a 100644
--- a/include/ws2ipdef.h
+++ b/include/ws2ipdef.h
Same here.
Mike.
More information about the wine-devel
mailing list