Skip to content

Commit

Permalink
[core] allow fine-grained setting of message timers (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
spencersevilla committed Jan 19, 2024
1 parent 3bbc32d commit 7411811
Showing 4 changed files with 84 additions and 15 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -31,4 +31,7 @@ In our specific deployment context, we lean heavily on the CUPS split and locate
Wherever possible, we have changed PFCP messages/operations from an action-based model to a state-based one, with the understanding/assumption that the CPS is always authoritative/correct over the UPS. In this design, the UPS should use messages to infer the state that the CPS wants, and silently recover into this state if able. For Session Establishment messages, this means that if the UPS already has an existing session for the given SEID, it should simply wipe out the preexisting session, create a new one according to the CPS details, and return OGS_PFCP_CAUSE_REQUEST_ACCEPTED. Similarly, for Session Delete messages where the SEID does not exist, the UPS can return OGS_PFCP_CAUSE_REQUEST_ACCEPTED without doing anything.

##### PFCP Session Re-Establishment:
When a UPS re-associates itself with the CPS after a period of disconnectivity, their respective states may have diverged substantially. We handle this using a reassociation process wherein (1) the CPS sends a Session-Set-Delete message, effectively instructing the UPS to delete any/all current sessions, and then (2) the CPS re-sends a Session Establishment message for each active session. This creates a bit more chatter over the wire than you might expect, but works incredibly well in our context.
When a UPS re-associates itself with the CPS after a period of disconnectivity, their respective states may have diverged substantially. We handle this using a reassociation process wherein (1) the CPS sends a Session-Set-Delete message, effectively instructing the UPS to delete any/all current sessions, and then (2) the CPS re-sends a Session Establishment message for each active session. This creates a bit more chatter over the wire than you might expect, but works incredibly well in our context.

## Fine-Grained Timers
Stock open5gs has one configurable parameter (`message.duration`) which sets the timeout value for *all* messages sent or received by the program in question. We keep this parameter as the default, but have also added several different ones pertaining to each message protocol to allow us to have finer-grained control over these timers, which is highly recommended by the 3GPP. Specifically, `message.duration` has been supplemented by `message.sbi_duration`, `message.gtp_duration`, `message.pfcp_duration` and `message.diameter_timeout`.
83 changes: 71 additions & 12 deletions lib/app/ogs-config.c
Original file line number Diff line number Diff line change
@@ -329,9 +329,25 @@ int ogs_app_parse_global_conf(ogs_yaml_iter_t *parent)
static void regenerate_all_timer_duration(void)
{
ogs_assert(local_conf.time.message.duration);
ogs_assert(local_conf.time.message.sbi_duration);
ogs_assert(local_conf.time.message.gtp_duration);
ogs_assert(local_conf.time.message.pfcp_duration);

// if message.duration is set, it overrides the default for all
// durations *except* any that were individually set
if (!local_conf.time.message.sbi_set) {
local_conf.time.message.sbi_duration = local_conf.time.message.duration;
}
if (!local_conf.time.message.gtp_set) {
local_conf.time.message.gtp_duration = local_conf.time.message.duration;
}
if (!local_conf.time.message.pfcp_set) {
local_conf.time.message.pfcp_duration = local_conf.time.message.duration;
}


local_conf.time.message.sbi.client_wait_duration =
local_conf.time.message.duration;
local_conf.time.message.sbi_duration;
local_conf.time.message.sbi.connection_deadline =
local_conf.time.message.sbi.client_wait_duration + ogs_time_from_sec(1);
local_conf.time.message.sbi.reconnect_interval =
@@ -341,11 +357,8 @@ static void regenerate_all_timer_duration(void)
local_conf.time.message.sbi.reconnect_interval_in_exception =
ogs_time_from_sec(2);

#define PFCP_N1_RESPONSE_RETRY_COUNT 3
local_conf.time.message.pfcp.n1_response_rcount =
PFCP_N1_RESPONSE_RETRY_COUNT;
local_conf.time.message.pfcp.t1_response_duration =
(local_conf.time.message.duration /
(local_conf.time.message.pfcp_duration /
(local_conf.time.message.pfcp.n1_response_rcount + 1));
ogs_assert(local_conf.time.message.pfcp.t1_response_duration);

@@ -367,11 +380,8 @@ static void regenerate_all_timer_duration(void)
local_conf.time.message.sbi.client_wait_duration +
ogs_time_from_sec(1));

#define GTP_N3_RESPONSE_RETRY_COUNT 3
local_conf.time.message.gtp.n3_response_rcount =
GTP_N3_RESPONSE_RETRY_COUNT;
local_conf.time.message.gtp.t3_response_duration =
(local_conf.time.message.duration /
(local_conf.time.message.gtp_duration /
(local_conf.time.message.gtp.n3_response_rcount + 1));
ogs_assert(local_conf.time.message.gtp.t3_response_duration);

@@ -383,8 +393,11 @@ static void regenerate_all_timer_duration(void)
ogs_assert(local_conf.time.message.gtp.t3_holding_duration);

#if 0
ogs_trace("%lld, %lld, %lld, %d, %lld, %d %lld, %d, %lld, %d, %lld",
ogs_trace("%lld, %lld, %lld, %lld, %lld, %lld, %d, %lld, %d %lld, %d, %lld, %d, %lld",
(long long)local_conf.time.message.duration,
(long long)local_conf.time.message.sbi_duration,
(long long)local_conf.time.message.gtp_duration,
(long long)local_conf.time.message.pfcp_duration,
(long long)local_conf.time.message.sbi.client_wait_duration,
(long long)local_conf.time.message.sbi.connection_deadline,
local_conf.time.message.pfcp.n1_response_rcount,
@@ -413,7 +426,6 @@ static int local_conf_prepare(void)

/* 86400 seconds = 1 day */
local_conf.time.subscription.validity_duration = 86400;

/*
* Message Wait Duration : 10 seconds (Default)
*
@@ -422,8 +434,16 @@ static int local_conf_prepare(void)
* It is recomended to set at least 9 seconds to reflect
* the paging failure result to GTPv2-C or HTTP2(SBI).
*/
local_conf.time.message.duration = ogs_time_from_sec(10);
#define DEFAULT_MSG_DURATION ogs_time_from_sec(10);
local_conf.time.message.duration = DEFAULT_MSG_DURATION;
local_conf.time.message.sbi_duration = DEFAULT_MSG_DURATION;
local_conf.time.message.gtp_duration = DEFAULT_MSG_DURATION;
local_conf.time.message.pfcp_duration = DEFAULT_MSG_DURATION;

#define PFCP_N1_RESPONSE_RETRY_COUNT 3
#define GTP_N3_RESPONSE_RETRY_COUNT 3
local_conf.time.message.pfcp.n1_response_rcount = PFCP_N1_RESPONSE_RETRY_COUNT;
local_conf.time.message.gtp.n3_response_rcount = GTP_N3_RESPONSE_RETRY_COUNT;
/*
* Handover Wait Duration : 300 ms (Default)
*
@@ -588,6 +608,45 @@ int ogs_app_parse_local_conf(const char *local)
ogs_time_from_msec(atoll(v));
regenerate_all_timer_duration();
}
} else if (!strcmp(msg_key, "sbi_duration")) {
const char *v =
ogs_yaml_iter_value(&msg_iter);
if (v) {
local_conf.time.message.sbi_set = true;
local_conf.time.message.sbi_duration =
ogs_time_from_msec(atoll(v));
regenerate_all_timer_duration();
}
} else if (!strcmp(msg_key, "gtp_duration")) {
const char *v =
ogs_yaml_iter_value(&msg_iter);
if (v) {
local_conf.time.message.gtp_set = true;
local_conf.time.message.gtp_duration =
ogs_time_from_msec(atoll(v));
regenerate_all_timer_duration();
}
} else if (!strcmp(msg_key, "pfcp_duration")) {
const char *v =
ogs_yaml_iter_value(&msg_iter);
if (v) {
local_conf.time.message.pfcp_set = true;
local_conf.time.message.pfcp_duration =
ogs_time_from_msec(atoll(v));
regenerate_all_timer_duration();
}
} else if (!strcmp(msg_key, "pfcp_n1")) {
const char *v = ogs_yaml_iter_value(&msg_iter);
if (v) {
local_conf.time.message.pfcp.n1_response_rcount = atoi(v);
regenerate_all_timer_duration();
}
} else if (!strcmp(msg_key, "gtp_n3")) {
const char *v = ogs_yaml_iter_value(&msg_iter);
if (v) {
local_conf.time.message.gtp.n3_response_rcount = atoi(v);
regenerate_all_timer_duration();
}
} else
ogs_warn("unknown key `%s`", msg_key);
}
7 changes: 7 additions & 0 deletions lib/app/ogs-config.h
Original file line number Diff line number Diff line change
@@ -94,6 +94,13 @@ typedef struct ogs_local_conf_s {

struct {
ogs_time_t duration;
ogs_time_t sbi_duration;
ogs_time_t gtp_duration;
ogs_time_t pfcp_duration;
bool sbi_set = false;
bool gtp_set = false;
bool pfcp_set = false;

struct {
ogs_time_t client_wait_duration;
ogs_time_t connection_deadline;
4 changes: 2 additions & 2 deletions lib/sbi/message.c
Original file line number Diff line number Diff line change
@@ -679,9 +679,9 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
ogs_sbi_header_set(request->http.headers,
OGS_SBI_OPTIONAL_CUSTOM_SENDER_TIMESTAMP, sender_timestamp);

ogs_assert(ogs_time_to_msec(ogs_local_conf()->time.message.duration));
ogs_assert(ogs_time_to_msec(ogs_local_conf()->time.message.sbi_duration));
max_rsp_time = ogs_msprintf("%d",
(int)ogs_time_to_msec(ogs_local_conf()->time.message.duration));
(int)ogs_time_to_msec(ogs_local_conf()->time.message.sbi_duration));
ogs_sbi_header_set(request->http.headers,
OGS_SBI_OPTIONAL_CUSTOM_MAX_RSP_TIME, max_rsp_time);
ogs_free(max_rsp_time);

0 comments on commit 7411811

Please sign in to comment.