Skip to content

Commit d05cbd6

Browse files
yosuke-wolfsslejohnstown
authored andcommitted
apps/wolfssh, examples/client: resend stdin a send did not take
- readInput() in apps/wolfssh runs FlushQueuedSend() when wolfSSH_stream_send() returns WS_WANT_WRITE without taking the buffer, then sends the same buffer again; a failed flush still ends in "Couldn't send data". - readInput() in examples/client retries WS_WANT_WRITE as it retries WS_REKEYING, for up to SEND_RETRY_TIMEOUT (10) seconds per buffer. - The comment on the queued check in apps/wolfssh describes the positive-return case.
1 parent 48ca213 commit d05cbd6

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

‎apps/wolfssh/wolfssh.c‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ static THREAD_RET readInput(void* in)
523523
int ret = 0;
524524
int err = 0;
525525
int queued = 0;
526+
int resend = 0;
526527
word32 sz = 0;
527528
#ifdef USE_WINDOWS_API
528529
HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
@@ -549,16 +550,24 @@ static THREAD_RET readInput(void* in)
549550
ret = wolfSSH_stream_send(args->ssh, buf, sz);
550551
err = (ret == WS_FATAL_ERROR) ?
551552
wolfSSH_get_error(args->ssh) : ret;
552-
/* A send the socket wasn't ready for still counts the data as
553-
* taken, it is left queued in the session instead. */
553+
/* Data taken with a positive return can still be queued in the
554+
* session, waiting on the socket. */
554555
queued = (wolfSSH_get_error(args->ssh) == WS_WANT_WRITE);
555556
wc_UnLockMutex(&args->lock);
557+
resend = 0;
556558
if (err == WS_REKEYING) {
557559
/* give readPeer() the lock to finish the rekey, then
558560
* send this buffer again */
559561
PauseForSocket();
562+
resend = 1;
560563
}
561-
} while (err == WS_REKEYING);
564+
else if (ret <= 0 && err == WS_WANT_WRITE) {
565+
/* None of buf was taken. Push out what is queued, then send
566+
* buf again. */
567+
resend = (FlushQueuedSend(args->ssh, &args->lock)
568+
== WS_SUCCESS);
569+
}
570+
} while (resend);
562571
if (ret <= 0) {
563572
fprintf(stderr, "Couldn't send data\n");
564573
break;

‎examples/client/client.c‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ static int windowMonitor(thread_args* args)
346346
#endif /* WOLFSSH_TERM */
347347

348348

349+
/* Seconds to keep resending stdin the socket was not ready to take. */
350+
#define SEND_RETRY_TIMEOUT 10
351+
349352
static THREAD_RET readInput(void* in)
350353
{
351354
byte buf[256];
@@ -354,6 +357,7 @@ static THREAD_RET readInput(void* in)
354357
int ret = 0;
355358
int err = 0;
356359
word32 sz = 0;
360+
time_t deadline = 0;
357361
#ifdef USE_WINDOWS_API
358362
HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
359363
#endif
@@ -373,23 +377,32 @@ static THREAD_RET readInput(void* in)
373377
fprintf(stderr, "Error reading stdin\n");
374378
break;
375379
}
380+
deadline = 0;
376381
do {
377382
/* lock SSH structure access */
378383
wc_LockMutex(&args->lock);
379384
ret = wolfSSH_stream_send(args->ssh, buf, sz);
380385
err = (ret == WS_FATAL_ERROR) ?
381386
wolfSSH_get_error(args->ssh) : ret;
382387
wc_UnLockMutex(&args->lock);
388+
/* A rekey restarts the wait on the socket. */
383389
if (err == WS_REKEYING) {
384-
/* give readPeer() the lock to finish the rekey, then
385-
* send this buffer again */
390+
deadline = 0;
391+
}
392+
else if (err == WS_WANT_WRITE && deadline == 0) {
393+
deadline = WTIME(NULL) + SEND_RETRY_TIMEOUT;
394+
}
395+
if (err == WS_REKEYING || err == WS_WANT_WRITE) {
396+
/* give readPeer() the lock to finish the rekey, or let the
397+
* socket drain, then send this buffer again */
386398
#ifdef USE_WINDOWS_API
387399
Sleep(1);
388400
#else
389401
usleep(1000);
390402
#endif
391403
}
392-
} while (err == WS_REKEYING);
404+
} while (err == WS_REKEYING ||
405+
(err == WS_WANT_WRITE && WTIME(NULL) < deadline));
393406
if (ret <= 0) {
394407
fprintf(stderr, "Couldn't send data\n");
395408
break;

0 commit comments

Comments
 (0)