2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for WSAAsync
5 * PROGRAMMERS: Miroslav Mastny
11 #define WAIT_TIMEOUT_ 10000
12 #define EXIT_FLAGS (FD_ACCEPT|FD_CONNECT)
13 #define MAX_LOOPCOUNT 9u
18 SOCKET ServerSocket
= INVALID_SOCKET
,
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
;
31 WSANETWORKEVENTS WsaNetworkEvents
;
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;
43 if (WSAStartup(MAKEWORD(2, 2), &WsaData
) != 0)
45 skip("WSAStartup failed\n");
49 ServerSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
50 ClientSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
51 ServerEvent
= WSACreateEvent();
52 ClientEvent
= WSACreateEvent();
54 if (ServerSocket
== INVALID_SOCKET
)
56 skip("ERROR: Server socket creation failed\n");
59 if (ClientSocket
== INVALID_SOCKET
)
61 skip("ERROR: Client socket creation failed\n");
62 closesocket(ServerSocket
);
65 if (ServerEvent
== WSA_INVALID_EVENT
)
67 skip("ERROR: Server WSAEvent creation failed\n");
68 closesocket(ClientSocket
);
69 closesocket(ServerSocket
);
72 if (ClientEvent
== WSA_INVALID_EVENT
)
74 skip("ERROR: Client WSAEvent creation failed\n");
75 WSACloseEvent(ServerEvent
);
76 closesocket(ClientSocket
);
77 closesocket(ServerSocket
);
80 ent
= gethostbyname("127.0.0.1");
83 ok(ent
!= NULL
, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n");
84 ent
= gethostbyname("localhost");
88 skip("ERROR: gethostbyname 'localhost' failed\n");
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);
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");
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");
108 trace("Starting server listening mode ...\n");
109 ok(listen(ServerSocket
, SOMAXCONN
) == 0, "ERROR: cannot initialize server listen\n");
111 trace("Starting client to server connection ...\n");
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");
117 fSockets
[0] = ServerSocket
;
118 fSockets
[1] = ClientSocket
;
120 fEvents
[0] = ServerEvent
;
121 fEvents
[1] = ClientEvent
;
123 while (dwFlags
!= EXIT_FLAGS
)
125 dwWait
= WaitForMultipleObjects(2, fEvents
, FALSE
, WAIT_TIMEOUT_
);
127 if (dwWait
!= WAIT_OBJECT_0
&& // server socket event
128 dwWait
!= WAIT_OBJECT_0
+1) // client socket event
130 ok(FALSE
, "Unknown event received %lu\n", dwWait
);
131 skip("ERROR: Connection timeout\n");
135 WSAEnumNetworkEvents(fSockets
[dwWait
-WAIT_OBJECT_0
], fEvents
[dwWait
-WAIT_OBJECT_0
], &WsaNetworkEvents
);
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)
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());
146 dwFlags
|= FD_ACCEPT
;
150 if ((WsaNetworkEvents
.lNetworkEvents
& FD_CONNECT
) != 0)
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)
156 len
= sizeof(addr_con_loc
);
157 ok(getsockname(fSockets
[dwWait
- WAIT_OBJECT_0
], (struct sockaddr
*)&addr_con_loc
, &len
) == 0, "\n");
158 dwFlags
|= FD_CONNECT
;
162 closesocket(sockaccept
);
163 closesocket(ServerSocket
);
164 closesocket(ClientSocket
);
166 /* same test but with waiting select and getsockname to return proper values */
167 ServerSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
168 ClientSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
170 if (ServerSocket
== INVALID_SOCKET
)
172 skip("ERROR: Server socket creation failed\n");
175 if (ClientSocket
== INVALID_SOCKET
)
177 skip("ERROR: Client socket creation failed\n");
178 closesocket(ServerSocket
);
181 ent
= gethostbyname("127.0.0.1");
184 ok(ent
!= NULL
, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n");
185 ent
= gethostbyname("localhost");
189 skip("ERROR: gethostbyname 'localhost' failed\n");
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);
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");
203 // Client initialization.
204 ok(ioctlsocket(ClientSocket
, FIONBIO
, &ulValue
) == 0, "ERROR: client ioctlsocket FIONBIO failed\n");
207 trace("Starting server listening mode ...\n");
208 ok(listen(ServerSocket
, SOMAXCONN
) == 0, "ERROR: cannot initialize server listen\n");
210 memset(&timeval
, 0, sizeof(timeval
));
211 timeval
.tv_usec
= WAIT_TIMEOUT_
;
214 while (dwFlags
!= EXIT_FLAGS
)
216 len
= sizeof(addr_con_loc
);
217 nSockNameRes
= getsockname(ClientSocket
, (struct sockaddr
*)&addr_con_loc
, &len
);
218 if (dwFlags
== 0 && !ConnectSent
)
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");
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");
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
);
237 if (addr_con_loc
.sin_addr
.s_addr
== 0ul)
239 if (++Addr_con_locLoopCount
>= MAX_LOOPCOUNT
)
241 ok(FALSE
, "Giving up, on getsockname() (%u/%u), as addr_con_loc is not set yet\n",
242 Addr_con_locLoopCount
, MAX_LOOPCOUNT
);
246 trace("Looping, for getsockname() (%u/%u), as addr_con_loc is not set yet\n",
247 Addr_con_locLoopCount
, MAX_LOOPCOUNT
);
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
);
255 if ((dwFlags
& FD_ACCEPT
) != 0)
257 trace("Select CONNECT...\n");
258 dwFlags
|= FD_CONNECT
;
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)
272 FD_SET(sockaccept
, &select_rfds
);
273 FD_SET(sockaccept
, &select_wfds
);
274 FD_SET(sockaccept
, &select_efds
);
276 if (select(0, &select_rfds
, &select_wfds
, &select_efds
, &timeval
) != 0)
277 {// connection accepted
278 if (dwFlags
== (FD_ACCEPT
| FD_CONNECT
))
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");
285 if (dwFlags
== FD_ACCEPT
)
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");
294 if (FD_ISSET(ServerSocket
, &select_rfds
))
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());
300 dwFlags
|= FD_ACCEPT
;
304 if (++ServerSocketLoopCount
>= MAX_LOOPCOUNT
)
306 ok(FALSE
, "Giving up, on select() (%u/%u), as ServerSocket is not readable yet\n",
307 ServerSocketLoopCount
, MAX_LOOPCOUNT
);
311 trace("Looping, for select() (%u/%u), as ServerSocket is not readable yet\n",
312 ServerSocketLoopCount
, MAX_LOOPCOUNT
);
321 WSACloseEvent(ServerEvent
);
322 WSACloseEvent(ClientEvent
);
323 closesocket(sockaccept
);
324 closesocket(ServerSocket
);
325 closesocket(ClientSocket
);