@@ -1695,8 +1695,16 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
1695
1695
/* Reset SSL socket state */
1696
1696
static void ssl_reset_sock_state (pj_ssl_sock_t * ssock )
1697
1697
{
1698
+ int post_unlock_flush_circ_buf = 0 ;
1699
+
1698
1700
ossl_sock_t * ossock = (ossl_sock_t * )ssock ;
1699
1701
1702
+ /* Must lock around SSL calls, particularly SSL_shutdown
1703
+ * as it can modify the write BIOs and destructively
1704
+ * interfere with any ssl_write() calls in progress
1705
+ * above in a multithreaded environment */
1706
+ pj_lock_acquire (ssock -> write_mutex );
1707
+
1700
1708
/* Detach from SSL instance */
1701
1709
if (ossock -> ossl_ssl ) {
1702
1710
SSL_set_ex_data (ossock -> ossl_ssl , sslsock_idx , NULL );
@@ -1710,15 +1718,21 @@ static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
1710
1718
if (ossock -> ossl_ssl && SSL_in_init (ossock -> ossl_ssl ) == 0 ) {
1711
1719
int ret = SSL_shutdown (ossock -> ossl_ssl );
1712
1720
if (ret == 0 ) {
1713
- /* Flush data to send close notify. */
1714
- flush_circ_buf_output (ssock , & ssock -> shutdown_op_key , 0 , 0 );
1721
+ /* SSL_shutdown will potentially trigger a bunch of
1722
+ * data to dump to the socket */
1723
+ post_unlock_flush_circ_buf = 1 ;
1715
1724
}
1716
1725
}
1717
1726
1718
- pj_lock_acquire (ssock -> write_mutex );
1719
1727
ssock -> ssl_state = SSL_STATE_NULL ;
1728
+
1720
1729
pj_lock_release (ssock -> write_mutex );
1721
1730
1731
+ if (post_unlock_flush_circ_buf ) {
1732
+ /* Flush data to send close notify. */
1733
+ flush_circ_buf_output (ssock , & ssock -> shutdown_op_key , 0 , 0 );
1734
+ }
1735
+
1722
1736
ssl_close_sockets (ssock );
1723
1737
1724
1738
/* Upon error, OpenSSL may leave any error description in the thread
@@ -2413,7 +2427,6 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
2413
2427
*/
2414
2428
pj_lock_acquire (ssock -> write_mutex );
2415
2429
* size = size_ = SSL_read (ossock -> ossl_ssl , data , size_ );
2416
- pj_lock_release (ssock -> write_mutex );
2417
2430
2418
2431
if (size_ <= 0 ) {
2419
2432
pj_status_t status ;
@@ -2436,15 +2449,22 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
2436
2449
/* Reset SSL socket state, then return PJ_FALSE */
2437
2450
status = STATUS_FROM_SSL_ERR2 ("Read" , ssock , size_ ,
2438
2451
err , len );
2452
+ pj_lock_release (ssock -> write_mutex );
2453
+ /* Unfortunately we can't hold the lock here to reset all the state.
2454
+ * We probably should though.
2455
+ */
2439
2456
ssl_reset_sock_state (ssock );
2440
2457
return status ;
2441
2458
}
2442
2459
}
2443
2460
2461
+ pj_lock_release (ssock -> write_mutex );
2444
2462
/* Need renegotiation */
2445
2463
return PJ_EEOF ;
2446
2464
}
2447
2465
2466
+ pj_lock_release (ssock -> write_mutex );
2467
+
2448
2468
return PJ_SUCCESS ;
2449
2469
}
2450
2470
0 commit comments