gtp: Introduce VTY configurable GTP timer X3

This timer controls the amount of time a resp message transmitted by the
local gsn is to be stored in the resp queue. This is used in order to
detect duplicate requests received, since GTP states the exact same
response should be answered if a duplicate request is received.

Prior to this patch, this timer was hardcoded to 60 seconds.
This patch actually should be set, in general, to a value
equal than (T3-RESPONSE * N3-REQUESTS) values configured at
the peer, since that is the maximum period during which the local gsn
expects to receive req retransmissions from the peer.
Hence, this value must be user configurable to adapt it to the peers
connected to the GSN.

The 60 seconds hardcoded value is therefore changed to default to our
local (T3-RESPONSE * N3-REQUESTS), since the most common scenario for
osmo-ggsn/osmo-sgsn is to run it against a peer osmo-sgsn/osmo-ggsn,
which will have the same values by default.
This way we avoid by default caching response messages for way too long,
potentially filling the queue.

Related: OS#5485
Change-Id: Ia15c1cfd201d7c43e9a1d6ceb6725ddf392d2c65
This commit is contained in:
Pau Espin 2022-11-04 11:21:23 +01:00
parent 9f1f747d8e
commit 3a55b89777
3 changed files with 7 additions and 1 deletions

View File

@ -108,6 +108,9 @@ struct osmo_tdef gtp_T_defs[] = {
{ .T = GTP_GSN_TIMER_N3_REQUESTS, .default_val = 3, .unit = OSMO_TDEF_CUSTOM,
.desc = "Counter N3-REQUESTS holds the maximum number of attempts made by GTP to send a request message"
},
{ .T = GTP_GSN_TIMER_T3_HOLD_RESPONSE, .default_val = 5 * 3 /* (GTP_GSN_TIMER_T3_RESPONSE * GTP_GSN_TIMER_N3_REQUESTS) */, .unit = OSMO_TDEF_S,
.desc = "Time a GTP respoonse message is kept cached to re-transmit it when a duplicate request is received. Value is generally equal to (T3-RESPONSE * N3-REQUESTS) set at the peer"
},
{}
};

View File

@ -67,6 +67,7 @@ enum gsn_rate_ctr_keys {
enum gtp_gsn_timers {
GTP_GSN_TIMER_T3_RESPONSE = 3,
GTP_GSN_TIMER_N3_REQUESTS = 1003,
GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3,
};
struct gsn_t {

View File

@ -499,11 +499,13 @@ static int gtp_resp(uint8_t version, struct gsn_t *gsn, struct pdp_t *pdp,
LOGP(DLGTP, LOGL_ERROR, "Retransmit resp queue is full (seq=%" PRIu16 ")\n",
seq);
} else {
unsigned int t3_hold_resp;
LOGP(DLGTP, LOGL_DEBUG, "Registering seq=%" PRIu16
" in restransmit resp queue\n", seq);
t3_hold_resp = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_T3_HOLD_RESPONSE, OSMO_TDEF_S, -1);
memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
qmsg->l = len;
qmsg->timeout = time(NULL) + 60; /* When to timeout */
qmsg->timeout = time(NULL) + t3_hold_resp; /* When to timeout */
qmsg->retrans = 0; /* No retransmissions so far */
qmsg->cbp = NULL;
qmsg->type = 0;