On Tue, Oct 12, 2010 at 8:01 PM, Erich Hoover <ehoo...@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.