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 14 START_TEST(WSAAsync) 15 { 16 WSADATA WsaData; 17 SOCKET ServerSocket = INVALID_SOCKET, 18 ClientSocket = INVALID_SOCKET; 19 WSAEVENT ServerEvent = WSA_INVALID_EVENT, 20 ClientEvent = WSA_INVALID_EVENT; 21 struct hostent *ent = NULL; 22 struct sockaddr_in server_addr_in; 23 struct sockaddr_in addr_remote; 24 struct sockaddr_in addr_con_loc; 25 int nConRes, nSockNameRes; 26 int addrsize, len; 27 WSAEVENT fEvents[2]; 28 SOCKET fSockets[2]; 29 SOCKET sockaccept; 30 WSANETWORKEVENTS WsaNetworkEvents; 31 ULONG ulValue = 1; 32 DWORD dwWait; 33 DWORD dwFlags = 0; 34 struct fd_set select_rfds; 35 struct fd_set select_wfds; 36 struct fd_set select_efds; 37 struct timeval timeval; 38 BOOL ConnectSent = FALSE; 39 40 if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0) 41 { 42 skip("WSAStartup failed\n"); 43 return; 44 } 45 46 ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 47 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 48 ServerEvent = WSACreateEvent(); 49 ClientEvent = WSACreateEvent(); 50 51 if (ServerSocket == INVALID_SOCKET) 52 { 53 skip("ERROR: Server socket creation failed\n"); 54 return; 55 } 56 if (ClientSocket == INVALID_SOCKET) 57 { 58 skip("ERROR: Client socket creation failed\n"); 59 closesocket(ServerSocket); 60 return; 61 } 62 if (ServerEvent == WSA_INVALID_EVENT) 63 { 64 skip("ERROR: Server WSAEvent creation failed\n"); 65 closesocket(ClientSocket); 66 closesocket(ServerSocket); 67 return; 68 } 69 if (ClientEvent == WSA_INVALID_EVENT) 70 { 71 skip("ERROR: Client WSAEvent creation failed\n"); 72 WSACloseEvent(ServerEvent); 73 closesocket(ClientSocket); 74 closesocket(ServerSocket); 75 return; 76 } 77 ent = gethostbyname("127.0.0.1"); 78 if (ent == NULL) 79 { 80 ok(ent != NULL, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n"); 81 ent = gethostbyname("localhost"); 82 83 if (ent == NULL) 84 { 85 skip("ERROR: gethostbyname 'localhost' failed\n"); 86 goto done; 87 } 88 } 89 90 server_addr_in.sin_family = AF_INET; 91 server_addr_in.sin_port = htons(SVR_PORT); 92 memcpy(&server_addr_in.sin_addr.S_un.S_addr, ent->h_addr_list[0], 4); 93 94 // Server initialization. 95 trace("Initializing server and client connections ...\n"); 96 ok(bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)) == 0, "ERROR: server bind failed\n"); 97 ok(ioctlsocket(ServerSocket, FIONBIO, &ulValue) == 0, "ERROR: server ioctlsocket FIONBIO failed\n"); 98 ok(WSAEventSelect(ServerSocket, ServerEvent, FD_ACCEPT | FD_CLOSE) == 0, "ERROR: server accept EventSelect failed\n"); 99 100 // Client initialization. 101 ok(WSAEventSelect(ClientSocket, ClientEvent, FD_CONNECT | FD_CLOSE) == 0, "ERROR: client EventSelect failed\n"); 102 ok(ioctlsocket(ClientSocket, FIONBIO, &ulValue) == 0, "ERROR: client ioctlsocket FIONBIO failed\n"); 103 104 // listen 105 trace("Starting server listening mode ...\n"); 106 ok(listen(ServerSocket, SOMAXCONN) == 0, "ERROR: cannot initialize server listen\n"); 107 108 trace("Starting client to server connection ...\n"); 109 // connect 110 nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)); 111 ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n"); 112 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n"); 113 114 fSockets[0] = ServerSocket; 115 fSockets[1] = ClientSocket; 116 117 fEvents[0] = ServerEvent; 118 fEvents[1] = ClientEvent; 119 120 while (dwFlags != EXIT_FLAGS) 121 { 122 dwWait = WaitForMultipleObjects(2, fEvents, FALSE, WAIT_TIMEOUT_); 123 124 if (dwWait != WAIT_OBJECT_0 && // server socket event 125 dwWait != WAIT_OBJECT_0+1) // client socket event 126 { 127 ok(0, "Unknown event received %ld\n", dwWait); 128 skip("ERROR: Connection timeout\n"); 129 break; 130 } 131 132 WSAEnumNetworkEvents(fSockets[dwWait-WAIT_OBJECT_0], fEvents[dwWait-WAIT_OBJECT_0], &WsaNetworkEvents); 133 134 if ((WsaNetworkEvents.lNetworkEvents & FD_ACCEPT) != 0) 135 {// connection accepted 136 trace("Event FD_ACCEPT...\n"); 137 ok(WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0, "Error on accept %d\n", WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT]); 138 if (WsaNetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0) 139 { 140 addrsize = sizeof(addr_remote); 141 sockaccept = accept(fSockets[dwWait - WAIT_OBJECT_0], (struct sockaddr*)&addr_remote, &addrsize); 142 ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError()); 143 dwFlags |= FD_ACCEPT; 144 } 145 } 146 147 if ((WsaNetworkEvents.lNetworkEvents & FD_CONNECT) != 0) 148 {// client connected 149 trace("Event FD_CONNECT...\n"); 150 ok(WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT] == 0, "Error on connect %d\n", WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT]); 151 if (WsaNetworkEvents.iErrorCode[FD_CONNECT_BIT] == 0) 152 { 153 len = sizeof(addr_con_loc); 154 ok(getsockname(fSockets[dwWait - WAIT_OBJECT_0], (struct sockaddr*)&addr_con_loc, &len) == 0, "\n"); 155 dwFlags |= FD_CONNECT; 156 } 157 } 158 } 159 closesocket(sockaccept); 160 closesocket(ServerSocket); 161 closesocket(ClientSocket); 162 163 /* same test but with waiting select and getsockname to return proper values */ 164 ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 165 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 166 167 if (ServerSocket == INVALID_SOCKET) 168 { 169 skip("ERROR: Server socket creation failed\n"); 170 return; 171 } 172 if (ClientSocket == INVALID_SOCKET) 173 { 174 skip("ERROR: Client socket creation failed\n"); 175 closesocket(ServerSocket); 176 return; 177 } 178 ent = gethostbyname("127.0.0.1"); 179 if (ent == NULL) 180 { 181 ok(ent != NULL, "ERROR: gethostbyname '127.0.0.1' failed, trying 'localhost'\n"); 182 ent = gethostbyname("localhost"); 183 184 if (ent == NULL) 185 { 186 skip("ERROR: gethostbyname 'localhost' failed\n"); 187 goto done; 188 } 189 } 190 191 server_addr_in.sin_family = AF_INET; 192 server_addr_in.sin_port = htons(SVR_PORT); 193 memcpy(&server_addr_in.sin_addr.S_un.S_addr, ent->h_addr_list[0], 4); 194 195 // Server initialization. 196 trace("Initializing server and client connections ...\n"); 197 ok(bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)) == 0, "ERROR: server bind failed\n"); 198 ok(ioctlsocket(ServerSocket, FIONBIO, &ulValue) == 0, "ERROR: server ioctlsocket FIONBIO failed\n"); 199 200 // Client initialization. 201 ok(ioctlsocket(ClientSocket, FIONBIO, &ulValue) == 0, "ERROR: client ioctlsocket FIONBIO failed\n"); 202 203 // listen 204 trace("Starting server listening mode ...\n"); 205 ok(listen(ServerSocket, SOMAXCONN) == 0, "ERROR: cannot initialize server listen\n"); 206 207 memset(&timeval, 0, sizeof(timeval)); 208 timeval.tv_usec = WAIT_TIMEOUT_; 209 dwFlags = 0; 210 211 while (dwFlags != EXIT_FLAGS) 212 { 213 len = sizeof(addr_con_loc); 214 nSockNameRes = getsockname(ClientSocket, (struct sockaddr*)&addr_con_loc, &len); 215 if (dwFlags == 0 && !ConnectSent) 216 { 217 ok(nSockNameRes == SOCKET_ERROR, "ERROR: getsockname function failed, expected %d error %d\n", SOCKET_ERROR, nSockNameRes); 218 ok(WSAGetLastError() == WSAEINVAL, "ERROR: getsockname function failed, expected %ld error %d\n", WSAEINVAL, WSAGetLastError()); 219 trace("Starting client to server connection ...\n"); 220 // connect 221 nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)); 222 ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n"); 223 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n"); 224 ConnectSent = TRUE; 225 continue; 226 } 227 else 228 { 229 if (nSockNameRes != 0) 230 ok(0, "ERROR: getsockname function failed, expected %d error %d\n", 0, nSockNameRes); 231 if (len != sizeof(addr_con_loc)) 232 ok(0, "ERROR: getsockname function wrong size, expected %d returned %d\n", sizeof(addr_con_loc), len); 233 if (addr_con_loc.sin_addr.s_addr != server_addr_in.sin_addr.s_addr) 234 ok(0, "ERROR: getsockname function wrong addr, expected %lx returned %lx\n", server_addr_in.sin_addr.s_addr, addr_con_loc.sin_addr.s_addr); 235 } 236 if ((dwFlags & FD_ACCEPT) != 0) 237 {// client connected 238 trace("Select CONNECT...\n"); 239 dwFlags |= FD_CONNECT; 240 } 241 242 FD_ZERO(&select_rfds); 243 FD_ZERO(&select_wfds); 244 FD_ZERO(&select_efds); 245 FD_SET(ServerSocket, &select_rfds); 246 FD_SET(ClientSocket, &select_rfds); 247 FD_SET(ServerSocket, &select_wfds); 248 FD_SET(ClientSocket, &select_wfds); 249 FD_SET(ServerSocket, &select_efds); 250 FD_SET(ClientSocket, &select_efds); 251 if ((dwFlags & FD_ACCEPT) != 0) 252 { 253 FD_SET(sockaccept, &select_rfds); 254 FD_SET(sockaccept, &select_wfds); 255 FD_SET(sockaccept, &select_efds); 256 } 257 if (select(0, &select_rfds, &select_wfds, &select_efds, &timeval) != 0) 258 {// connection accepted 259 if (dwFlags == (FD_ACCEPT | FD_CONNECT)) 260 { 261 trace("Select ACCEPT&CONNECT...\n"); 262 ok(FD_ISSET(ClientSocket, &select_wfds), "ClientSocket is not writable\n"); 263 ok(FD_ISSET(sockaccept, &select_wfds), "sockaccept is not writable\n"); 264 ok(!FD_ISSET(ServerSocket, &select_rfds), "ServerSocket is readable\n"); 265 } 266 if (dwFlags == FD_ACCEPT) 267 { 268 trace("Select ACCEPT...\n"); 269 ok(!FD_ISSET(ClientSocket, &select_wfds), "ClientSocket is writable\n"); 270 ok(FD_ISSET(sockaccept, &select_wfds), "sockaccept is not writable\n"); 271 ok(FD_ISSET(ServerSocket, &select_rfds), "ServerSocket is not readable\n"); 272 } 273 if (dwFlags == 0) 274 { 275 if (FD_ISSET(ServerSocket, &select_rfds)) 276 { 277 trace("Select ACCEPT...\n"); 278 addrsize = sizeof(addr_remote); 279 sockaccept = accept(ServerSocket, (struct sockaddr*)&addr_remote, &addrsize); 280 ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError()); 281 dwFlags |= FD_ACCEPT; 282 } 283 } 284 } 285 } 286 287 done: 288 WSACloseEvent(ServerEvent); 289 WSACloseEvent(ClientEvent); 290 closesocket(sockaccept); 291 closesocket(ServerSocket); 292 closesocket(ClientSocket); 293 294 WSACleanup(); 295 } 296