diff options
author | Liong Sauw Ming <ming@teluu.com> | 2016-06-14 10:28:19 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2016-06-14 10:28:19 +0000 |
commit | 5c501dbfeb072cb6dc36b400358e21d6d615eba1 (patch) | |
tree | e95eda827a61332988613bed4dd816322b672641 /pjlib | |
parent | 78bf67e1d5dc32e877e490edb1b927776c539523 (diff) |
Re #1930: Fixed race condition when more than one thread try to close the same activesock.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5343 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r-- | pjlib/src/pj/ssl_sock_ossl.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index e59c24cf..835d86f1 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -812,15 +812,29 @@ static void destroy_ssl(pj_ssl_sock_t *ssock) /* Close sockets */ static void close_sockets(pj_ssl_sock_t *ssock) { - if (ssock->asock) { - pj_activesock_close(ssock->asock); - ssock->asock = NULL; - ssock->sock = PJ_INVALID_SOCKET; - } - if (ssock->sock != PJ_INVALID_SOCKET) { - pj_sock_close(ssock->sock); - ssock->sock = PJ_INVALID_SOCKET; - } + pj_activesock_t *asock; + pj_sock_t sock; + + /* This can happen when pj_ssl_sock_create() fails. */ + if (!ssock->write_mutex) + return; + + pj_lock_acquire(ssock->write_mutex); + asock = ssock->asock; + if (asock) { + ssock->asock = NULL; + ssock->sock = PJ_INVALID_SOCKET; + } + sock = ssock->sock; + if (sock != PJ_INVALID_SOCKET) + ssock->sock = PJ_INVALID_SOCKET; + pj_lock_release(ssock->write_mutex); + + if (asock) + pj_activesock_close(asock); + + if (sock != PJ_INVALID_SOCKET) + pj_sock_close(sock); } @@ -1945,18 +1959,24 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock, status = pj_timer_heap_schedule(ssock->param.timer_heap, &ssock->timer, &ssock->param.timeout); - if (status != PJ_SUCCESS) + if (status != PJ_SUCCESS) { ssock->timer.id = TIMER_NONE; + status = PJ_SUCCESS; + } } /* Start SSL handshake */ ssock->ssl_state = SSL_STATE_HANDSHAKING; SSL_set_accept_state(ssock->ossl_ssl); - status = do_handshake(ssock); + //To avoid race condition, we don't need to do it here and + //let the handshake happen in ssock->asock's callback instead. + //status = do_handshake(ssock); on_return: - if (ssock && status != PJ_EPENDING) - on_handshake_complete(ssock, status); + if (ssock && status != PJ_SUCCESS) { + //on_handshake_complete(ssock, status); + close_sockets(ssock); + } /* Must return PJ_TRUE whatever happened, as active socket must * continue listening. @@ -2863,8 +2883,10 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock, status = pj_timer_heap_schedule(ssock->param.timer_heap, &ssock->timer, &ssock->param.timeout); - if (status != PJ_SUCCESS) + if (status != PJ_SUCCESS) { ssock->timer.id = TIMER_NONE; + status = PJ_SUCCESS; + } } status = pj_activesock_start_connect(ssock->asock, pool, remaddr, |