ReactOS  0.4.15-dev-3165-gdf6fff7
WSAAsync.c File Reference
#include "ws2_32.h"
Include dependency graph for WSAAsync.c:

Go to the source code of this file.

Macros

#define SVR_PORT   5000
 
#define WAIT_TIMEOUT_   10000
 
#define EXIT_FLAGS   (FD_ACCEPT|FD_CONNECT)
 
#define MAX_LOOPCOUNT   9u
 

Functions

 START_TEST (WSAAsync)
 

Macro Definition Documentation

◆ EXIT_FLAGS

#define EXIT_FLAGS   (FD_ACCEPT|FD_CONNECT)

Definition at line 12 of file WSAAsync.c.

◆ MAX_LOOPCOUNT

#define MAX_LOOPCOUNT   9u

Definition at line 13 of file WSAAsync.c.

◆ SVR_PORT

#define SVR_PORT   5000

Definition at line 10 of file WSAAsync.c.

◆ WAIT_TIMEOUT_

#define WAIT_TIMEOUT_   10000

Definition at line 11 of file WSAAsync.c.

Function Documentation

◆ START_TEST()

START_TEST ( WSAAsync  )

Definition at line 15 of file WSAAsync.c.

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());
146  dwFlags |= FD_ACCEPT;
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");
158  dwFlags |= FD_CONNECT;
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");
258  dwFlags |= FD_CONNECT;
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());
300  dwFlags |= FD_ACCEPT;
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 
320 done:
321  WSACloseEvent(ServerEvent);
322  WSACloseEvent(ClientEvent);
323  closesocket(sockaccept);
325  closesocket(ClientSocket);
326 
327  WSACleanup();
328 }
Definition: winsock.h:66
#define SOCKET_ERROR
Definition: winsock.h:333
#define MAX_LOOPCOUNT
Definition: WSAAsync.c:13
char ** h_addr_list
Definition: winsock.h:138
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define FD_ACCEPT
Definition: winsock.h:408
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define FD_CONNECT
Definition: winsock.h:409
#define TRUE
Definition: types.h:120
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define WSAEINVAL
Definition: winerror.h:1946
#define WSAEVENT
Definition: winsock2.h:585
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define ioctlsocket
Definition: ncftp.h:481
#define FD_CONNECT_BIT
Definition: winsock2.h:301
#define closesocket
Definition: ncftp.h:477
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
#define SVR_PORT
Definition: WSAAsync.c:10
#define WSA_INVALID_EVENT
Definition: winsock2.h:595
#define SOMAXCONN
Definition: winsock.h:399
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FD_ISSET(fd, set)
Definition: winsock.h:100
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
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
unsigned long tv_usec
Definition: linux.h:1739
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define WAIT_OBJECT_0
Definition: winbase.h:403
#define FD_CLOSE
Definition: winsock.h:410
#define trace
Definition: atltest.h:70
#define INVALID_SOCKET
Definition: winsock.h:332
unsigned long DWORD
Definition: ntddk_ex.h:95
INT WSAAPI WSAEnumNetworkEvents(IN SOCKET s, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents)
Definition: event.c:94
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define FIONBIO
Definition: winsock.h:149
#define EXIT_FLAGS
Definition: WSAAsync.c:12
int iErrorCode[FD_MAX_EVENTS]
Definition: winsock2.h:644
#define FD_ACCEPT_BIT
Definition: winsock2.h:299
WSAEVENT WSAAPI WSACreateEvent(VOID)
Definition: event.c:42
#define htons(x)
Definition: module.h:213
#define WAIT_TIMEOUT_
Definition: WSAAsync.c:11
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
SOCKET ServerSocket
Definition: socket.c:3
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
#define skip(...)
Definition: atltest.h:64
unsigned int ULONG
Definition: retypes.h:1
#define AF_INET
Definition: tcpip.h:117
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCK_STREAM
Definition: tcpip.h:118
#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