Commit 4df2dc79 authored by Iurii Metelytsia's avatar Iurii Metelytsia Committed by Nathan Heldt-Sheller

[IOT-3286] IoTivity may hang on exit

1. Reference counter has been added to ssl adapter.
2. Waiting for ReceiveThread when the caipserver is stopped added.
Signed-off-by: default avatarIurii Metelytsia <i.metelytsia@samsung.com>
Change-Id: I3ccf95ff1c851fe0d3e70f75ed00fdb1fce7bf82
parent a9e1dcab
...@@ -111,8 +111,17 @@ CAResult_t CAinitSslAdapter(void); ...@@ -111,8 +111,17 @@ CAResult_t CAinitSslAdapter(void);
/** /**
* de-inits mbedTLS library and free the allocated memory. * de-inits mbedTLS library and free the allocated memory.
*
* @param[in] cleanup perform cleanup of allocated memory.
* If this flag is false, need to perform cleanup
* by calling CAcleanupSslAdapter.
*/
void CAdeinitSslAdapter(bool cleanup);
/**
* Free allocated memory
*/ */
void CAdeinitSslAdapter(void); void CAcleanupSslAdapter(void);
/** /**
* Performs TLS encryption of the CoAP PDU. * Performs TLS encryption of the CoAP PDU.
......
...@@ -431,6 +431,12 @@ static CAcloseSslConnectionCallback g_closeSslConnectionCallback = NULL; ...@@ -431,6 +431,12 @@ static CAcloseSslConnectionCallback g_closeSslConnectionCallback = NULL;
*/ */
static oc_mutex g_sslContextMutex = NULL; static oc_mutex g_sslContextMutex = NULL;
/**
* @var g_sslInterestedThreadsCount
* @brief The number of threads that use this module
*/
static int g_sslInterestedThreadsCount = 0;
/** /**
* @var g_sslCallback * @var g_sslCallback
* @brief callback to deliver the TLS handshake result * @brief callback to deliver the TLS handshake result
...@@ -1717,7 +1723,7 @@ static void StopRetransmit(void) ...@@ -1717,7 +1723,7 @@ static void StopRetransmit(void)
} }
} }
#endif #endif
void CAdeinitSslAdapter(void) void CAdeinitSslAdapter(bool cleanup)
{ {
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
...@@ -1753,8 +1759,34 @@ void CAdeinitSslAdapter(void) ...@@ -1753,8 +1759,34 @@ void CAdeinitSslAdapter(void)
// Unlock tlsContext mutex and de-initialize it // Unlock tlsContext mutex and de-initialize it
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
oc_mutex_free(g_sslContextMutex);
g_sslContextMutex = NULL; if (cleanup)
{
CAcleanupSslAdapter();
}
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s ", __func__);
}
void CAcleanupSslAdapter(void)
{
bool free_mutex = false;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
VERIFY_NON_NULL_VOID(g_sslContextMutex, NET_SSL_TAG, "context mutex is NULL");
oc_mutex_lock(g_sslContextMutex);
if (g_sslInterestedThreadsCount > 0 && --g_sslInterestedThreadsCount == 0)
{
free_mutex = true;
}
oc_mutex_unlock(g_sslContextMutex);
if (free_mutex)
{
oc_mutex_free(g_sslContextMutex);
g_sslContextMutex = NULL;
}
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s ", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s ", __func__);
} }
...@@ -1868,17 +1900,27 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1868,17 +1900,27 @@ CAResult_t CAinitSslAdapter(void)
g_sslContextMutex = oc_mutex_new_recursive(); g_sslContextMutex = oc_mutex_new_recursive();
VERIFY_NON_NULL_RET(g_sslContextMutex, NET_SSL_TAG, "oc_mutex_new_recursive failed", VERIFY_NON_NULL_RET(g_sslContextMutex, NET_SSL_TAG, "oc_mutex_new_recursive failed",
CA_MEMORY_ALLOC_FAILED); CA_MEMORY_ALLOC_FAILED);
oc_mutex_lock(g_sslContextMutex);
g_sslInterestedThreadsCount = 0;
} }
else else
{ {
OIC_LOG(INFO, NET_SSL_TAG, "Done already!"); OIC_LOG(INFO, NET_SSL_TAG, "Done already!");
return CA_STATUS_OK;
oc_mutex_lock(g_sslContextMutex);
if (NULL != g_caSslContext)
{
g_sslInterestedThreadsCount++;
oc_mutex_unlock(g_sslContextMutex);
return CA_STATUS_OK;
}
} }
// Lock tlsContext mutex and create tlsContext // Lock tlsContext mutex and create tlsContext
oc_mutex_lock(g_sslContextMutex); g_sslInterestedThreadsCount++;
g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
if (NULL == g_caSslContext) if (NULL == g_caSslContext)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Context malloc failed"); OIC_LOG(ERROR, NET_SSL_TAG, "Context malloc failed");
...@@ -1925,7 +1967,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1925,7 +1967,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Seed initialization failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Seed initialization failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_ON); mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_ON);
...@@ -1936,7 +1978,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1936,7 +1978,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
...@@ -1946,7 +1988,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1946,7 +1988,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
...@@ -1958,7 +2000,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1958,7 +2000,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Cookie setup failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Cookie setup failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
...@@ -1968,7 +2010,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1968,7 +2010,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
...@@ -1978,7 +2020,7 @@ CAResult_t CAinitSslAdapter(void) ...@@ -1978,7 +2020,7 @@ CAResult_t CAinitSslAdapter(void)
{ {
OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!"); OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!");
oc_mutex_unlock(g_sslContextMutex); oc_mutex_unlock(g_sslContextMutex);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
......
...@@ -2658,7 +2658,7 @@ static CAResult_t CAStartLE(void) ...@@ -2658,7 +2658,7 @@ static CAResult_t CAStartLE(void)
static CAResult_t CAStopLE(void) static CAResult_t CAStopLE(void)
{ {
#ifdef __WITH_DTLS__ #ifdef __WITH_DTLS__
CAdeinitSslAdapter(); CAdeinitSslAdapter(false);
#endif #endif
CAStopLEQueues(); CAStopLEQueues();
...@@ -2680,6 +2680,11 @@ static CAResult_t CAStopLE(void) ...@@ -2680,6 +2680,11 @@ static CAResult_t CAStopLE(void)
break; break;
} }
oc_mutex_unlock(g_bleIsServerMutex); oc_mutex_unlock(g_bleIsServerMutex);
#ifdef __WITH_DTLS__
CAcleanupSslAdapter();
#endif
return CAStopLEAdapter(); return CAStopLEAdapter();
} }
......
...@@ -550,7 +550,7 @@ CAResult_t CAReadIPData(void) ...@@ -550,7 +550,7 @@ CAResult_t CAReadIPData(void)
CAResult_t CAStopIP(void) CAResult_t CAStopIP(void)
{ {
#ifdef __WITH_DTLS__ #ifdef __WITH_DTLS__
CAdeinitSslAdapter(); CAdeinitSslAdapter(false);
#endif #endif
if (g_sendQueueHandle && g_sendQueueHandle->threadMutex) if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
...@@ -561,6 +561,10 @@ CAResult_t CAStopIP(void) ...@@ -561,6 +561,10 @@ CAResult_t CAStopIP(void)
CAIPStopNetworkMonitor(CA_ADAPTER_IP); CAIPStopNetworkMonitor(CA_ADAPTER_IP);
CAIPStopServer(); CAIPStopServer();
#ifdef __WITH_DTLS__
CAcleanupSslAdapter();
#endif
return CA_STATUS_OK; return CA_STATUS_OK;
} }
......
...@@ -153,6 +153,13 @@ static CAIPErrorHandleCallback g_ipErrorHandler = NULL; ...@@ -153,6 +153,13 @@ static CAIPErrorHandleCallback g_ipErrorHandler = NULL;
static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL; static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL;
static oc_mutex g_mutex = NULL;
static oc_cond g_condVar = NULL;
static CAResult_t CAIPCreateMutex(void);
static void CAIPDestroyMutex(void);
static CAResult_t CAIPCreateCond(void);
static void CAIPDestroyCond(void);
static void CAFindReadyMessage(void); static void CAFindReadyMessage(void);
#if !defined(WSA_WAIT_EVENT_0) #if !defined(WSA_WAIT_EVENT_0)
static void CASelectReturned(fd_set *readFds, int ret); static void CASelectReturned(fd_set *readFds, int ret);
...@@ -162,6 +169,47 @@ static void CAEventReturned(CASocketFd_t socket); ...@@ -162,6 +169,47 @@ static void CAEventReturned(CASocketFd_t socket);
static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags); static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags);
static CAResult_t CAIPCreateMutex(void)
{
if (!g_mutex)
{
if (NULL == (g_mutex = oc_mutex_new()))
{
OIC_LOG(ERROR, TAG, "Failed to created mutex!");
return CA_STATUS_FAILED;
}
}
return CA_STATUS_OK;
}
static void CAIPDestroyMutex(void)
{
if (g_mutex)
{
oc_mutex_free(g_mutex);
g_mutex = NULL;
}
}
static CAResult_t CAIPCreateCond(void)
{
if (!g_condVar)
{
if (NULL == (g_condVar = oc_cond_new()))
{
OIC_LOG(ERROR, TAG, "Failed to created cond!");
return CA_STATUS_FAILED;
}
}
return CA_STATUS_OK;
}
static void CAIPDestroyCond(void)
{
if (g_condVar)
{
oc_cond_free(g_condVar);
g_condVar = NULL;
}
}
static void CACloseFDs(void) static void CACloseFDs(void)
{ {
#if !defined(WSA_WAIT_EVENT_0) #if !defined(WSA_WAIT_EVENT_0)
...@@ -183,6 +231,10 @@ static void CAReceiveHandler(void *data) ...@@ -183,6 +231,10 @@ static void CAReceiveHandler(void *data)
CAFindReadyMessage(); CAFindReadyMessage();
} }
CACloseFDs(); CACloseFDs();
oc_mutex_lock(g_mutex);
oc_cond_signal(g_condVar);
oc_mutex_unlock(g_mutex);
} }
#define CLOSE_SOCKET(TYPE) \ #define CLOSE_SOCKET(TYPE) \
...@@ -1001,6 +1053,18 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool) ...@@ -1001,6 +1053,18 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
#endif #endif
res = CAIPCreateMutex();
if (CA_STATUS_OK == res)
{
res = CAIPCreateCond();
}
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "failed to create mutex/cond");
return res;
}
// set up appropriate FD mechanism for fast shutdown // set up appropriate FD mechanism for fast shutdown
CAInitializeFastShutdownMechanism(); CAInitializeFastShutdownMechanism();
...@@ -1033,6 +1097,20 @@ void CAIPStopServer(void) ...@@ -1033,6 +1097,20 @@ void CAIPStopServer(void)
{ {
caglobals.ip.terminate = true; caglobals.ip.terminate = true;
if (!caglobals.ip.started)
{
// Close fd's since receive handler was not started
CACloseFDs();
}
else
{
caglobals.ip.started = false;
// wait for thread finished
oc_mutex_lock(g_mutex);
oc_cond_wait_for(g_condVar, g_mutex, 300000);
oc_mutex_unlock(g_mutex);
}
#if !defined(WSA_WAIT_EVENT_0) #if !defined(WSA_WAIT_EVENT_0)
if (caglobals.ip.shutdownFds[1] != -1) if (caglobals.ip.shutdownFds[1] != -1)
{ {
...@@ -1052,11 +1130,8 @@ void CAIPStopServer(void) ...@@ -1052,11 +1130,8 @@ void CAIPStopServer(void)
} }
#endif #endif
if (!caglobals.ip.started) CAIPDestroyMutex();
{ // Close fd's since receive handler was not started CAIPDestroyCond();
CACloseFDs();
}
caglobals.ip.started = false;
} }
void CAWakeUpForChange(void) void CAWakeUpForChange(void)
......
...@@ -547,7 +547,7 @@ CAResult_t CAStopTCP() ...@@ -547,7 +547,7 @@ CAResult_t CAStopTCP()
CAInitializeTCPGlobals(); CAInitializeTCPGlobals();
#ifdef __WITH_TLS__ #ifdef __WITH_TLS__
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
#endif #endif
return CA_STATUS_OK; return CA_STATUS_OK;
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define GetCASecureEndpointAttributes GetCASecureEndpointAttributesTest #define GetCASecureEndpointAttributes GetCASecureEndpointAttributesTest
#define CAsetPeerCNVerifyCallback CAsetPeerCNVerifyCallbackTest #define CAsetPeerCNVerifyCallback CAsetPeerCNVerifyCallbackTest
#define CAsetCloseSslConnectionCallback CAsetCloseSslConnectionCallbackTest #define CAsetCloseSslConnectionCallback CAsetCloseSslConnectionCallbackTest
#define CAcleanupSslAdapter CAcleanupSslAdapterTest
#include "../src/adapter_util/ca_adapter_net_ssl.c" #include "../src/adapter_util/ca_adapter_net_ssl.c"
...@@ -1891,7 +1892,7 @@ static int testCAinitSslAdapter() ...@@ -1891,7 +1892,7 @@ static int testCAinitSslAdapter()
result = CAinitSslAdapter(); result = CAinitSslAdapter();
if (result == CA_STATUS_OK) if (result == CA_STATUS_OK)
{ {
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
} }
else else
{ {
...@@ -1958,7 +1959,7 @@ static int testCAsetSslAdapterCallbacks() ...@@ -1958,7 +1959,7 @@ static int testCAsetSslAdapterCallbacks()
ret += 1; ret += 1;
} }
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
return ret; return ret;
} }
...@@ -2269,7 +2270,7 @@ static void * testCAencryptSsl(void * arg) ...@@ -2269,7 +2270,7 @@ static void * testCAencryptSsl(void * arg)
CAcloseSslConnection(&serverAddr); CAcloseSslConnection(&serverAddr);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
socketClose(); socketClose();
...@@ -2657,7 +2658,7 @@ static void * testCAdecryptSsl(void * arg) ...@@ -2657,7 +2658,7 @@ static void * testCAdecryptSsl(void * arg)
CAcloseSslConnection(&serverAddr); CAcloseSslConnection(&serverAddr);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
socketClose(); socketClose();
...@@ -2739,7 +2740,7 @@ static int testCAdeinitSslAdapter() ...@@ -2739,7 +2740,7 @@ static int testCAdeinitSslAdapter()
CAsetTlsCipherSuite(SSL_ECDHE_ECDSA_WITH_AES_128_CCM); CAsetTlsCipherSuite(SSL_ECDHE_ECDSA_WITH_AES_128_CCM);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
if (g_caSslContext != NULL || if (g_caSslContext != NULL ||
g_sslContextMutex != NULL) g_sslContextMutex != NULL)
...@@ -2814,7 +2815,7 @@ static void * testServer(void * arg) ...@@ -2814,7 +2815,7 @@ static void * testServer(void * arg)
CAcloseSslConnection(&serverAddr); CAcloseSslConnection(&serverAddr);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
socketClose_server(); socketClose_server();
...@@ -3027,7 +3028,7 @@ static int testCAsetTlsCipherSuite() ...@@ -3027,7 +3028,7 @@ static int testCAsetTlsCipherSuite()
ret += 1; ret += 1;
} }
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
return ret; return ret;
} }
...@@ -3139,7 +3140,7 @@ TEST(TLSAdapter, Test_11) ...@@ -3139,7 +3140,7 @@ TEST(TLSAdapter, Test_11)
CAcloseSslConnection(&serverAddr); CAcloseSslConnection(&serverAddr);
CAdeinitSslAdapter(); CAdeinitSslAdapter(true);
socketClose(); socketClose();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment