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 d47d5ab
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 14 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
81 changes: 70 additions & 11 deletions lib/app/ogs-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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,
Expand Down Expand Up @@ -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)
*
Expand All @@ -423,7 +435,15 @@ static int local_conf_prepare(void)
* the paging failure result to GTPv2-C or HTTP2(SBI).
*/
local_conf.time.message.duration = ogs_time_from_sec(10);
local_conf.time.message.sbi_set = false;
local_conf.time.message.gtp_set = false;
local_conf.time.message.pfcp_set = false;


#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)
*
Expand Down Expand Up @@ -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);
}
Expand Down
7 changes: 7 additions & 0 deletions lib/app/ogs-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
bool gtp_set;
bool pfcp_set;

struct {
ogs_time_t client_wait_duration;
ogs_time_t connection_deadline;
Expand Down
4 changes: 2 additions & 2 deletions lib/sbi/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit d47d5ab

Please sign in to comment.