From: hyuna0213.jo Date: Thu, 19 Jan 2017 23:58:30 +0000 (+0900) Subject: Replace u_array_list data structure with linked-list in catcpserver X-Git-Tag: 1.3.0~720 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce3a4e081b14cd28edc8a99da3866785c8e55546;p=platform%2Fupstream%2Fiotivity.git Replace u_array_list data structure with linked-list in catcpserver Change-Id: I00560bbadf9a1b04864d6676e7605f9ed876d8b9 Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/16613 Tested-by: jenkins-iotivity Reviewed-by: jihwan seo Reviewed-by: Dan Mihai Reviewed-by: Ashok Babu Channa --- diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index f971ec7..bf99f27 100755 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -613,7 +613,6 @@ typedef struct CASocket_t ipv4s; /**< IPv4 accept socket secure */ CASocket_t ipv6; /**< IPv6 accept socket */ CASocket_t ipv6s; /**< IPv6 accept socket secure */ - void *svrlist; /**< unicast IPv4 TCP server information*/ int selectTimeout; /**< in seconds */ int listenBacklog; /**< backlog counts*/ #if defined(_WIN32) diff --git a/resource/csdk/connectivity/inc/catcpadapter.h b/resource/csdk/connectivity/inc/catcpadapter.h index 4801a03..eb232dd 100644 --- a/resource/csdk/connectivity/inc/catcpadapter.h +++ b/resource/csdk/connectivity/inc/catcpadapter.h @@ -55,9 +55,9 @@ typedef enum } CATCPConnectionState_t; /** - * TCP Session Information for IPv4 TCP transport + * TCP Session Information for IPv4/IPv6 TCP transport */ -typedef struct +typedef struct CATCPSessionInfo_t { CASecureEndpoint_t sep; /**< secure endpoint information */ int fd; /**< file descriptor info */ @@ -69,6 +69,7 @@ typedef struct CAProtocol_t protocol; /**< application-level protocol */ CATCPConnectionState_t state; /**< current tcp session state */ bool isClient; /**< Host Mode of Operation. */ + struct CATCPSessionInfo_t *next; /**< Linked list; for multiple session list. */ } CATCPSessionInfo_t; /** diff --git a/resource/csdk/connectivity/inc/catcpinterface.h b/resource/csdk/connectivity/inc/catcpinterface.h index 1befc26..90b2354 100644 --- a/resource/csdk/connectivity/inc/catcpinterface.h +++ b/resource/csdk/connectivity/inc/catcpinterface.h @@ -177,10 +177,10 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint); /** * Disconnect from TCP Server. * - * @param[in] index current session index in list. + * @param[in] removedData removed session information from list. * @return ::CA_STATUS_OK or Appropriate error code. */ -CAResult_t CADisconnectTCPSession(size_t index); +CAResult_t CADisconnectTCPSession(CATCPSessionInfo_t *removedData); /** * Disconnect all connection from TCP Server. @@ -191,11 +191,9 @@ void CATCPDisconnectAll(); * Get TCP connection information from list. * * @param[in] endpoint remote endpoint information. - * @param[out] index index of array list. * @return TCP Session Information structure. */ -CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint, - size_t *index); +CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint); /** * Get total length from CoAP over TCP header. @@ -209,10 +207,9 @@ size_t CAGetTotalLengthFromHeader(const unsigned char *recvBuffer); * Get session information from socket file descriptor. * * @param[in] fd socket file descriptor. - * @param[out] index index of array list * @return TCP Server Information structure. */ -CATCPSessionInfo_t *CAGetSessionInfoFromFD(CASocketFd_t fd, size_t *index); +CATCPSessionInfo_t *CAGetSessionInfoFromFD(CASocketFd_t fd); /** * Get socket file descriptor from remote device information. diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c index b75f89f..6bdc2b0 100755 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c @@ -172,10 +172,9 @@ void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, #else unsigned char *buffer = (unsigned char*)data; size_t bufferLen = dataLength; - size_t index = 0; //get remote device information from file descriptor. - CATCPSessionInfo_t *svritem = CAGetTCPSessionInfoFromEndpoint(&sep->endpoint, &index); + CATCPSessionInfo_t *svritem = CAGetTCPSessionInfoFromEndpoint(&sep->endpoint); if (!svritem) { OIC_LOG(ERROR, TAG, "there is no connection information in list"); @@ -307,7 +306,6 @@ static void CAInitializeTCPGlobals() caglobals.tcp.selectTimeout = CA_TCP_SELECT_TIMEOUT; caglobals.tcp.listenBacklog = CA_TCP_LISTEN_BACKLOG; - caglobals.tcp.svrlist = NULL; CATransportFlags_t flags = 0; if (caglobals.client) diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c index 6b2a758..4042592 100644 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@ -59,12 +59,14 @@ #include "catcpinterface.h" #include "caipnwmonitor.h" -#include #include "caadapterutils.h" #include "octhread.h" #include "oic_malloc.h" #include "oic_string.h" +#include +#include + #ifdef __WITH_TLS__ #include "ca_adapter_net_ssl.h" #endif @@ -110,6 +112,11 @@ static CATCPErrorHandleCallback g_tcpErrorHandler = NULL; */ static CATCPConnectionHandleCallback g_connectionCallback = NULL; +/** + * Store the connected TCP session information. + */ +static CATCPSessionInfo_t *g_sessionList = NULL; + static CAResult_t CATCPCreateMutex(); static void CATCPDestroyMutex(); static CAResult_t CATCPCreateCond(); @@ -233,14 +240,12 @@ static void CAFindReadyMessage() FD_SET(caglobals.tcp.connectionFds[0], &readFds); } - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; i < length; i++) + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session) { - CATCPSessionInfo_t *svritem = - (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i); - if (svritem && 0 <= svritem->fd && CONNECTED == svritem->state) + if (session && session->fd != OC_INVALID_SOCKET && session->state == CONNECTED) { - FD_SET(svritem->fd, &readFds); + FD_SET(session->fd, &readFds); } } @@ -307,16 +312,14 @@ static void CASelectReturned(fd_set *readFds) } else { - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; i < length; i++) + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session) { - CATCPSessionInfo_t *svritem = - (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i); - if (svritem && svritem->fd >= 0) + if (session && session->fd != OC_INVALID_SOCKET) { - if (FD_ISSET(svritem->fd, readFds)) + if (FD_ISSET(session->fd, readFds)) { - CAReceiveMessage(svritem->fd); + CAReceiveMessage(session->fd); } } } @@ -422,14 +425,12 @@ static void CAFindReadyMessage() while (!caglobals.tcp.terminate) { - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; (i < length) && (arraySize < EVENT_ARRAY_SIZE); i++) + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session); { - CATCPSessionInfo_t *svritem = - (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i); - if (svritem && OC_INVALID_SOCKET != svritem->fd) + if (session && OC_INVALID_SOCKET != session->fd && (arraySize < EVENT_ARRAY_SIZE)) { - CAPushSocket(svritem->fd, socketArray, eventArray, &arraySize, _countof(socketArray)); + CAPushSocket(session->fd, socketArray, eventArray, &arraySize, _countof(socketArray)); } } @@ -547,15 +548,7 @@ static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock) svritem->sep.endpoint.addr, &svritem->sep.endpoint.port); oc_mutex_lock(g_mutexObjectList); - bool result = u_arraylist_add(caglobals.tcp.svrlist, svritem); - if (!result) - { - OIC_LOG(ERROR, TAG, "u_arraylist_add failed."); - OC_CLOSE_SOCKET(sockfd); - OICFree(svritem); - oc_mutex_unlock(g_mutexObjectList); - return; - } + LL_APPEND(g_sessionList, svritem); oc_mutex_unlock(g_mutexObjectList); CHECKFD(sockfd); @@ -735,8 +728,7 @@ static void CAReceiveMessage(CASocketFd_t fd) CAResult_t res = CA_STATUS_OK; //get remote device information from file descriptor. - size_t index = 0; - CATCPSessionInfo_t *svritem = CAGetSessionInfoFromFD(fd, &index); + CATCPSessionInfo_t *svritem = CAGetSessionInfoFromFD(fd); if (!svritem) { OIC_LOG(ERROR, TAG, "there is no connection information in list"); @@ -873,47 +865,6 @@ static void CAWakeUpForReadFdsUpdate() } #endif -static CAResult_t CATCPConvertNameToAddr(int family, const char *host, uint16_t port, - struct sockaddr_storage *sockaddr) -{ - struct addrinfo *addrs = NULL; - struct addrinfo hints = { .ai_family = family, - .ai_protocol = IPPROTO_TCP, - .ai_socktype = SOCK_STREAM, - .ai_flags = AI_NUMERICHOST }; - - int r = getaddrinfo(host, NULL, &hints, &addrs); - if (r) - { -#ifdef EAI_SYSTEM - if (EAI_SYSTEM == r) - { - OIC_LOG_V(ERROR, TAG, "getaddrinfo failed: errno %s", strerror(errno)); - } - else -#endif - { - OIC_LOG_V(ERROR, TAG, "getaddrinfo failed: %s", gai_strerror(r)); - } - freeaddrinfo(addrs); - return CA_STATUS_FAILED; - } - // assumption: in this case, getaddrinfo will only return one addrinfo - // or first is the one we want. - if (addrs[0].ai_family == AF_INET6) - { - memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6)); - ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port); - } - else - { - memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in)); - ((struct sockaddr_in *)sockaddr)->sin_port = htons(port); - } - freeaddrinfo(addrs); - return CA_STATUS_OK; -} - static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem) { VERIFY_NON_NULL(svritem, TAG, "svritem is NULL"); @@ -1125,13 +1076,6 @@ CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool) return res; } - oc_mutex_lock(g_mutexObjectList); - if (!caglobals.tcp.svrlist) - { - caglobals.tcp.svrlist = u_arraylist_create(); - } - oc_mutex_unlock(g_mutexObjectList); - if (caglobals.server) { NEWSOCKET(AF_INET, ipv4); @@ -1430,18 +1374,7 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint) // #2. add TCP connection info to list oc_mutex_lock(g_mutexObjectList); - if (caglobals.tcp.svrlist) - { - bool res = u_arraylist_add(caglobals.tcp.svrlist, svritem); - if (!res) - { - OIC_LOG(ERROR, TAG, "u_arraylist_add failed."); - OC_CLOSE_SOCKET(svritem->fd); - OICFree(svritem); - oc_mutex_unlock(g_mutexObjectList); - return OC_INVALID_SOCKET; - } - } + LL_APPEND(g_sessionList, svritem); oc_mutex_unlock(g_mutexObjectList); // #3. create the socket and connect to TCP server @@ -1460,16 +1393,11 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint) return svritem->fd; } -CAResult_t CADisconnectTCPSession(size_t index) +CAResult_t CADisconnectTCPSession(CATCPSessionInfo_t *removedData) { OIC_LOG_V(DEBUG, TAG, "%s", __func__); - CATCPSessionInfo_t *removedData = u_arraylist_remove(caglobals.tcp.svrlist, index); - if (!removedData) - { - OIC_LOG(DEBUG, TAG, "there is no data to be removed"); - return CA_STATUS_OK; - } + VERIFY_NON_NULL(removedData, TAG, "removedData is NULL"); // close the socket and remove session info in list. if (removedData->fd != OC_INVALID_SOCKET) @@ -1500,17 +1428,19 @@ CAResult_t CADisconnectTCPSession(size_t index) void CATCPDisconnectAll() { oc_mutex_lock(g_mutexObjectList); - - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (ssize_t index = length; index > 0; index--) + CATCPSessionInfo_t *session = NULL; + CATCPSessionInfo_t *tmp = NULL; + LL_FOREACH_SAFE(g_sessionList, session, tmp); { - // disconnect session from remote device. - CADisconnectTCPSession(index - 1); + if (session) + { + LL_DELETE(g_sessionList, session); + // disconnect session from remote device. + CADisconnectTCPSession(session); + } } - u_arraylist_destroy(caglobals.tcp.svrlist); - caglobals.tcp.svrlist = NULL; - + g_sessionList = NULL; oc_mutex_unlock(g_mutexObjectList); #ifdef __WITH_TLS__ @@ -1519,35 +1449,29 @@ void CATCPDisconnectAll() } -CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint, size_t *index) +CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint) { VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint is NULL", NULL); - VERIFY_NON_NULL_RET(index, TAG, "index is NULL", NULL); OIC_LOG_V(DEBUG, TAG, "Looking for [%s:%d]", endpoint->addr, endpoint->port); // get connection info from list - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; i < length; i++) + oc_mutex_lock(g_mutexObjectList); + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session) { - CATCPSessionInfo_t *svritem = (CATCPSessionInfo_t *) u_arraylist_get( - caglobals.tcp.svrlist, i); - if (!svritem) - { - continue; - } - - if (!strncmp(svritem->sep.endpoint.addr, endpoint->addr, - sizeof(svritem->sep.endpoint.addr)) - && (svritem->sep.endpoint.port == endpoint->port) - && (svritem->sep.endpoint.flags & endpoint->flags)) + if (!strncmp(session->sep.endpoint.addr, endpoint->addr, + sizeof(session->sep.endpoint.addr)) + && (session->sep.endpoint.port == endpoint->port) + && (session->sep.endpoint.flags & endpoint->flags)) { + oc_mutex_unlock(g_mutexObjectList); OIC_LOG(DEBUG, TAG, "Found in session list"); - *index = i; - return svritem; + return session; } } + oc_mutex_unlock(g_mutexObjectList); OIC_LOG(DEBUG, TAG, "Session not found"); return NULL; } @@ -1560,24 +1484,17 @@ CASocketFd_t CAGetSocketFDFromEndpoint(const CAEndpoint_t *endpoint) // get connection info from list. oc_mutex_lock(g_mutexObjectList); - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; i < length; i++) + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session) { - CATCPSessionInfo_t *svritem = (CATCPSessionInfo_t *) u_arraylist_get( - caglobals.tcp.svrlist, i); - if (!svritem) - { - continue; - } - - if (!strncmp(svritem->sep.endpoint.addr, endpoint->addr, - sizeof(svritem->sep.endpoint.addr)) - && (svritem->sep.endpoint.port == endpoint->port) - && (svritem->sep.endpoint.flags & endpoint->flags)) + if (!strncmp(session->sep.endpoint.addr, endpoint->addr, + sizeof(session->sep.endpoint.addr)) + && (session->sep.endpoint.port == endpoint->port) + && (session->sep.endpoint.flags & endpoint->flags)) { oc_mutex_unlock(g_mutexObjectList); OIC_LOG(DEBUG, TAG, "Found in session list"); - return svritem->fd; + return session->fd; } } @@ -1586,48 +1503,53 @@ CASocketFd_t CAGetSocketFDFromEndpoint(const CAEndpoint_t *endpoint) return OC_INVALID_SOCKET; } -CATCPSessionInfo_t *CAGetSessionInfoFromFD(CASocketFd_t fd, size_t *index) +CATCPSessionInfo_t *CAGetSessionInfoFromFD(CASocketFd_t fd) { oc_mutex_lock(g_mutexObjectList); - // check from the last item. - CATCPSessionInfo_t *svritem = NULL; - uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); - for (size_t i = 0; i < length; i++) + CATCPSessionInfo_t *session = NULL; + LL_FOREACH(g_sessionList, session) { - svritem = (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i); - - if (svritem && svritem->fd == fd) + if (session && session->fd == fd) { - *index = i; oc_mutex_unlock(g_mutexObjectList); - return svritem; + return session; } } oc_mutex_unlock(g_mutexObjectList); - return NULL; } CAResult_t CASearchAndDeleteTCPSession(const CAEndpoint_t *endpoint) { - oc_mutex_lock(g_mutexObjectList); + VERIFY_NON_NULL(endpoint, TAG, "endpoint is NULL"); - CAResult_t result = CA_STATUS_OK; - size_t index = 0; - CATCPSessionInfo_t *svritem = CAGetTCPSessionInfoFromEndpoint(endpoint, &index); - if (svritem) + OIC_LOG_V(DEBUG, TAG, "Looking for [%s:%d]", endpoint->addr, endpoint->port); + + // get connection info from list + CATCPSessionInfo_t *session = NULL; + CATCPSessionInfo_t *tmp = NULL; + + oc_mutex_lock(g_mutexObjectList); + LL_FOREACH_SAFE(g_sessionList, session, tmp) { - result = CADisconnectTCPSession(index); - if (CA_STATUS_OK != result) + if (!strncmp(session->sep.endpoint.addr, endpoint->addr, + sizeof(session->sep.endpoint.addr)) + && (session->sep.endpoint.port == endpoint->port) + && (session->sep.endpoint.flags & endpoint->flags)) { - OIC_LOG_V(ERROR, TAG, "CADisconnectTCPSession failed, result[%d]", result); + OIC_LOG(DEBUG, TAG, "Found in session list"); + LL_DELETE(g_sessionList, session); + CADisconnectTCPSession(session); + oc_mutex_unlock(g_mutexObjectList); + return CA_STATUS_OK; } } - oc_mutex_unlock(g_mutexObjectList); - return result; + + OIC_LOG(DEBUG, TAG, "Session not found"); + return CA_STATUS_OK; } size_t CAGetTotalLengthFromHeader(const unsigned char *recvBuffer)