@@ -1132,11 +1132,21 @@ static int sftp_worker(thread_ctx_t* threadCtx)
11321132 WS_SOCKET_T sockfd ;
11331133 int select_ret = 0 ;
11341134
1135+ error = wolfSSH_get_error (threadCtx -> ssh );
11351136 sockfd = (WS_SOCKET_T )wolfSSH_get_fd (threadCtx -> ssh );
11361137 do {
11371138 if (threadCtx -> nonBlock ) {
1138- if (error == WS_WANT_READ )
1139+ if (error == WS_WANT_READ ) {
1140+ WOLFSSH_CHANNEL * c ;
11391141 printf ("... sftp server would read block\n" );
1142+
1143+ /* if all channels are closed then close connection */
1144+ c = wolfSSH_ChannelNext (threadCtx -> ssh , NULL );
1145+ if (c && wolfSSH_ChannelGetEof (c )) {
1146+ ret = 0 ;
1147+ break ;
1148+ }
1149+ }
11401150 else if (error == WS_WANT_WRITE ) {
11411151 word32 c ;
11421152 printf ("... sftp server would write block\n" );
@@ -1148,24 +1158,31 @@ static int sftp_worker(thread_ctx_t* threadCtx)
11481158 }
11491159 }
11501160
1151- if (wolfSSH_stream_peek (threadCtx -> ssh , tmp , 1 ) > 0 ) {
1152- select_ret = WS_SELECT_RECV_READY ;
1161+ /* if there is a current send in progress then continue to process it */
1162+ if (wolfSSH_SFTP_PendingSend (threadCtx -> ssh )) {
1163+ ret = wolfSSH_SFTP_read (threadCtx -> ssh );
1164+ error = wolfSSH_get_error (threadCtx -> ssh );
11531165 }
11541166 else {
1155- select_ret = tcp_select (sockfd , TEST_SFTP_TIMEOUT );
1156- }
1167+ if (wolfSSH_stream_peek (threadCtx -> ssh , tmp , 1 ) > 0 ) {
1168+ select_ret = WS_SELECT_RECV_READY ;
1169+ }
1170+ else {
1171+ select_ret = tcp_select (sockfd , TEST_SFTP_TIMEOUT );
1172+ }
11571173
1158- if (select_ret == WS_SELECT_RECV_READY ||
1159- select_ret == WS_SELECT_ERROR_READY ||
1160- error == WS_WANT_WRITE )
1161- {
1162- ret = wolfSSH_SFTP_read (threadCtx -> ssh );
1163- error = wolfSSH_get_error (threadCtx -> ssh );
1174+ if (select_ret == WS_SELECT_RECV_READY ||
1175+ select_ret == WS_SELECT_ERROR_READY ||
1176+ error == WS_WANT_WRITE )
1177+ {
1178+ ret = wolfSSH_SFTP_read (threadCtx -> ssh );
1179+ error = wolfSSH_get_error (threadCtx -> ssh );
1180+ }
1181+ else if (select_ret == WS_SELECT_TIMEOUT )
1182+ error = WS_WANT_READ ;
1183+ else
1184+ error = WS_FATAL_ERROR ;
11641185 }
1165- else if (select_ret == WS_SELECT_TIMEOUT )
1166- error = WS_WANT_READ ;
1167- else
1168- error = WS_FATAL_ERROR ;
11691186
11701187 if (error == WS_WANT_READ || error == WS_WANT_WRITE ||
11711188 error == WS_CHAN_RXD || error == WS_REKEYING ||
@@ -1181,7 +1198,7 @@ static int sftp_worker(thread_ctx_t* threadCtx)
11811198 }
11821199 }
11831200
1184- } while (ret != WS_FATAL_ERROR );
1201+ } while (ret != WS_FATAL_ERROR && ret != WS_SOCKET_ERROR_E );
11851202
11861203 return ret ;
11871204}
@@ -1279,8 +1296,43 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
12791296 }
12801297
12811298 if (error != WS_SOCKET_ERROR_E && error != WS_FATAL_ERROR ) {
1282- if (wolfSSH_shutdown (threadCtx -> ssh ) != WS_SUCCESS ) {
1283- fprintf (stderr , "Error with SSH shutdown.\n" );
1299+ ret = wolfSSH_shutdown (threadCtx -> ssh );
1300+
1301+ /* peer hung up, stop shutdown */
1302+ if (ret == WS_SOCKET_ERROR_E ) {
1303+ ret = 0 ;
1304+ }
1305+
1306+ error = wolfSSH_get_error (threadCtx -> ssh );
1307+ if (error != WS_SOCKET_ERROR_E &&
1308+ (error == WS_WANT_READ || error == WS_WANT_WRITE )) {
1309+ int maxAttempt = 10 ; /* make 10 attempts max before giving up */
1310+ int attempt ;
1311+
1312+ for (attempt = 0 ; attempt < maxAttempt ; attempt ++ ) {
1313+ ret = wolfSSH_worker (threadCtx -> ssh , NULL );
1314+ error = wolfSSH_get_error (threadCtx -> ssh );
1315+
1316+ /* peer succesfully closed down gracefully */
1317+ if (ret == WS_CHANNEL_CLOSED ) {
1318+ ret = 0 ;
1319+ break ;
1320+ }
1321+
1322+ /* peer hung up, stop shutdown */
1323+ if (ret == WS_SOCKET_ERROR_E ) {
1324+ ret = 0 ;
1325+ break ;
1326+ }
1327+
1328+ if (error != WS_WANT_READ && error != WS_WANT_WRITE ) {
1329+ break ;
1330+ }
1331+ }
1332+
1333+ if (attempt == maxAttempt ) {
1334+ printf ("Gave up on gracefull shutdown, closing the socket\n" );
1335+ }
12841336 }
12851337 }
12861338
@@ -1838,11 +1890,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
18381890 break ;
18391891
18401892 case 'p' :
1841- port = (word16 )atoi (myoptarg );
1842- #if !defined(NO_MAIN_DRIVER ) || defined(USE_WINDOWS_API )
1843- if (port == 0 )
1844- err_sys ("port number cannot be 0" );
1845- #endif
1893+ if (myoptarg == NULL ) {
1894+ err_sys ("NULL port value" );
1895+ }
1896+ else {
1897+ port = (word16 )atoi (myoptarg );
1898+ #if !defined(NO_MAIN_DRIVER ) || defined(USE_WINDOWS_API )
1899+ if (port == 0 )
1900+ err_sys ("port number cannot be 0" );
1901+ #endif
1902+ }
18461903 break ;
18471904
18481905 case 'R' :
0 commit comments