@@ -1173,7 +1173,10 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11731173 byte shellBuffer [EXAMPLE_BUFFER_SZ ];
11741174 byte channelBuffer [EXAMPLE_BUFFER_SZ ];
11751175 char * forcedCmd ;
1176- int windowFull = 0 ;
1176+ int windowFull = 0 ; /* Contains size of bytes from shellBuffer that did
1177+ * not get passed on to wolfSSH yet. This happens
1178+ * with window full errors or when rekeying. */
1179+ int wantWrite = 0 ;
11771180 int peerConnected = 1 ;
11781181 int stdoutEmpty = 0 ;
11791182
@@ -1423,7 +1426,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14231426 maxFd = sshFd ;
14241427
14251428 FD_ZERO (& writeFds );
1426- if (windowFull ) {
1429+ if (windowFull || wantWrite ) {
14271430 FD_SET (sshFd , & writeFds );
14281431 }
14291432
@@ -1452,10 +1455,10 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14521455 pending = 1 ; /* found some pending SSH data */
14531456 }
14541457
1455- if (windowFull || pending || FD_ISSET (sshFd , & readFds )) {
1458+ if (wantWrite || windowFull || pending || FD_ISSET (sshFd , & readFds )) {
14561459 word32 lastChannel = 0 ;
14571460
1458- windowFull = 0 ;
1461+ wantWrite = 0 ;
14591462 /* The following tries to read from the first channel inside
14601463 the stream. If the pending data in the socket is for
14611464 another channel, this will return an error with id
@@ -1466,24 +1469,31 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14661469 if (cnt_r < 0 ) {
14671470 rc = wolfSSH_get_error (ssh );
14681471 if (rc == WS_CHAN_RXD ) {
1469- if (lastChannel == shellChannelId ) {
1470- cnt_r = wolfSSH_ChannelIdRead (ssh , shellChannelId ,
1472+ if (!windowFull ) { /* don't rewrite channeldBuffer if full
1473+ * of windowFull left overs */
1474+ if (lastChannel == shellChannelId ) {
1475+ cnt_r = wolfSSH_ChannelIdRead (ssh , shellChannelId ,
14711476 channelBuffer ,
14721477 sizeof channelBuffer );
1473- if (cnt_r <= 0 )
1474- break ;
1475- cnt_w = (int )write (childFd ,
1476- channelBuffer , cnt_r );
1477- if (cnt_w <= 0 )
1478- break ;
1478+ if (cnt_r <= 0 )
1479+ break ;
1480+ cnt_w = (int )write (childFd ,
1481+ channelBuffer , cnt_r );
1482+ if (cnt_w <= 0 )
1483+ break ;
1484+ }
14791485 }
14801486 }
14811487 else if (rc == WS_CHANNEL_CLOSED ) {
14821488 peerConnected = 0 ;
14831489 continue ;
14841490 }
14851491 else if (rc == WS_WANT_WRITE ) {
1486- windowFull = 1 ;
1492+ wantWrite = 1 ;
1493+ continue ;
1494+ }
1495+ else if (rc == WS_REKEYING ) {
1496+ wantWrite = 1 ;
14871497 continue ;
14881498 }
14891499 else if (rc != WS_WANT_READ ) {
@@ -1495,17 +1505,22 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14951505 /* if the window was previously full, try resending the data */
14961506 if (windowFull ) {
14971507 cnt_w = wolfSSH_ChannelIdSend (ssh , shellChannelId ,
1498- shellBuffer , cnt_r );
1499- if (cnt_w == WS_WINDOW_FULL ) {
1500- windowFull = 1 ;
1508+ shellBuffer , windowFull );
1509+ if (cnt_w == WS_WINDOW_FULL || cnt_w == WS_REKEYING ) {
15011510 continue ;
15021511 }
15031512 else if (cnt_w == WS_WANT_WRITE ) {
1504- windowFull = 1 ;
1513+ wantWrite = 1 ;
15051514 continue ;
15061515 }
15071516 else {
1508- windowFull = 0 ;
1517+ windowFull -= cnt_w ;
1518+ if (windowFull > 0 ) {
1519+ WMEMMOVE (shellBuffer , shellBuffer + cnt_w , windowFull );
1520+ continue ;
1521+ }
1522+ if (windowFull < 0 )
1523+ windowFull = 0 ;
15091524 }
15101525 }
15111526
@@ -1524,12 +1539,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15241539 if (cnt_r > 0 ) {
15251540 cnt_w = wolfSSH_extended_data_send (ssh , shellBuffer ,
15261541 cnt_r );
1527- if (cnt_w == WS_WINDOW_FULL ) {
1528- windowFull = 1 ;
1542+ if (cnt_w > 0 && cnt_w < cnt_r ) { /* partial send */
1543+ windowFull = cnt_r - cnt_w ;
1544+ WMEMMOVE (shellBuffer , shellBuffer + cnt_w ,
1545+ windowFull );
1546+ }
1547+ else if (cnt_w == WS_WINDOW_FULL ||
1548+ cnt_w == WS_REKEYING ) {
1549+ windowFull = cnt_r ; /* save amount to be sent */
15291550 continue ;
15301551 }
15311552 else if (cnt_w == WS_WANT_WRITE ) {
1532- windowFull = 1 ;
1553+ wantWrite = 1 ;
15331554 continue ;
15341555 }
15351556 else if (cnt_w < 0 )
@@ -1556,12 +1577,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15561577 if (cnt_r > 0 ) {
15571578 cnt_w = wolfSSH_ChannelIdSend (ssh , shellChannelId ,
15581579 shellBuffer , cnt_r );
1559- if (cnt_w == WS_WINDOW_FULL ) {
1560- windowFull = 1 ;
1580+ if (cnt_w > 0 && cnt_w < cnt_r ) { /* partial send */
1581+ windowFull = cnt_r - cnt_w ;
1582+ WMEMMOVE (shellBuffer , shellBuffer + cnt_w ,
1583+ windowFull );
1584+ }
1585+ else if (cnt_w == WS_WINDOW_FULL ||
1586+ cnt_w == WS_REKEYING ) {
1587+ windowFull = cnt_r ; /* save amount to be sent */
15611588 continue ;
15621589 }
15631590 else if (cnt_w == WS_WANT_WRITE ) {
1564- windowFull = 1 ;
1591+ wantWrite = 1 ;
15651592 continue ;
15661593 }
15671594 else if (cnt_w < 0 ) {
@@ -1586,12 +1613,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15861613 if (cnt_r > 0 ) {
15871614 cnt_w = wolfSSH_ChannelIdSend (ssh , shellChannelId ,
15881615 shellBuffer , cnt_r );
1589- if (cnt_w == WS_WINDOW_FULL ) {
1590- windowFull = 1 ;
1616+ if (cnt_w > 0 && cnt_w < cnt_r ) { /* partial send */
1617+ windowFull = cnt_r - cnt_w ;
1618+ WMEMMOVE (shellBuffer , shellBuffer + cnt_w ,
1619+ windowFull );
1620+ }
1621+ else if (cnt_w == WS_WINDOW_FULL ||
1622+ cnt_w == WS_REKEYING ) {
1623+ windowFull = cnt_r ;
15911624 continue ;
15921625 }
15931626 else if (cnt_w == WS_WANT_WRITE ) {
1594- windowFull = 1 ;
1627+ wantWrite = 1 ;
15951628 continue ;
15961629 }
15971630 else if (cnt_w < 0 ) {
0 commit comments