Fix the SMF crash [#437]

This commit is contained in:
Sukchan Lee 2020-05-14 13:38:26 -04:00
parent 4e01d270eb
commit 46f20cc979
8 changed files with 117 additions and 58 deletions

View File

@ -32,6 +32,9 @@
#include "ogs-app.h"
#include "ipfw/ogs-ipfw.h"
#include "timer.h"
#include "smf-sm.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -19,12 +19,38 @@
#include "context.h"
#include "event.h"
#include "smf-sm.h"
#include "pfcp-path.h"
#include "n4-build.h"
static void pfcp_node_fsm_init(ogs_pfcp_node_t *node, bool try_to_assoicate)
{
smf_event_t e;
ogs_assert(node);
e.pfcp_node = node;
if (try_to_assoicate == true) {
node->t_association = ogs_timer_add(smf_self()->timer_mgr,
smf_timer_association, node);
ogs_assert(node->t_association);
}
ogs_fsm_create(&node->sm, smf_pfcp_state_initial, smf_pfcp_state_final);
ogs_fsm_init(&node->sm, &e);
}
static void pfcp_node_fsm_fini(ogs_pfcp_node_t *node)
{
smf_event_t e;
e.pfcp_node = node;
ogs_fsm_fini(&node->sm, &e);
ogs_fsm_delete(&node->sm);
if (node->t_association)
ogs_timer_delete(node->t_association);
}
static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
{
int rv;
@ -69,13 +95,16 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
}
e = smf_event_new(SMF_EVT_N4_MESSAGE);
ogs_assert(e);
node = ogs_pfcp_node_find(&ogs_pfcp_self()->n4_list, &from);
if (!node) {
node = ogs_pfcp_node_add(&ogs_pfcp_self()->n4_list, &from);
ogs_assert(node);
node->sock = data;
pfcp_node_fsm_init(node, false);
}
ogs_assert(e);
e->pfcp_node = node;
e->pkbuf = pkbuf;
@ -91,6 +120,7 @@ int smf_pfcp_open(void)
{
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
ogs_pfcp_node_t *pfcp_node = NULL;
/* PFCP Server */
ogs_list_for_each(&ogs_pfcp_self()->pfcp_list, node) {
@ -120,11 +150,19 @@ int smf_pfcp_open(void)
ogs_assert(ogs_pfcp_self()->pfcp_addr || ogs_pfcp_self()->pfcp_addr6);
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node)
pfcp_node_fsm_init(pfcp_node, true);
return OGS_OK;
}
void smf_pfcp_close(void)
{
ogs_pfcp_node_t *pfcp_node = NULL;
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

View File

@ -42,9 +42,6 @@ void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e)
ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
ogs_assert(rv == OGS_OK);
node->t_association = ogs_timer_add(smf_self()->timer_mgr,
smf_timer_association, node);
ogs_assert(node->t_association);
node->t_heartbeat = ogs_timer_add(smf_self()->timer_mgr,
smf_timer_heartbeat, node);
ogs_assert(node->t_heartbeat);
@ -63,7 +60,6 @@ void smf_pfcp_state_final(ogs_fsm_t *s, smf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
ogs_timer_delete(node->t_association);
ogs_timer_delete(node->t_heartbeat);
}
@ -89,14 +85,20 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
ogs_timer_start(node->t_association,
smf_timer_cfg(SMF_TIMER_ASSOCIATION)->duration);
if (node->t_association) {
ogs_timer_start(node->t_association,
smf_timer_cfg(SMF_TIMER_ASSOCIATION)->duration);
smf_pfcp_send_association_setup_request(node);
smf_pfcp_send_association_setup_request(node);
}
break;
case OGS_FSM_EXIT_SIG:
ogs_timer_stop(node->t_association);
if (node->t_association) {
ogs_timer_stop(node->t_association);
}
break;
case SMF_EVT_N4_TIMER:
switch(e->timer_id) {
case SMF_TIMER_ASSOCIATION:
@ -106,6 +108,7 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
ogs_warn("Retry to association with peer [%s]:%d failed",
OGS_ADDR(addr, buf), OGS_PORT(addr));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
smf_timer_cfg(SMF_TIMER_ASSOCIATION)->duration);

View File

@ -73,28 +73,13 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
if (rv != OGS_OK) {
ogs_fatal("Can't establish N4-PFCP path");
}
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node) {
smf_event_t e;
e.pfcp_node = pfcp_node;
ogs_fsm_create(&pfcp_node->sm,
smf_pfcp_state_initial, smf_pfcp_state_final);
ogs_fsm_init(&pfcp_node->sm, &e);
}
break;
case OGS_FSM_EXIT_SIG:
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node) {
smf_event_t e;
e.pfcp_node = pfcp_node;
ogs_fsm_fini(&pfcp_node->sm, &e);
ogs_fsm_delete(&pfcp_node->sm);
}
smf_gtp_close();
smf_pfcp_close();
break;
case SMF_EVT_S5C_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
@ -217,6 +202,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(recvbuf);
pfcp_node = e->pfcp_node;
ogs_assert(pfcp_node);
ogs_assert(OGS_FSM_STATE(&pfcp_node->sm));
if (ogs_pfcp_parse_msg(&pfcp_message, recvbuf) != OGS_OK) {
ogs_error("ogs_pfcp_parse_msg() failed");

View File

@ -33,6 +33,9 @@
#include "ipfw/ogs-ipfw.h"
#include "timer.h"
#include "upf-sm.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -19,12 +19,38 @@
#include "context.h"
#include "event.h"
#include "upf-sm.h"
#include "pfcp-path.h"
#include "n4-build.h"
static void pfcp_node_fsm_init(ogs_pfcp_node_t *node, bool try_to_assoicate)
{
upf_event_t e;
ogs_assert(node);
e.pfcp_node = node;
if (try_to_assoicate == true) {
node->t_association = ogs_timer_add(upf_self()->timer_mgr,
upf_timer_association, node);
ogs_assert(node->t_association);
}
ogs_fsm_create(&node->sm, upf_pfcp_state_initial, upf_pfcp_state_final);
ogs_fsm_init(&node->sm, &e);
}
static void pfcp_node_fsm_fini(ogs_pfcp_node_t *node)
{
upf_event_t e;
e.pfcp_node = node;
ogs_fsm_fini(&node->sm, &e);
ogs_fsm_delete(&node->sm);
if (node->t_association)
ogs_timer_delete(node->t_association);
}
static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
{
int rv;
@ -69,13 +95,16 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
}
e = upf_event_new(UPF_EVT_N4_MESSAGE);
ogs_assert(e);
node = ogs_pfcp_node_find(&ogs_pfcp_self()->n4_list, &from);
if (!node) {
node = ogs_pfcp_node_add(&ogs_pfcp_self()->n4_list, &from);
ogs_assert(node);
node->sock = data;
pfcp_node_fsm_init(node, false);
}
ogs_assert(e);
e->pfcp_node = node;
e->pkbuf = pkbuf;
@ -91,6 +120,7 @@ int upf_pfcp_open(void)
{
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
ogs_pfcp_node_t *pfcp_node = NULL;
/* PFCP Server */
ogs_list_for_each(&ogs_pfcp_self()->pfcp_list, node) {
@ -120,11 +150,19 @@ int upf_pfcp_open(void)
ogs_assert(ogs_pfcp_self()->pfcp_addr || ogs_pfcp_self()->pfcp_addr6);
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node)
pfcp_node_fsm_init(pfcp_node, true);
return OGS_OK;
}
void upf_pfcp_close(void)
{
ogs_pfcp_node_t *pfcp_node = NULL;
ogs_list_for_each(&ogs_pfcp_self()->n4_list, pfcp_node)
pfcp_node_fsm_fini(pfcp_node);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list);
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

View File

@ -42,9 +42,6 @@ void upf_pfcp_state_initial(ogs_fsm_t *s, upf_event_t *e)
ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
ogs_assert(rv == OGS_OK);
node->t_association = ogs_timer_add(upf_self()->timer_mgr,
upf_timer_association, node);
ogs_assert(node->t_association);
node->t_heartbeat = ogs_timer_add(upf_self()->timer_mgr,
upf_timer_heartbeat, node);
ogs_assert(node->t_heartbeat);
@ -63,7 +60,6 @@ void upf_pfcp_state_final(ogs_fsm_t *s, upf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
ogs_timer_delete(node->t_association);
ogs_timer_delete(node->t_heartbeat);
}
@ -85,14 +81,20 @@ void upf_pfcp_state_will_associate(ogs_fsm_t *s, upf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
ogs_timer_start(node->t_association,
upf_timer_cfg(UPF_TIMER_ASSOCIATION)->duration);
if (node->t_association) {
ogs_timer_start(node->t_association,
upf_timer_cfg(UPF_TIMER_ASSOCIATION)->duration);
upf_pfcp_send_association_setup_request(node);
upf_pfcp_send_association_setup_request(node);
}
break;
case OGS_FSM_EXIT_SIG:
ogs_timer_stop(node->t_association);
if (node->t_association) {
ogs_timer_stop(node->t_association);
}
break;
case UPF_EVT_N4_TIMER:
switch(e->timer_id) {
case UPF_TIMER_ASSOCIATION:
@ -102,6 +104,7 @@ void upf_pfcp_state_will_associate(ogs_fsm_t *s, upf_event_t *e)
ogs_warn("Retry to association with peer [%s]:%d failed",
OGS_ADDR(addr, buf), OGS_PORT(addr));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
upf_timer_cfg(UPF_TIMER_ASSOCIATION)->duration);

View File

@ -62,28 +62,13 @@ void upf_state_operational(ogs_fsm_t *s, upf_event_t *e)
if (rv != OGS_OK) {
ogs_fatal("Can't establish GTP-U path");
}
ogs_list_for_each(&ogs_pfcp_self()->n4_list, node) {
upf_event_t e;
e.pfcp_node = node;
ogs_fsm_create(&node->sm,
upf_pfcp_state_initial, upf_pfcp_state_final);
ogs_fsm_init(&node->sm, &e);
}
break;
case OGS_FSM_EXIT_SIG:
ogs_list_for_each(&ogs_pfcp_self()->n4_list, node) {
upf_event_t e;
e.pfcp_node = node;
ogs_fsm_fini(&node->sm, &e);
ogs_fsm_delete(&node->sm);
}
upf_pfcp_close();
upf_gtp_close();
break;
case UPF_EVT_N4_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;