Erich Hoover : ws2_32/tests: Add regression tests for WSARecvMsg and IP_PKTINFO.
Alexandre Julliard
julliard at winehq.org
Tue Dec 7 10:59:32 CST 2010
Module: wine
Branch: master
Commit: c134680321ca9344779f8d554c12f415fb65a432
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c134680321ca9344779f8d554c12f415fb65a432
Author: Erich Hoover <ehoover at mines.edu>
Date: Sun Dec 5 17:09:15 2010 -0700
ws2_32/tests: Add regression tests for WSARecvMsg and IP_PKTINFO.
---
dlls/ws2_32/tests/sock.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 177 insertions(+), 0 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 9e0b4cb..528c657 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -1085,6 +1085,182 @@ static void test_so_reuseaddr(void)
closesocket(s2);
}
+#define IP_PKTINFO_LEN (sizeof(WSACMSGHDR) + WSA_CMSG_ALIGN(sizeof(struct in_pktinfo)))
+
+static void test_ip_pktinfo(void)
+{
+ ULONG addresses[2] = {inet_addr("127.0.0.1"), htonl(INADDR_ANY)};
+ char recvbuf[10], pktbuf[512], msg[] = "HELLO";
+ struct sockaddr_in s1addr, s2addr, s3addr;
+ GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
+ LPFN_WSARECVMSG pWSARecvMsg = NULL;
+ unsigned int rc, foundhdr, yes = 1;
+ DWORD dwBytes, dwSize, dwFlags;
+ socklen_t addrlen;
+ WSACMSGHDR *cmsg;
+ WSAOVERLAPPED ov;
+ WSABUF iovec[1];
+ SOCKET s1, s2;
+ WSAMSG hdr;
+ int i, err;
+
+ memset(&ov, 0, sizeof(ov));
+ ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (ov.hEvent == INVALID_HANDLE_VALUE)
+ {
+ skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError());
+ return;
+ }
+
+ memset(&hdr, 0x00, sizeof(hdr));
+ s1addr.sin_family = AF_INET;
+ s1addr.sin_port = htons(0);
+ /* Note: s1addr.sin_addr is set below */
+ iovec[0].buf = recvbuf;
+ iovec[0].len = sizeof(recvbuf);
+ hdr.name = (struct sockaddr*)&s3addr;
+ hdr.namelen = sizeof(s3addr);
+ hdr.lpBuffers = &iovec[0];
+ hdr.dwBufferCount = 1;
+ hdr.Control.buf = pktbuf;
+ /* Note: hdr.Control.len is set below */
+ hdr.dwFlags = 0;
+
+ for (i=0;i<sizeof(addresses)/sizeof(UINT32);i++)
+ {
+ s1addr.sin_addr.s_addr = addresses[i];
+
+ /* Build "server" side socket */
+ s1=socket(AF_INET, SOCK_DGRAM, 0);
+ if (s1 == INVALID_SOCKET)
+ {
+ skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
+ goto cleanup;
+ }
+
+ /* Obtain the WSARecvMsg function */
+ WSAIoctl(s1, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
+ &pWSARecvMsg, sizeof(pWSARecvMsg), &dwBytes, NULL, NULL);
+ if (!pWSARecvMsg)
+ {
+ win_skip("WSARecvMsg is unsupported, some tests will be skipped.\n");
+ closesocket(s1);
+ goto cleanup;
+ }
+
+ /* Setup the server side socket */
+ rc=bind(s1, (struct sockaddr*)&s1addr, sizeof(s1addr));
+ ok(rc != SOCKET_ERROR, "bind() failed error: %d\n", WSAGetLastError());
+ rc=setsockopt(s1, IPPROTO_IP, IP_PKTINFO, (const char*)&yes, sizeof(yes));
+ ok(rc == 0, "failed to set IPPROTO_IP flag IP_PKTINFO!\n");
+
+ /* Build "client" side socket */
+ addrlen = sizeof(s2addr);
+ if (getsockname(s1, (struct sockaddr *) &s2addr, &addrlen) != 0)
+ {
+ skip("Failed to call getsockname, some tests skipped: %d\n", WSAGetLastError());
+ closesocket(s1);
+ goto cleanup;
+ }
+ s2addr.sin_addr.s_addr = addresses[0]; /* Always target the local adapter address */
+ s2=socket(AF_INET, SOCK_DGRAM, 0);
+ if (s2 == INVALID_SOCKET)
+ {
+ skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
+ closesocket(s1);
+ goto cleanup;
+ }
+
+ /* Test an empty message header */
+ rc=pWSARecvMsg(s1, NULL, NULL, NULL, NULL);
+ err=WSAGetLastError();
+ ok(rc == SOCKET_ERROR && err == WSAEFAULT, "WSARecvMsg() failed error: %d (ret = %d)\n", err, rc);
+
+ /*
+ * Send a packet from the client to the server and test for specifying
+ * a short control header.
+ */
+ rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
+ ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
+ hdr.Control.len = 1;
+ rc=pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
+ err=WSAGetLastError();
+ ok(rc == SOCKET_ERROR && err == WSAEMSGSIZE && (hdr.dwFlags & MSG_CTRUNC),
+ "WSARecvMsg() failed error: %d (ret: %d, flags: %d)\n", err, rc, hdr.dwFlags);
+ hdr.dwFlags = 0; /* Reset flags */
+
+ /* Perform another short control header test, this time with an overlapped receive */
+ hdr.Control.len = 1;
+ rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
+ err=WSAGetLastError();
+ ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
+ rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
+ ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
+ if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
+ {
+ skip("Server side did not receive packet, some tests skipped.\n");
+ closesocket(s2);
+ closesocket(s1);
+ continue;
+ }
+ dwFlags = 0;
+ WSAGetOverlappedResult(s1, &ov, NULL, FALSE, &dwFlags);
+ ok(dwFlags == 0,
+ "WSAGetOverlappedResult() returned unexpected flags %d!\n", dwFlags);
+ ok(hdr.dwFlags == MSG_CTRUNC,
+ "WSARecvMsg() overlapped operation set unexpected flags %d.\n", hdr.dwFlags);
+ hdr.dwFlags = 0; /* Reset flags */
+
+ /*
+ * Setup an overlapped receive, send a packet, then wait for the packet to be retrieved
+ * on the server end and check that the returned packet matches what was sent.
+ */
+ hdr.Control.len = sizeof(pktbuf);
+ rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
+ err=WSAGetLastError();
+ ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
+ ok(hdr.Control.len == sizeof(pktbuf),
+ "WSARecvMsg() control length mismatch (%d != sizeof pktbuf).\n", hdr.Control.len);
+ rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
+ ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
+ if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
+ {
+ skip("Server side did not receive packet, some tests skipped.\n");
+ closesocket(s2);
+ closesocket(s1);
+ continue;
+ }
+ dwSize = 0;
+ WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, NULL);
+ ok(dwSize == sizeof(msg),
+ "WSARecvMsg() buffer length does not match transmitted data!\n");
+ ok(strncmp(iovec[0].buf, msg, sizeof(msg)) == 0,
+ "WSARecvMsg() buffer does not match transmitted data!\n");
+ ok(hdr.Control.len == IP_PKTINFO_LEN,
+ "WSARecvMsg() control length mismatch (%d != %d).\n", hdr.Control.len, IP_PKTINFO_LEN);
+
+ /* Test for the expected IP_PKTINFO return information. */
+ foundhdr = FALSE;
+ for (cmsg = WSA_CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = WSA_CMSG_NXTHDR(&hdr, cmsg))
+ {
+ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
+ {
+ struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
+
+ ok(pi->ipi_addr.s_addr == s2addr.sin_addr.s_addr, "destination ip mismatch!\n");
+ foundhdr = TRUE;
+ }
+ }
+ ok(foundhdr, "IP_PKTINFO header information was not returned!\n");
+
+ closesocket(s2);
+ closesocket(s1);
+ }
+
+cleanup:
+ CloseHandle(ov.hEvent);
+}
+
/************* Array containing the tests to run **********/
#define STD_STREAM_SOCKET \
@@ -4422,6 +4598,7 @@ START_TEST( sock )
test_set_getsockopt();
test_so_reuseaddr();
+ test_ip_pktinfo();
test_extendedSocketOptions();
for (i = 0; i < NUM_TESTS; i++)
More information about the wine-cvs
mailing list