Handle 0 bytes received as socket closed (#58)

* Handle 0 bytes received as socket closed

* Remove NuGet from build (wrong version but it shouldn't be needed at all)
This commit is contained in:
Matt Durak 2020-11-18 10:34:53 -08:00 коммит произвёл GitHub
Родитель a3300caadf
Коммит 9382bf53f7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 60 добавлений и 7 удалений

Просмотреть файл

@ -38,9 +38,6 @@ jobs:
filename: '"c:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat"'
modifyEnvironment: true
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 4.3.0 (required for .NET core assemblies)'
- task: CMake@1
displayName: 'CMake .. -Drun_unittests:bool=ON -Drun_int_tests:bool=ON -Duse_cppunittest:bool=ON -G "Visual Studio 16 2019" -A x64'
inputs:
@ -106,9 +103,6 @@ jobs:
filename: '"c:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat"'
modifyEnvironment: true
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 4.3.0 (required for .NET core assemblies)'
- task: CMake@1
displayName: 'CMake .. -Drun_unittests:bool=ON -Drun_int_tests:bool=ON -Duse_cppunittest:bool=ON -G "Visual Studio 16 2019" -A x64'
inputs:

Просмотреть файл

@ -200,3 +200,5 @@ Note: It is the responsibility of the caller to ensure the order of the receive
**SRS_ASYNC_SOCKET_01_044: [** When receiving completes successfully, `on_receive_complete` shall be called with `ASYNC_SOCKET_RECEIVE_OK`. **]**
**SRS_ASYNC_SOCKET_01_045: [** When receiving completes with error, `on_receive_complete` shall be called with `ASYNC_SOCKET_RECEIVE_ERROR`. **]**
**SRS_ASYNC_SOCKET_42_001: [** When receiving completes with 0 bytes received, `on_receive_complete` shall be called with `ASYNC_SOCKET_RECEIVE_ABANDONED`. **]**

Просмотреть файл

@ -291,7 +291,9 @@ static VOID CALLBACK on_io_complete(PTP_CALLBACK_INSTANCE instance, PVOID contex
- **SRS_ASYNC_SOCKET_WIN32_01_070: [** If `io_result` is not `NO_ERROR`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ERROR` as result and 0 for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_095: [**If `io_result` is `NO_ERROR`, but the number of bytes received is greater than the sum of all buffer sizes passed to `async_socket_receive_async`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ERROR` as result and `number_of_bytes_transferred` for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_095: [** If `io_result` is `NO_ERROR`, but the number of bytes received is greater than the sum of all buffer sizes passed to `async_socket_receive_async`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ERROR` as result and `number_of_bytes_transferred` for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_42_003: [** If `io_result` is `NO_ERROR`, but the number of bytes received is 0, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ABANDONED` as result and 0 for `bytes_received`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_068: [** `on_io_complete` shall close the event handle created in `async_socket_send_async`/`async_socket_receive_async`. **]**

Просмотреть файл

@ -156,6 +156,12 @@ static VOID WINAPI on_io_complete(PTP_CALLBACK_INSTANCE instance, PVOID context,
bytes_received, io_context->total_buffer_bytes);
receive_result = ASYNC_SOCKET_RECEIVE_ERROR;
}
else if (bytes_received == 0)
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_42_003: [ If io_result is NO_ERROR, but the number of bytes received is 0, the on_receive_complete callback passed to async_socket_receive_async shall be called with on_receive_complete_context as context, ASYNC_SOCKET_RECEIVE_ABANDONED as result and 0 for bytes_received. ]*/
LogError("Socket received 0 bytes, assuming socket is closed");
receive_result = ASYNC_SOCKET_RECEIVE_ABANDONED;
}
else
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_069: [ If io_result is NO_ERROR, the on_receive_complete callback passed to async_socket_receive_async shall be called with on_receive_complete_context as context, ASYNC_SOCKET_RECEIVE_OK as result and number_of_bytes_transferred as bytes_received. ]*/

Просмотреть файл

@ -2371,6 +2371,55 @@ TEST_FUNCTION(on_io_complete_with_error_indicates_the_receive_as_complete_with_E
async_socket_destroy(async_socket);
}
/* Tests_SRS_ASYNC_SOCKET_WIN32_42_003: [ If io_result is NO_ERROR, but the number of bytes received is 0, the on_receive_complete callback passed to async_socket_receive_async shall be called with on_receive_complete_context as context, ASYNC_SOCKET_RECEIVE_ABANDONED as result and 0 for bytes_received. ]*/
TEST_FUNCTION(on_io_complete_with_NO_ERROR_indicates_the_receive_as_complete_with_ABANDONED_with_0_bytes_received)
{
// arrange
ASYNC_SOCKET_HANDLE async_socket = async_socket_create(test_execution_engine, test_socket);
uint8_t payload_bytes[1];
ASYNC_SOCKET_BUFFER payload_buffers[1];
PTP_IO test_ptp_io;
PTP_WIN32_IO_CALLBACK test_on_io_complete;
PVOID test_ptp_io_context;
LPOVERLAPPED overlapped;
payload_buffers[0].buffer = payload_bytes;
payload_buffers[0].length = sizeof(payload_bytes);
umock_c_reset_all_calls();
STRICT_EXPECTED_CALL(mocked_InitializeThreadpoolEnvironment(IGNORED_ARG));
STRICT_EXPECTED_CALL(mocked_SetThreadpoolCallbackPool(IGNORED_ARG, test_pool));
STRICT_EXPECTED_CALL(mocked_CreateThreadpoolCleanupGroup());
STRICT_EXPECTED_CALL(mocked_CreateThreadpoolIo(test_socket, IGNORED_ARG, IGNORED_ARG, IGNORED_ARG))
.CaptureReturn(&test_ptp_io)
.CaptureArgumentValue_pv(&test_ptp_io_context)
.CaptureArgumentValue_pfnio(&test_on_io_complete);
(void)async_socket_open_async(async_socket, test_on_open_complete, (void*)0x4242);
umock_c_reset_all_calls();
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
STRICT_EXPECTED_CALL(mocked_CreateEventA(NULL, FALSE, FALSE, NULL));
STRICT_EXPECTED_CALL(mocked_StartThreadpoolIo(test_ptp_io));
STRICT_EXPECTED_CALL(mocked_WSARecv((SOCKET)test_socket, IGNORED_ARG, 1, NULL, IGNORED_ARG, IGNORED_ARG, NULL))
.CaptureArgumentValue_lpOverlapped(&overlapped)
.SetReturn(SOCKET_ERROR);
STRICT_EXPECTED_CALL(mocked_WSAGetLastError())
.SetReturn(WSA_IO_PENDING);
(void)async_socket_receive_async(async_socket, payload_buffers, sizeof(payload_buffers) / sizeof(payload_buffers[0]), test_on_receive_complete, (void*)0x4244);
umock_c_reset_all_calls();
STRICT_EXPECTED_CALL(test_on_receive_complete((void*)0x4244, ASYNC_SOCKET_RECEIVE_ABANDONED, 0));
STRICT_EXPECTED_CALL(mocked_CloseHandle(IGNORED_ARG));
STRICT_EXPECTED_CALL(free(IGNORED_ARG));
// act
test_on_io_complete(NULL, test_ptp_io_context, overlapped, NO_ERROR, (ULONG_PTR)0, test_ptp_io);
// assert
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
// cleanup
async_socket_destroy(async_socket);
}
static void on_io_complete_with_error_indicates_the_receive_as_complete_with_ABANDONED(ULONG error_code)
{
// arrange