ReactOS 0.4.15-dev-5667-ged97270
WSAAsync.c
Go to the documentation of this file.
1/*
2* PROJECT: ReactOS api tests
3* LICENSE: GPL - See COPYING in the top level directory
4* PURPOSE: Test for WSAAsync
5* PROGRAMMERS: Miroslav Mastny
6*/
7
8#include "ws2_32.h"
9
10#define SVR_PORT 5000
11#define WAIT_TIMEOUT_ 10000
12#define EXIT_FLAGS (FD_ACCEPT|FD_CONNECT)
13#define MAX_LOOPCOUNT 9u
14
15START_TEST(WSAAsync)
16{
17 WSADATA WsaData;
19 ClientSocket = INVALID_SOCKET;
20 WSAEVENT ServerEvent = WSA_INVALID_EVENT,
21 ClientEvent = WSA_INVALID_EVENT;
22 struct hostent *ent = NULL;
23 struct sockaddr_in server_addr_in;
24 struct sockaddr_in addr_remote;
25 struct sockaddr_in addr_con_loc;
26 int nConRes, nSockNameRes;
27 int addrsize, len;
28 WSAEVENT fEvents[2];
29 SOCKET fSockets[2];
30 SOCKET sockaccept;
31 WSANETWORKEVENTS WsaNetworkEvents;
32 ULONG ulValue = 1;
33 DWORD dwWait;
34 DWORD dwFlags = 0;
35 struct fd_set select_rfds;
36 struct fd_set select_wfds;
37 struct fd_set select_efds;
38 struct timeval timeval;
39 BOOL ConnectSent = FALSE;
40 unsigned int Addr_con_locLoopCount = 0,
41 ServerSocketLoopCount = 0;
42
43 if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0)
44 {
45 skip("WSAStartup failed\n");
46 return;
47 }
48
50 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
51 ServerEvent = WSACreateEvent();
52 ClientEvent = WSACreateEvent();
53
55 {
56 skip("ERROR: Server socket creation failed\n");
57 return;
58 }
59 if (ClientSocket == INVALID_SOCKET)
60 {
61 skip("ERROR: Client socket creation failed\n");
63 return;
64 }
65 if (ServerEvent == WSA_INVALID_EVENT)
66 {
67 skip("ERROR: Server WSAEvent creation failed\n");
68 closesocket(ClientSocket);
70 return;
71 }
72 if (ClientEvent == WSA_INVALID_EVENT)
73 {
74 skip("ERROR: Client WSAEvent creation failed\n");
75 WSACloseEvent(ServerEvent);
76 closesocket(ClientSocket);
78 return;
79 }
80 ent = gethostbyname("127.0.0.1");
81 if (ent == NULL)
82 {
83 ok(ent != NULL, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n");
84 ent = gethostbyname("localhost");
85
86 if (ent == NULL)
87 {
88 skip("ERROR: gethostbyname 'localhost' failed\n");
89 goto done;
90 }
91 }
92
93 server_addr_in.sin_family = AF_INET;
94 server_addr_in.sin_port = htons(SVR_PORT);
95 memcpy(&server_addr_in.sin_addr.S_un.S_addr, ent->h_addr_list[0], 4);
96
97 // Server initialization.
98 trace("Initializing server and client connections ...\n");
99 ok(bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)) == 0, "ERROR: server bind failed\n");
100 ok(ioctlsocket(ServerSocket, FIONBIO, &ulValue) == 0, "ERROR: server ioctlsocket FIONBIO failed\n");
101 ok(WSAEventSelect(ServerSocket, ServerEvent, FD_ACCEPT | FD_CLOSE) == 0, "ERROR: server accept EventSelect failed\n");
102
103 // Client initialization.
104 ok(WSAEventSelect(ClientSocket, ClientEvent, FD_CONNECT | FD_CLOSE) == 0, "ERROR: client EventSelect failed\n");
105 ok(ioctlsocket(ClientSocket, FIONBIO, &ulValue) == 0, "ERROR: client ioctlsocket FIONBIO failed\n");
106
107 // listen
108 trace("Starting server listening mode ...\n");
109 ok(listen(ServerSocket, SOMAXCONN) == 0, "ERROR: cannot initialize server listen\n");
110
111 trace("Starting client to server connection ...\n");
112 // connect
113 nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
114 ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n");
115 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
116
117 fSockets[0] = ServerSocket;
118 fSockets[1] = ClientSocket;
119
120 fEvents[0] = ServerEvent;
121 fEvents[1] = ClientEvent;
122
123 while (dwFlags != EXIT_FLAGS)
124 {
125 dwWait = WaitForMultipleObjects(2, fEvents, FALSE, WAIT_TIMEOUT_);
126
127 if (dwWait != WAIT_OBJECT_0 && // server socket event
128 dwWait != WAIT_OBJECT_0+1) // client socket event
129 {
130 ok(FALSE, "Unknown event received %lu\n", dwWait);
131 skip("ERROR: Connection timeout\n");
132 break;
133 }
134
135 WSAEnumNetworkEvents(fSockets[dwWait-WAIT_OBJECT_0], fEvents[dwWait-WAIT_OBJECT_0], &WsaNetworkEvents);
136
137 if ((WsaNetworkEvents.lNetworkEvents & FD_ACCEPT) != 0)
138 {// connection accepted
139 trace("Event FD_ACCEPT...\n");
140 ok(WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0, "Error on accept %d\n", WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT]);
141 if (WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0)
142 {
143 addrsize = sizeof(addr_remote);
144 sockaccept = accept(fSockets[dwWait - WAIT_OBJECT_0], (struct sockaddr*)&addr_remote, &addrsize);
145 ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError());
147 }
148 }
149
150 if ((WsaNetworkEvents.lNetworkEvents & FD_CONNECT) != 0)
151 {// client connected
152 trace("Event FD_CONNECT...\n");
153 ok(WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT] == 0, "Error on connect %d\n", WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT]);
154 if (WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT] == 0)
155 {
156 len = sizeof(addr_con_loc);
157 ok(getsockname(fSockets[dwWait - WAIT_OBJECT_0], (struct sockaddr*)&addr_con_loc, &len) == 0, "\n");
159 }
160 }
161 }
162 closesocket(sockaccept);
164 closesocket(ClientSocket);
165
166 /* same test but with waiting select and getsockname to return proper values */
168 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
169
171 {
172 skip("ERROR: Server socket creation failed\n");
173 return;
174 }
175 if (ClientSocket == INVALID_SOCKET)
176 {
177 skip("ERROR: Client socket creation failed\n");
179 return;
180 }
181 ent = gethostbyname("127.0.0.1");
182 if (ent == NULL)
183 {
184 ok(ent != NULL, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n");
185 ent = gethostbyname("localhost");
186
187 if (ent == NULL)
188 {
189 skip("ERROR: gethostbyname 'localhost' failed\n");
190 goto done;
191 }
192 }
193
194 server_addr_in.sin_family = AF_INET;
195 server_addr_in.sin_port = htons(SVR_PORT);
196 memcpy(&server_addr_in.sin_addr.S_un.S_addr, ent->h_addr_list[0], 4);
197
198 // Server initialization.
199 trace("Initializing server and client connections ...\n");
200 ok(bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)) == 0, "ERROR: server bind failed\n");
201 ok(ioctlsocket(ServerSocket, FIONBIO, &ulValue) == 0, "ERROR: server ioctlsocket FIONBIO failed\n");
202
203 // Client initialization.
204 ok(ioctlsocket(ClientSocket, FIONBIO, &ulValue) == 0, "ERROR: client ioctlsocket FIONBIO failed\n");
205
206 // listen
207 trace("Starting server listening mode ...\n");
208 ok(listen(ServerSocket, SOMAXCONN) == 0, "ERROR: cannot initialize server listen\n");
209
210 memset(&timeval, 0, sizeof(timeval));
212 dwFlags = 0;
213
214 while (dwFlags != EXIT_FLAGS)
215 {
216 len = sizeof(addr_con_loc);
217 nSockNameRes = getsockname(ClientSocket, (struct sockaddr*)&addr_con_loc, &len);
218 if (dwFlags == 0 && !ConnectSent)
219 {
220 ok(nSockNameRes == SOCKET_ERROR, "ERROR: getsockname function failed, expected %d error %d\n", SOCKET_ERROR, nSockNameRes);
221 ok(WSAGetLastError() == WSAEINVAL, "ERROR: getsockname function failed, expected %ld error %d\n", WSAEINVAL, WSAGetLastError());
222 trace("Starting client to server connection ...\n");
223 // connect
224 nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
225 ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n");
226 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
227 ConnectSent = TRUE;
228 continue;
229 }
230 else
231 {
232 if (nSockNameRes != 0)
233 ok(FALSE, "ERROR: getsockname function failed, expected 0 error %d\n", nSockNameRes);
234 if (len != sizeof(addr_con_loc))
235 ok(FALSE, "ERROR: getsockname function wrong size, expected %Iu returned %d\n", sizeof(addr_con_loc), len);
236
237 if (addr_con_loc.sin_addr.s_addr == 0ul)
238 {
239 if (++Addr_con_locLoopCount >= MAX_LOOPCOUNT)
240 {
241 ok(FALSE, "Giving up, on getsockname() (%u/%u), as addr_con_loc is not set yet\n",
242 Addr_con_locLoopCount, MAX_LOOPCOUNT);
243 goto done;
244 }
245
246 trace("Looping, for getsockname() (%u/%u), as addr_con_loc is not set yet\n",
247 Addr_con_locLoopCount, MAX_LOOPCOUNT);
248 Sleep(1);
249 continue;
250 }
251
252 if (addr_con_loc.sin_addr.s_addr != server_addr_in.sin_addr.s_addr)
253 ok(FALSE, "ERROR: getsockname function wrong addr, expected %08lx returned %08lx\n", server_addr_in.sin_addr.s_addr, addr_con_loc.sin_addr.s_addr);
254 }
255 if ((dwFlags & FD_ACCEPT) != 0)
256 {// client connected
257 trace("Select CONNECT...\n");
259 }
260
261 FD_ZERO(&select_rfds);
262 FD_ZERO(&select_wfds);
263 FD_ZERO(&select_efds);
264 FD_SET(ServerSocket, &select_rfds);
265 FD_SET(ClientSocket, &select_rfds);
266 FD_SET(ServerSocket, &select_wfds);
267 FD_SET(ClientSocket, &select_wfds);
268 FD_SET(ServerSocket, &select_efds);
269 FD_SET(ClientSocket, &select_efds);
270 if ((dwFlags & FD_ACCEPT) != 0)
271 {
272 FD_SET(sockaccept, &select_rfds);
273 FD_SET(sockaccept, &select_wfds);
274 FD_SET(sockaccept, &select_efds);
275 }
276 if (select(0, &select_rfds, &select_wfds, &select_efds, &timeval) != 0)
277 {// connection accepted
278 if (dwFlags == (FD_ACCEPT | FD_CONNECT))
279 {
280 trace("Select ACCEPT&CONNECT...\n");
281 ok(FD_ISSET(ClientSocket, &select_wfds), "ClientSocket is not writable\n");
282 ok(FD_ISSET(sockaccept, &select_wfds), "sockaccept is not writable\n");
283 ok(!FD_ISSET(ServerSocket, &select_rfds), "ServerSocket is readable\n");
284 }
285 if (dwFlags == FD_ACCEPT)
286 {
287 trace("Select ACCEPT...\n");
288 ok(!FD_ISSET(ClientSocket, &select_wfds), "ClientSocket is writable\n");
289 ok(FD_ISSET(sockaccept, &select_wfds), "sockaccept is not writable\n");
290 ok(FD_ISSET(ServerSocket, &select_rfds), "ServerSocket is not readable\n");
291 }
292 if (dwFlags == 0)
293 {
294 if (FD_ISSET(ServerSocket, &select_rfds))
295 {
296 trace("Select ACCEPT...\n");
297 addrsize = sizeof(addr_remote);
298 sockaccept = accept(ServerSocket, (struct sockaddr*)&addr_remote, &addrsize);
299 ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError());
301 }
302 else
303 {
304 if (++ServerSocketLoopCount >= MAX_LOOPCOUNT)
305 {
306 ok(FALSE, "Giving up, on select() (%u/%u), as ServerSocket is not readable yet\n",
307 ServerSocketLoopCount, MAX_LOOPCOUNT);
308 goto done;
309 }
310
311 trace("Looping, for select() (%u/%u), as ServerSocket is not readable yet\n",
312 ServerSocketLoopCount, MAX_LOOPCOUNT);
313 Sleep(1);
314 continue;
315 }
316 }
317 }
318 }
319
320done:
321 WSACloseEvent(ServerEvent);
322 WSACloseEvent(ClientEvent);
323 closesocket(sockaccept);
325 closesocket(ClientSocket);
326
327 WSACleanup();
328}
#define WAIT_TIMEOUT_
Definition: WSAAsync.c:11
#define EXIT_FLAGS
Definition: WSAAsync.c:12
#define MAX_LOOPCOUNT
Definition: WSAAsync.c:13
#define SVR_PORT
Definition: WSAAsync.c:10
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WSAAPI WSAEnumNetworkEvents(IN SOCKET s, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents)
Definition: event.c:94
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
INT WSAAPI WSAEventSelect(IN SOCKET s, IN WSAEVENT hEventObject, IN LONG lNetworkEvents)
Definition: select.c:182
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define IPPROTO_TCP
Definition: ip.h:196
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:213
#define ioctlsocket
Definition: ncftp.h:481
#define closesocket
Definition: ncftp.h:477
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
SOCKET ServerSocket
Definition: socket.c:3
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
int iErrorCode[FD_MAX_EVENTS]
Definition: winsock2.h:644
Definition: winsock.h:66
char ** h_addr_list
Definition: winsock.h:138
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
unsigned long tv_usec
Definition: linux.h:1739
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint32_t ULONG
Definition: typedefs.h:59
#define WAIT_OBJECT_0
Definition: winbase.h:406
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define WSAEINVAL
Definition: winerror.h:1946
#define FD_CONNECT_BIT
Definition: winsock2.h:301
#define FD_ACCEPT_BIT
Definition: winsock2.h:299
WINSOCK_API_LINKAGE WSAEVENT WSAAPI WSACreateEvent(void)
Definition: event.c:42
#define WSA_INVALID_EVENT
Definition: winsock2.h:623
DWORD WSAEVENT
Definition: winsock2.h:606
#define SOMAXCONN
Definition: winsock.h:399
#define FD_ISSET(fd, set)
Definition: winsock.h:100
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define FD_ZERO(set)
Definition: winsock.h:96
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:332
#define FD_CLOSE
Definition: winsock.h:410
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define FD_CONNECT
Definition: winsock.h:409
#define FD_SET(fd, set)
Definition: winsock.h:89
#define FIONBIO
Definition: winsock.h:149
#define FD_ACCEPT
Definition: winsock.h:408