diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs/gb_proxy.c | 24 | ||||
-rw-r--r-- | src/gprs/gb_proxy_vty.c | 38 |
2 files changed, 54 insertions, 8 deletions
diff --git a/src/gprs/gb_proxy.c b/src/gprs/gb_proxy.c index f834ed3e6..8bb67895e 100644 --- a/src/gprs/gb_proxy.c +++ b/src/gprs/gb_proxy.c @@ -338,7 +338,8 @@ static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer, msgb_nsei(msg)); /* Patch and flush stored messages towards the SGSN */ - while ((stored_msg = msgb_dequeue(&link_info->stored_msgs))) { + while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs, + &link_info->stored_msgs_len))) { struct gprs_gb_parse_context tmp_parse_ctx = {0}; tmp_parse_ctx.to_bss = 0; tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg); @@ -492,6 +493,24 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, /* The message cannot be processed since the IMSI is still missing */ + /* If queue is getting too large, drop oldest msgb before adding new one */ + if (peer->cfg->stored_msgs_max_len > 0) { + int exceeded_max_len = link_info->stored_msgs_len + + 1 - peer->cfg->stored_msgs_max_len; + + for (; exceeded_max_len > 0; exceeded_max_len--) { + struct msgb *msgb_drop; + msgb_drop = msgb_dequeue_count(&link_info->stored_msgs, + &link_info->stored_msgs_len); + LOGP(DLLC, LOGL_INFO, + "NSEI=%d(BSS) Dropping stored msgb from list " + "(!acq imsi, length %d, max_len exceeded)\n", + msgb_nsei(msgb_drop), link_info->stored_msgs_len); + + msgb_free(msgb_drop); + } + } + /* Enqueue unpatched messages */ LOGP(DLLC, LOGL_INFO, "NSEI=%d(BSS) IMSI acquisition in progress, " @@ -500,7 +519,8 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul"); - msgb_enqueue(&link_info->stored_msgs, stored_msg); + msgb_enqueue_count(&link_info->stored_msgs, stored_msg, + &link_info->stored_msgs_len); if (!link_info->imsi_acq_pending) { LOGP(DLLC, LOGL_INFO, diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c index cd10abfda..d74335556 100644 --- a/src/gprs/gb_proxy_vty.c +++ b/src/gprs/gb_proxy_vty.c @@ -23,6 +23,7 @@ #include <arpa/inet.h> #include <string.h> #include <time.h> +#include <inttypes.h> #include <osmocom/core/talloc.h> #include <osmocom/core/rate_ctr.h> @@ -128,6 +129,9 @@ static int config_write_gbproxy(struct vty *vty) vty_out(vty, " link-list keep-mode %s%s", get_value_string(keep_modes, g_cfg->keep_link_infos), VTY_NEWLINE); + if (g_cfg->stored_msgs_max_len > 0) + vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s", + g_cfg->stored_msgs_max_len, VTY_NEWLINE); return CMD_SUCCESS; @@ -402,6 +406,7 @@ DEFUN(cfg_gbproxy_no_secondary_sgsn, } #define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n" +#define GBPROXY_LINK_STR "Set TLLI parameters\n" #define GBPROXY_MAX_AGE_STR "Limit maximum age\n" DEFUN(cfg_gbproxy_link_list_max_age, @@ -464,6 +469,27 @@ DEFUN(cfg_gbproxy_link_list_keep_mode, return CMD_SUCCESS; } +DEFUN(cfg_gbproxy_link_stored_msgs_max_len, + cfg_gbproxy_link_stored_msgs_max_len_cmd, + "link stored-msgs-max-length <1-99999>", + GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR + "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n") +{ + g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len, + cfg_gbproxy_link_no_stored_msgs_max_len_cmd, + "no link stored-msgs-max-length", + NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR) +{ + g_cfg->stored_msgs_max_len = 0; + + return CMD_SUCCESS; +} + DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]", SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n") @@ -502,10 +528,6 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links", llist_for_each_entry(link_info, &state->logical_links, list) { time_t age = now - link_info->timestamp; - int stored_msgs = 0; - struct llist_head *iter; - llist_for_each(iter, &link_info->stored_msgs) - stored_msgs++; if (link_info->imsi > 0) { snprintf(mi_buf, sizeof(mi_buf), "(invalid)"); @@ -518,8 +540,10 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links", vty_out(vty, " TLLI %08x, IMSI %s, AGE %d", link_info->tlli.current, mi_buf, (int)age); - if (stored_msgs) - vty_out(vty, ", STORED %d", stored_msgs); + if (link_info->stored_msgs_len) + vty_out(vty, ", STORED %"PRIu32"/%"PRIu32, + link_info->stored_msgs_len, + g_cfg->stored_msgs_max_len); if (g_cfg->route_to_sgsn2) vty_out(vty, ", SGSN NSEI %d", @@ -825,6 +849,7 @@ int gbproxy_vty_init(void) install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd); + install_element(GBPROXY_NODE, &cfg_gbproxy_link_stored_msgs_max_len_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd); @@ -834,6 +859,7 @@ int gbproxy_vty_init(void) install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd); install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd); + install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd); /* broken or deprecated to allow an upgrade path */ install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd); |