Run threaded api-test SFTP/SCP tests on Windows

pull/1122/head
Yosuke Shimizu 2026-06-15 16:42:40 +09:00 committed by John Safranek
parent 53047bd8c7
commit 5acbeaeaee
10 changed files with 190 additions and 53 deletions

View File

@ -139,12 +139,13 @@ jobs:
run: nuget restore ${{env.WOLFSSL_SOLUTION_FILE_PATH}}
# These env paths already include the wolfssh/ and wolfssl/ checkout
# prefixes, so they must run from the workspace root (as the build job does).
- name: updated user_settings.h for sshd and x509
run: cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
- name: replace wolfSSL user_settings.h with wolfSSH user_settings.h
run: get-content ${{env.USER_SETTINGS_H_NEW}} | %{$_ -replace "if 0","if 1"}
# prefixes, so this runs from the default working directory, the workspace
# root.
- name: Enable wolfSSH options (sshd, sftp, x509) in user_settings.h
shell: bash
run: |
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
# WholeProgramOptimization=false disables /GL so the v142-independent objects
# link without a cross-version code-generation requirement (C1047).

View File

@ -2249,6 +2249,11 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
int count = 0;
while (strList) {
if (WSTRLEN(strList->str) >= sizeof names - 1) {
fprintf(stderr, "Ignoring over-long entry: %.32s\n", strList->str);
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
passwd = WSTRCHR(names, ':');
if (passwd != NULL) {
@ -2278,6 +2283,11 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList,
int count = 0;
while (strList) {
if (WSTRLEN(strList->str) >= sizeof names - 1) {
fprintf(stderr, "Ignoring over-long entry: %.32s\n", strList->str);
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
passwd = WSTRCHR(names, ':');
if (passwd != NULL) {
@ -2314,6 +2324,11 @@ static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
buf = NULL;
bufSz = 0;
if (WSTRLEN(strList->str) >= sizeof names - 1) {
fprintf(stderr, "Ignoring over-long entry: %.32s\n", strList->str);
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
fileName = WSTRCHR(names, ':');
if (fileName != NULL) {
@ -2834,6 +2849,12 @@ static INLINE void SignalTcpReady(tcp_ready* ready, word16 port)
ready->port = port;
pthread_cond_signal(&ready->cond);
pthread_mutex_unlock(&ready->mutex);
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
ready->ready = 1;
ready->port = port;
/* SetEvent is a full barrier; this one-shot signal needs no lock */
SetEvent(ready->readyEvent);
#else
WOLFSSH_UNUSED(ready);
WOLFSSH_UNUSED(port);
@ -2979,7 +3000,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
}
else {
port = (word16)atoi(myoptarg);
#if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
#if !defined(NO_MAIN_DRIVER)
if (port == 0) {
ES_ERROR("port number cannot be 0");
}

View File

@ -156,6 +156,7 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
static word32 lastOutputTime = 0;
static word32 lastPrintedBytes[2] = {0, 0};
word32 elapsedTime;
word32 nameSz;
#endif
char buf[80];
word64 longBytes = ((word64)bytes[1] << 32) | bytes[0];
@ -176,13 +177,19 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
}
lastPrintedBytes[0] = bytes[0];
lastPrintedBytes[1] = bytes[1];
if (WSTRNCMP(currentFile, name, WSTRLEN(name)) != 0) {
/* clamp over-long names: currentFile holds the truncated prefix, so the
* comparison must use the same bound or every call looks like a new file */
nameSz = (word32)WSTRLEN(name);
if (nameSz >= sizeof(currentFile))
nameSz = (word32)sizeof(currentFile) - 1;
if (WSTRNCMP(currentFile, name, nameSz) != 0 ||
currentFile[nameSz] != '\0') {
startTime = current_time(1);
lastOutputTime = 0; /* Reset timer for new file transfer */
lastPrintedBytes[0] = 0;
lastPrintedBytes[1] = 0;
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME);
WMEMSET(currentFile, 0, sizeof(currentFile));
WMEMCPY(currentFile, name, nameSz);
}
elapsedTime = currentTime - startTime;
WSNPRINTF(buf, sizeof(buf), "Processed %8llu\t bytes in %d seconds\r",
@ -191,7 +198,7 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
if (elapsedTime > TIMEOUT_VALUE) {
WSNPRINTF(buf, sizeof(buf), "\nProcess timed out at %d seconds, "
"stopping\r", elapsedTime);
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WMEMSET(currentFile, 0, sizeof(currentFile));
wolfSSH_SFTP_Interrupt(ssh);
}
#endif
@ -667,7 +674,7 @@ static int doCmds(func_args* args)
ret == WS_CHAN_RXD || ret == WS_REKEYING);
#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WMEMSET(currentFile, 0, sizeof(currentFile));
#endif
if (ret != WS_SUCCESS) {
@ -778,7 +785,7 @@ static int doCmds(func_args* args)
ret == WS_CHAN_RXD || ret == WS_REKEYING);
#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WMEMSET(currentFile, 0, sizeof(currentFile));
#endif
if (ret != WS_SUCCESS) {
@ -1445,6 +1452,7 @@ static int doAutopilot(int cmd, char* local, char* remote)
int ret = WS_SUCCESS;
char fullpath[128] = ".";
WS_SFTPNAME* name = NULL;
word32 remoteSz;
byte remoteAbsPath = 0;
/* check if is absolute path before making it one */
@ -1462,8 +1470,11 @@ static int doAutopilot(int cmd, char* local, char* remote)
if (remoteAbsPath) {
/* use remote absolute path if provided */
remoteSz = (word32)WSTRLEN(remote);
if (remoteSz >= sizeof(fullpath))
return WS_BUFFER_E;
WMEMSET(fullpath, 0, sizeof(fullpath));
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
WMEMCPY(fullpath, remote, remoteSz + 1);
}
else {
err = doBuildRemotePath(remote, fullpath, sizeof(fullpath), &name);

View File

@ -1952,12 +1952,19 @@ int wolfSSH_SCP_connect(WOLFSSH* ssh, byte* cmd)
}
/* Shared format so the size probe and the write cannot drift. */
#define SCP_CMD_FMT "scp -%c %s"
static char* MakeScpCmd(const char* name, char dir, void* heap)
{
char* cmd;
int sz;
sz = WSNPRINTF(NULL, 0, "scp -%c %s", dir, name) + 1;
#ifdef USE_WINDOWS_API
sz = WSCPRINTF(SCP_CMD_FMT, dir, name) + 1;
#else
sz = WSNPRINTF(NULL, 0, SCP_CMD_FMT, dir, name) + 1;
#endif
if (sz <= 0) {
return NULL;
}
@ -1965,7 +1972,7 @@ static char* MakeScpCmd(const char* name, char dir, void* heap)
if (cmd == NULL) {
return NULL;
}
sz = WSNPRINTF(cmd, sz, "scp -%c %s", dir, name);
sz = WSNPRINTF(cmd, sz, SCP_CMD_FMT, dir, name);
if (sz <= 0) {
WFREE(cmd, heap, DYNTYPE_STRING);
return NULL;
@ -2717,10 +2724,15 @@ static ScpDir* ScpNewDir(void *fs, const char* path, void* heap)
int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
{
ScpDir* entry;
word32 pathSz;
if (ctx == NULL || path == NULL)
return WS_BAD_ARGUMENT;
pathSz = (word32)WSTRLEN(path);
if (pathSz >= sizeof(ctx->dirName))
return WS_BUFFER_E;
entry = ScpNewDir(fs, path, heap);
if (entry == NULL) {
return WS_FATAL_ERROR;
@ -2734,13 +2746,28 @@ int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
ctx->currentDir = entry;
}
/* append directory name to ctx->dirName */
WSTRNCPY(ctx->dirName, path, DEFAULT_SCP_FILE_NAME_SZ-1);
ctx->dirName[DEFAULT_SCP_FILE_NAME_SZ-1] = '\0';
/* append directory name to ctx->dirName, terminator included; the guard
* above bounds pathSz so the copy always fits */
WMEMCPY(ctx->dirName, path, pathSz + 1);
return WS_SUCCESS;
}
#ifdef WOLFSSH_TEST_INTERNAL
int wolfSSH_TestScpPushDir(const char* path)
{
ScpSendCtx ctx;
int ret;
WMEMSET(&ctx, 0, sizeof(ctx));
ret = ScpPushDir(NULL, &ctx, path, NULL);
if (ret == WS_SUCCESS)
ScpSendCtxFreeDirs(NULL, &ctx, NULL);
return ret;
}
#endif /* WOLFSSH_TEST_INTERNAL */
/* Remove top ScpDir from directory stack, remove dir from ctx->dirName */
int ScpPopDir(void *fs, ScpSendCtx* ctx, void* heap)
{

View File

@ -1687,6 +1687,20 @@ static void test_wolfSSH_agent_signrequest_success(void)
#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT) && \
!defined(SINGLE_THREADED)
/* A peer gone at shutdown is not a failure: the send path returns the reset,
* the recv path returns generic WS_ERROR with the code in wolfSSH_get_error.
* WS_SOCKET_ERROR_E is generic, so a real shutdown failure is tolerated too. */
static int AbsorbBenignReset(WOLFSSH* ssh, int ret)
{
if (ret == WS_SOCKET_ERROR_E ||
(ret == WS_ERROR &&
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
ret = WS_SUCCESS;
}
return ret;
}
byte userPassword[256];
static int sftpUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
@ -1820,10 +1834,8 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -2004,11 +2016,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
wolfSSH_worker(ssh, NULL);
}
argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
/* If the socket is closed on shutdown, peer is gone, this is OK. */
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
@ -2030,6 +2038,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}
@ -2090,10 +2099,8 @@ static void test_wolfSSH_SFTP_PartialSend(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -2279,10 +2286,7 @@ static void test_wolfSSH_SFTP_PartialSend(void)
wolfSSH_worker(ssh, NULL);
}
argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
argsCount = WS_SUCCESS;
@ -2299,6 +2303,7 @@ static void test_wolfSSH_SFTP_PartialSend(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
#endif /* WOLFSSH_TEST_INTERNAL */
}
@ -2330,10 +2335,8 @@ static void sftp_rekey_test(int nonBlock)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -2417,9 +2420,7 @@ static void sftp_rekey_test(int nonBlock)
* before the WS_REKEYING fixup below could otherwise mask it. The loop cap
* is one above the assert threshold to leave last-iteration headroom. */
AssertIntLE(tries, SFTP_REKEY_MAX_TRIES);
if (argsCount == WS_SOCKET_ERROR_E) {
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, argsCount);
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
/* in cases where highwater mark is really small a re-key could happen */
@ -2437,6 +2438,7 @@ static void sftp_rekey_test(int nonBlock)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}
static void test_wolfSSH_SFTP_ReKey(void)
@ -2615,10 +2617,8 @@ static void test_wolfSSH_SFTP_Confinement(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -2791,10 +2791,7 @@ static void test_wolfSSH_SFTP_Confinement(void)
while (wolfSSH_get_error(ssh) == WS_REKEYING)
wolfSSH_worker(ssh, NULL);
ret = wolfSSH_shutdown(ssh);
if (ret == WS_SOCKET_ERROR_E) {
ret = WS_SUCCESS;
}
ret = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (ret == WS_REKEYING) {
ret = WS_SUCCESS;
@ -2809,6 +2806,7 @@ static void test_wolfSSH_SFTP_Confinement(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
/* remove staged targets; escMkdir/escDest only exist if confinement
* leaked, and inJailDir only if the positive-case RMDIR did not run, so
@ -3184,10 +3182,8 @@ static void scp_rekey_test(int nonBlock, int toServer)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -3282,6 +3278,7 @@ static void scp_rekey_test(int nonBlock, int toServer)
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
ThreadJoin(serThread);
FreeTcpReady(&ready);
/* verify the transferred file matches the source once the server is done */
AssertIntEQ(scpFilesMatch(verifyName, fileData, SCP_REKEY_FILE_SZ), 0);
@ -4035,10 +4032,8 @@ static void test_wolfSSH_KeyboardInteractive(void)
args[argsCount++] = "-1";
args[argsCount++] = "-i";
args[argsCount++] = "test:test";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
@ -4051,11 +4046,7 @@ static void test_wolfSSH_KeyboardInteractive(void)
AssertNotNull(ssh);
argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
/* If the socket is closed on shutdown, peer is gone, this is OK. */
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
@ -4077,6 +4068,7 @@ static void test_wolfSSH_KeyboardInteractive(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}
#else /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */
@ -4095,6 +4087,8 @@ int wolfSSH_ApiTest(int argc, char** argv)
#ifdef WOLFSSH_TEST_BLOCK
return 77;
#else
WSTARTTCP();
AssertIntEQ(wolfSSH_Init(), WS_SUCCESS);
#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2)

View File

@ -1836,6 +1836,7 @@ static void test_client(void)
if (!unbalanced) {
AssertIntEQ(serverArgs.return_code, WS_SUCCESS);
}
FreeTcpReady(&ready);
}
static void test_basic_KeyboardInteractive(void)

View File

@ -8875,6 +8875,39 @@ static int test_ScpExtractFileName(void)
}
#endif /* WOLFSSH_TEST_INTERNAL && WOLFSSH_SCP && !WOLFSSH_SCP_USER_CALLBACKS */
#if defined(WOLFSSH_TEST_INTERNAL) && defined(WOLFSSH_SCP) && \
!defined(WOLFSSH_SCP_USER_CALLBACKS) && !defined(NO_FILESYSTEM)
/* ScpPushDir bounds the request path against ctx->dirName before copying it.
* The accept side stops short of WS_SUCCESS because no directory that long
* exists to open, so it asserts the guard did not fire rather than success. */
static int test_ScpPushDir(void)
{
char path[DEFAULT_SCP_FILE_NAME_SZ + 1];
int ret;
/* one byte too long for ctx->dirName: rejected before anything is opened */
WMEMSET(path, 'a', DEFAULT_SCP_FILE_NAME_SZ);
path[DEFAULT_SCP_FILE_NAME_SZ] = '\0';
ret = wolfSSH_TestScpPushDir(path);
if (ret != WS_BUFFER_E)
return -913;
/* exact fit clears the length guard and fails at the open instead */
path[DEFAULT_SCP_FILE_NAME_SZ - 1] = '\0';
ret = wolfSSH_TestScpPushDir(path);
if (ret == WS_BUFFER_E)
return -914;
/* NULL path is rejected */
ret = wolfSSH_TestScpPushDir(NULL);
if (ret != WS_BAD_ARGUMENT)
return -915;
return 0;
}
#endif /* WOLFSSH_TEST_INTERNAL && WOLFSSH_SCP &&
* !WOLFSSH_SCP_USER_CALLBACKS && !NO_FILESYSTEM */
#endif /* WOLFSSH_TEST_INTERNAL */
/* Error Code And Message Test */
@ -9497,6 +9530,14 @@ int wolfSSH_UnitTest(int argc, char** argv)
testResult = testResult || unitResult;
#endif
#if defined(WOLFSSH_TEST_INTERNAL) && defined(WOLFSSH_SCP) && \
!defined(WOLFSSH_SCP_USER_CALLBACKS) && !defined(NO_FILESYSTEM)
unitResult = test_ScpPushDir();
printf("ScpPushDir: %s\n",
(unitResult == 0 ? "SUCCESS" : "FAILED"));
testResult = testResult || unitResult;
#endif
#ifdef WOLFSSH_TEST_CAPTURING_ALLOCATOR
unitResult = test_SshResourceFree_zeroesSecrets();
printf("SshResourceFree_zeroesSecrets: %s\n",

View File

@ -1533,6 +1533,9 @@ enum WS_MessageIdLimits {
word32 bufSz, word32* inOutIdx);
WOLFSSH_API int wolfSSH_TestScpGetTimestamp(WOLFSSH* ssh, byte* buf,
word32 bufSz, word32* inOutIdx);
#if !defined(WOLFSSH_SCP_USER_CALLBACKS) && !defined(NO_FILESYSTEM)
WOLFSSH_API int wolfSSH_TestScpPushDir(const char* path);
#endif
#endif /* WOLFSSH_SCP */
#ifndef WOLFSSH_NO_DH
WOLFSSH_API int wolfSSH_TestKeyAgreeDh_client(WOLFSSH* ssh, byte hashId,

View File

@ -642,6 +642,14 @@ extern "C" {
#endif
#endif /* WSTRING_USER */
/* Measures a formatted string's length; _snprintf_s rejects the NULL/0 probe
* form that WSNPRINTF maps to on Windows. Defined outside WSTRING_USER so
* custom string ports need not supply it, and left overridable. */
#if defined(USE_WINDOWS_API) && !defined(WSCPRINTF)
#include <stdio.h>
#define WSCPRINTF(f,...) _scprintf((f),##__VA_ARGS__)
#endif
/* get local time for debug print out */
#if defined(USE_WINDOWS_API) || defined(__MINGW32__)
#define WTIME time

View File

@ -687,7 +687,7 @@ static INLINE void tcp_listen(WS_SOCKET_T* sockfd, word16* port, int useAnyAddr)
err_sys("tcp listen failed");
#endif
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) && !defined(WOLFSSL_NUCLEUS)
#if !defined(WOLFSSL_TIRTOS) && !defined(WOLFSSL_NUCLEUS)
if (*port == 0) {
socklen_t len = sizeof(addr);
if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
@ -837,6 +837,8 @@ typedef struct tcp_ready {
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
pthread_mutex_t mutex;
pthread_cond_t cond;
#elif defined(USE_WINDOWS_API)
HANDLE readyEvent; /* manual-reset event, set when ready */
#endif
} tcp_ready;
@ -860,6 +862,14 @@ typedef struct func_args {
#ifdef WOLFSSH_TEST_LOCKING
#if defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
/* Upper bound on the wait for the server to become ready. The signal fires
* right after the listen() so the real wait is sub-second; this generous
* bound only keeps a dead server from hanging the run. */
#define TCP_READY_TIMEOUT_MS 30000
#endif
static INLINE void InitTcpReady(tcp_ready* ready)
{
ready->ready = 0;
@ -869,6 +879,12 @@ static INLINE void InitTcpReady(tcp_ready* ready)
!defined(__MINGW32__) && !defined(SINGLE_THREADED)
pthread_mutex_init(&ready->mutex, NULL);
pthread_cond_init(&ready->cond, NULL);
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
ready->readyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ready->readyEvent == NULL) {
err_sys("Create tcp ready event failed");
}
#endif
}
@ -879,6 +895,12 @@ static INLINE void FreeTcpReady(tcp_ready* ready)
!defined(__MINGW32__) && !defined(SINGLE_THREADED)
pthread_mutex_destroy(&ready->mutex);
pthread_cond_destroy(&ready->cond);
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
if (ready->readyEvent != NULL) {
CloseHandle(ready->readyEvent);
ready->readyEvent = NULL;
}
#else
WOLFSSH_UNUSED(ready);
#endif
@ -902,6 +924,14 @@ static INLINE void WaitTcpReady(tcp_ready* ready)
* seems to help. This is not ideal. (XXX) */
k_sleep(Z_TIMEOUT_TICKS(300));
#endif /* WOLFSSH_ZEPHYR */
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
/* timeout or unset predicate means the server never signalled; abort
* so the failure points at startup, not a later bogus connect */
if (WaitForSingleObject(ready->readyEvent, TCP_READY_TIMEOUT_MS)
!= WAIT_OBJECT_0 || !ready->ready) {
err_sys("wait for tcp ready failed");
}
#else
WOLFSSH_UNUSED(ready);
#endif