index_pool is introduced to access context memory safely

This commit is contained in:
Sukchan Lee 2017-04-10 22:48:07 +09:00
parent aab0732178
commit e4c6c8cf56
6 changed files with 53 additions and 30 deletions

View File

@ -4,13 +4,17 @@
#include "core.h"
#include "core_mutex.h"
typedef c_uint32_t index_t;
#define INVALID_INDEX 0
#define index_declare(__name, __size) \
#define index_declare(__name, __type, __size) \
typedef struct { \
int head, tail; \
int size, avail; \
c_uint32_t free_index[__size]; \
index_t free_index[__size]; \
__type *index_pool[__size + 1]; \
__type *free_pool[__size], node_pool[__size]; \
mutex_id mut; \
} index_##__name##_t; \
index_##__name##_t __name
@ -21,7 +25,11 @@
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
{ \
(__pname)->free_index[__i] = (__i + 1); \
(__pname)->index_pool[__i + 1] = NULL; \
(__pname)->free_pool[__i] = &((__pname)->node_pool[__i]); \
} \
} while (0)
#define index_final(__pname) \
@ -33,31 +41,42 @@
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
{ \
(__pname)->free_index[__i] = (__i + 1); \
(__pname)->index_pool[__i + 1] = NULL; \
(__pname)->free_pool[__i] = &((__pname)->node_pool[__i]); \
} \
} while (0)
#define index_alloc(__pname, __index) do { \
(__index) = INVALID_INDEX; \
#define index_alloc(__pname, __pptr_node) do { \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail > 0) { \
(__pname)->avail--; \
(__index) = (__pname)->free_index[(__pname)->head]; \
(__pname)->free_index[(__pname)->head] = INVALID_INDEX; \
(__pname)->head = ((__pname)->head + 1) % ((__pname)->size); \
(__pname)->avail--; \
*(__pptr_node) = (void*)(__pname)->free_pool[(__pname)->head]; \
memset(*(__pptr_node), 0, sizeof(gtp_xact_t)); \
(__pname)->free_pool[(__pname)->head] = NULL; \
((*(__pptr_node))->index) = (__pname)->free_index[(__pname)->head]; \
(__pname)->index_pool[((*(__pptr_node))->index)] = *(__pptr_node); \
(__pname)->free_index[(__pname)->head] = INVALID_INDEX; \
(__pname)->head = ((__pname)->head + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define index_free(__pname, __index) do { \
#define index_free(__pname, __ptr_node) do { \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail < (__pname)->size) { \
(__pname)->avail++; \
(__pname)->free_index[(__pname)->tail] = (__index); \
(__pname)->index_pool[((__ptr_node)->index)] = NULL; \
(__pname)->free_index[(__pname)->tail] = ((__ptr_node)->index); \
(__pname)->free_pool[(__pname)->tail] = (void*)(__ptr_node); \
(__pname)->tail = ((__pname)->tail + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define index_find(__pname, __index) (void*)(__pname)->index_pool[(__index)];
#define index_size(__pname) ((__pname)->size)
#define index_avail(__pname) ((__pname)->avail)

View File

@ -40,14 +40,14 @@ ED4(c_uint8_t version:3;,
} __attribute__ ((packed)) gtpv2c_header_t;
static int gtp_xact_pool_initialized = 0;
pool_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL);
index_declare(gtp_xact_pool, gtp_xact_t, SIZE_OF_GTP_XACT_POOL);
status_t gtp_xact_init(gtp_xact_ctx_t *context,
tm_service_t *tm_service, c_uintptr_t event)
{
if (gtp_xact_pool_initialized == 0)
{
pool_init(&gtp_xact_pool, SIZE_OF_GTP_XACT_POOL);
index_init(&gtp_xact_pool, SIZE_OF_GTP_XACT_POOL);
}
gtp_xact_pool_initialized = 1;
@ -68,7 +68,7 @@ status_t gtp_xact_final(void)
d_print("%d not freed in gtp_xact_pool[%d] of S11/S5-SM\n",
pool_size(&gtp_xact_pool) - pool_avail(&gtp_xact_pool),
pool_size(&gtp_xact_pool));
pool_final(&gtp_xact_pool);
index_final(&gtp_xact_pool);
}
gtp_xact_pool_initialized = 0;
@ -85,20 +85,18 @@ static gtp_xact_t *gtp_xact_create(gtp_xact_ctx_t *context,
d_assert(sock, return NULL, "Null param");
d_assert(gnode, return NULL, "Null param");
pool_alloc_node(&gtp_xact_pool, &xact);
index_alloc(&gtp_xact_pool, &xact);
d_assert(xact, return NULL, "Transaction allocation failed");
memset(xact, 0, sizeof(gtp_xact_t));
xact->org = org;
xact->xid = xid;
xact->sock = sock;
xact->gnode = gnode;
xact->tm_wait = event_timer(context->tm_service, context->event,
duration, (c_uintptr_t)xact);
duration, xact->index);
d_assert(xact->tm_wait,
pool_free_node(&gtp_xact_pool, xact); return NULL,
index_free(&gtp_xact_pool, xact); return NULL,
"Timer allocation failed");
xact->retry_count = retry_count;
tm_start(xact->tm_wait);
@ -132,7 +130,7 @@ static status_t gtp_xact_delete(gtp_xact_t *xact)
list_remove(xact->org == GTP_LOCAL_ORIGINATOR ? &xact->gnode->local_list :
&xact->gnode->remote_list, xact);
pool_free_node(&gtp_xact_pool, xact);
index_free(&gtp_xact_pool, xact);
return CORE_OK;
}
@ -224,8 +222,10 @@ out:
return CORE_ERROR;
}
status_t gtp_xact_timeout(gtp_xact_t *xact)
status_t gtp_xact_timeout(index_t index)
{
gtp_xact_t *xact = index_find(&gtp_xact_pool, index);
d_assert(xact, goto out, "Null param");
d_assert(xact->sock, goto out, "Null param");
d_assert(xact->gnode, goto out, "Null param");

View File

@ -3,6 +3,7 @@
#include "core_pkbuf.h"
#include "core_list.h"
#include "core_index.h"
#include "core_net.h"
#include "core_timer.h"
@ -28,6 +29,8 @@ typedef struct _gtp_xact_ctx_t {
*/
typedef struct _gtp_xact_t {
lnode_t node; /**< A node of list */
index_t index;
#define GTP_LOCAL_ORIGINATOR 0
#define GTP_REMOTE_ORIGINATOR 1
c_uint8_t org; /**< Transaction' originator.
@ -59,7 +62,7 @@ CORE_DECLARE(status_t) gtp_xact_commit(
gtp_xact_t *xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) gtp_xact_associated_commit(gtp_xact_t *xact,
gtp_xact_t *assoc_xact, c_uint8_t type, c_uint32_t teid, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) gtp_xact_timeout(gtp_xact_t *xact);
CORE_DECLARE(status_t) gtp_xact_timeout(index_t index);
CORE_DECLARE(status_t) gtp_xact_receive(
gtp_xact_ctx_t *context, net_sock_t *sock, gtp_node_t *gnode,

View File

@ -224,10 +224,10 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
}
case EVT_TM_MME_S11_T3:
{
gtp_xact_t *xact = (gtp_xact_t *)event_get_param1(e);
d_assert(xact, break, "Null param");
index_t index = (index_t)event_get_param1(e);
d_assert(index, break, "Null param");
gtp_xact_timeout(xact);
gtp_xact_timeout(index);
break;
}
default:

View File

@ -89,10 +89,10 @@ void pgw_state_operational(pgw_sm_t *s, event_t *e)
}
case EVT_TM_PGW_T3:
{
gtp_xact_t *xact = (gtp_xact_t *)event_get_param1(e);
d_assert(xact, break, "Null param");
index_t index = (index_t)event_get_param1(e);
d_assert(index, break, "Null param");
gtp_xact_timeout(xact);
gtp_xact_timeout(index);
break;
}
default:

View File

@ -95,10 +95,11 @@ void sgw_state_operational(sgw_sm_t *s, event_t *e)
}
case EVT_TM_SGW_T3:
{
gtp_xact_t *xact = (gtp_xact_t *)event_get_param1(e);
d_assert(xact, break, "Null param");
index_t index = (index_t)event_get_param1(e);
printf("index = %d\n", index);
d_assert(index, break, "Null param");
gtp_xact_timeout(xact);
gtp_xact_timeout(index);
break;
}
default: