1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PURPOSE: Test for WSASocket 5 * PROGRAMMERS: Peter Hater 6 */ 7 8 #include "ws2_32.h" 9 10 void Test_CloseDuplicatedSocket() 11 { 12 char szBuf[10]; 13 int err; 14 SOCKET sck, dup_sck; 15 WSAPROTOCOL_INFOW ProtocolInfo; 16 struct sockaddr_in to = { AF_INET, 2222, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }; 17 18 /* Create the socket */ 19 sck = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 20 if(sck == INVALID_SOCKET) 21 { 22 skip("socket failed %d. Aborting test.\n", WSAGetLastError()); 23 return; 24 } 25 26 err = sendto(sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to)); 27 ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError()); 28 29 err = WSADuplicateSocketW(sck, GetCurrentProcessId(), &ProtocolInfo); 30 ok(err == 0, "WSADuplicateSocketW err = %d %d\n", err, WSAGetLastError()); 31 32 dup_sck = WSASocketW(0, 0, 0, &ProtocolInfo, 0, 0); 33 if (dup_sck == INVALID_SOCKET) 34 { 35 skip("WSASocketW failed %d. Aborting test.\n", WSAGetLastError()); 36 closesocket(sck); 37 return; 38 } 39 40 err = sendto(dup_sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to)); 41 ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError()); 42 43 err = closesocket(sck); 44 ok(err == 0, "closesocket sck err = %d %d\n", err, WSAGetLastError()); 45 46 err = sendto(dup_sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to)); 47 ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError()); 48 49 err = closesocket(dup_sck); 50 ok(err == 0, "closesocket dup_sck err = %d %d\n", err, WSAGetLastError()); 51 return; 52 } 53 54 // 100 ms 55 #define TIMEOUT_SEC 0 56 #define TIMEOUT_USEC 100000 57 58 // 250 ms 59 #define TIME_SLEEP1 250 60 61 #define THREAD_PROC_LOOPS 5 62 63 #define LISTEN_PORT 22222 64 #define LISTEN_BACKLOG 5 65 66 DWORD WINAPI thread_proc(void* param) 67 { 68 fd_set read, write, except; 69 struct timeval tval; 70 SOCKET sock = (SOCKET)param; 71 int i; 72 73 tval.tv_sec = TIMEOUT_SEC; 74 tval.tv_usec = TIMEOUT_USEC; 75 76 for (i = 0; i < THREAD_PROC_LOOPS; ++i) 77 { 78 FD_ZERO(&read); FD_ZERO(&write); FD_ZERO(&except); 79 // write will be empty 80 FD_SET(sock, &read); FD_SET(sock, &except); 81 82 select(0, &read, &write, &except, &tval); 83 } 84 85 return 0; 86 } 87 88 void Test_CloseWhileSelectSameSocket() 89 { 90 int err; 91 SOCKET sock; 92 struct sockaddr_in addrin; 93 HANDLE hthread; 94 95 /* Create the socket */ 96 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 97 if (sock == INVALID_SOCKET) 98 { 99 skip("socket failed %d. Aborting test.\n", WSAGetLastError()); 100 return; 101 } 102 103 memset(&addrin, 0, sizeof(struct sockaddr_in)); 104 addrin.sin_family = AF_INET; 105 addrin.sin_addr.s_addr = inet_addr("127.0.0.1"); 106 addrin.sin_port = htons(LISTEN_PORT); 107 108 err = bind(sock, (struct sockaddr*)(&addrin), sizeof(struct sockaddr_in)); 109 ok(err == 0, "bind err = %d %d\n", err, WSAGetLastError()); 110 err = listen(sock, LISTEN_BACKLOG); 111 ok(err == 0, "listen err = %d %d\n", err, WSAGetLastError()); 112 113 hthread = CreateThread(NULL, 0, thread_proc, (void*)sock, 0, NULL); 114 ok(hthread != NULL, "CreateThread %ld\n", GetLastError()); 115 116 Sleep(TIME_SLEEP1); 117 err = closesocket(sock); 118 ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError()); 119 120 WaitForSingleObject(hthread, INFINITE); 121 CloseHandle(hthread); 122 return; 123 } 124 125 void Test_CloseWhileSelectDuplicatedSocket() 126 { 127 int err; 128 SOCKET sock, dup_sock; 129 WSAPROTOCOL_INFOW ProtocolInfo; 130 struct sockaddr_in addrin; 131 HANDLE hthread; 132 133 /* Create the socket */ 134 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 135 if (sock == INVALID_SOCKET) 136 { 137 skip("socket failed %d. Aborting test.\n", WSAGetLastError()); 138 return; 139 } 140 141 memset(&addrin, 0, sizeof(struct sockaddr_in)); 142 addrin.sin_family = AF_INET; 143 addrin.sin_addr.s_addr = inet_addr("127.0.0.1"); 144 addrin.sin_port = htons(LISTEN_PORT); 145 146 err = bind(sock, (struct sockaddr*)(&addrin), sizeof(struct sockaddr_in)); 147 ok(err == 0, "bind err = %d %d\n", err, WSAGetLastError()); 148 err = listen(sock, LISTEN_BACKLOG); 149 ok(err == 0, "listen err = %d %d\n", err, WSAGetLastError()); 150 151 err = WSADuplicateSocketW(sock, GetCurrentProcessId(), &ProtocolInfo); 152 ok(err == 0, "WSADuplicateSocketW err = %d %d\n", err, WSAGetLastError()); 153 154 dup_sock = WSASocketW(0, 0, 0, &ProtocolInfo, 0, 0); 155 if (dup_sock == INVALID_SOCKET) 156 { 157 skip("WSASocketW failed %d. Aborting test.\n", WSAGetLastError()); 158 closesocket(sock); 159 return; 160 } 161 162 hthread = CreateThread(NULL, 0, thread_proc, (void*)dup_sock, 0, NULL); 163 ok(hthread != NULL, "CreateThread %ld\n", GetLastError()); 164 165 err = closesocket(sock); 166 ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError()); 167 168 Sleep(TIME_SLEEP1); 169 err = closesocket(dup_sock); 170 ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError()); 171 172 WaitForSingleObject(hthread, INFINITE); 173 CloseHandle(hthread); 174 return; 175 } 176 177 START_TEST(close) 178 { 179 int err; 180 WSADATA wdata; 181 182 /* Start up Winsock */ 183 err = WSAStartup(MAKEWORD(2, 2), &wdata); 184 ok(err == 0, "WSAStartup failed, iResult == %d %d\n", err, WSAGetLastError()); 185 186 Test_CloseDuplicatedSocket(); 187 Test_CloseWhileSelectSameSocket(); 188 Test_CloseWhileSelectDuplicatedSocket(); 189 190 WSACleanup(); 191 } 192 193