@@ -1233,6 +1233,15 @@ fn handle_handshake_complete(
12331233 }
12341234 }
12351235
1236+ // CRITICAL: Ensure all pending TLS data is sent before returning
1237+ // TLS 1.3 Finished must reach server before handshake is considered complete
1238+ // Without this, server may not process application data
1239+ if !socket. is_bio_mode ( ) {
1240+ socket
1241+ . blocking_flush_all_pending ( vm)
1242+ . map_err ( SslError :: Py ) ?;
1243+ }
1244+
12361245 Ok ( true )
12371246}
12381247
@@ -1307,11 +1316,12 @@ pub(super) fn ssl_do_handshake(
13071316 conn. send_close_notify ( ) ;
13081317 // Flush any pending TLS data before sending close_notify
13091318 let _ = socket. flush_pending_tls_output ( vm) ;
1310- // Actually send the close_notify alert
1319+ // Actually send the close_notify alert using send_all_bytes
1320+ // for proper partial send handling and retry logic
13111321 if let Ok ( alert_data) = ssl_write_tls_records ( conn)
13121322 && !alert_data. is_empty ( )
13131323 {
1314- let _ = socket . sock_send ( alert_data, vm) ;
1324+ let _ = send_all_bytes ( socket , alert_data, vm) ;
13151325 }
13161326 }
13171327
@@ -1477,11 +1487,38 @@ pub(super) fn ssl_read(
14771487 // Check if connection needs to write data first (e.g., TLS key update, renegotiation)
14781488 // This mirrors the handshake logic which checks both wants_read() and wants_write()
14791489 if conn. wants_write ( ) && !is_bio {
1490+ // Check deadline BEFORE attempting flush
1491+ if let Some ( deadline) = deadline
1492+ && std:: time:: Instant :: now ( ) >= deadline
1493+ {
1494+ return Err ( SslError :: Timeout (
1495+ "The read operation timed out" . to_string ( ) ,
1496+ ) ) ;
1497+ }
1498+
14801499 // Flush pending TLS data before continuing
14811500 let tls_data = ssl_write_tls_records ( conn) ?;
14821501 if !tls_data. is_empty ( ) {
1483- send_all_bytes ( socket, tls_data, vm) ?;
1502+ // Use best-effort send - don't fail READ just because WRITE couldn't complete
1503+ match send_all_bytes ( socket, tls_data, vm) {
1504+ Ok ( ( ) ) => { }
1505+ Err ( SslError :: WantWrite ) => {
1506+ // Socket buffer full - acceptable during READ operation
1507+ // Pending data will be sent on next write/read call
1508+ }
1509+ Err ( e) => return Err ( e) ,
1510+ }
14841511 }
1512+
1513+ // Check deadline AFTER flush attempt
1514+ if let Some ( deadline) = deadline
1515+ && std:: time:: Instant :: now ( ) >= deadline
1516+ {
1517+ return Err ( SslError :: Timeout (
1518+ "The read operation timed out" . to_string ( ) ,
1519+ ) ) ;
1520+ }
1521+
14851522 // After flushing, rustls may want to read again - continue loop
14861523 continue ;
14871524 }
0 commit comments