From 55f5f74ff39b8760db6d4de468be5e1c4d456fa8 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 20 Sep 2021 12:41:59 +0200 Subject: [PATCH] Fixed case where calling gw::setup_if_addr after ue attachment would spawn a new thread without closing the current one. This would end up being a resource leak as the number of threads grow forever until the application crashes. --- srsue/hdr/stack/upper/gw.h | 23 +++++++++-------------- srsue/src/stack/upper/gw.cc | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index 8ea0a345b..aec223558 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -54,14 +54,9 @@ public: void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu); // NAS interface - int setup_if_addr(uint32_t eps_bearer_id, - uint8_t pdn_type, - uint32_t ip_addr, - uint8_t* ipv6_if_addr, - char* err_str); + int setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str); int deactivate_eps_bearer(const uint32_t eps_bearer_id); - int apply_traffic_flow_template(const uint8_t& eps_bearer_id, - const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); + int apply_traffic_flow_template(const uint8_t& eps_bearer_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); void set_test_loop_mode(const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms); // RRC interface @@ -75,13 +70,13 @@ private: gw_args_t args = {}; - std::atomic running = {false}; - bool run_enable = false; - int32_t netns_fd = 0; - int32_t tun_fd = 0; - struct ifreq ifr = {}; - int32_t sock = 0; - bool if_up = false; + std::atomic running = {false}; + std::atomic run_enable = {false}; + int32_t netns_fd = 0; + int32_t tun_fd = 0; + struct ifreq ifr = {}; + int32_t sock = 0; + bool if_up = false; static const int NOT_ASSIGNED = -1; int32_t default_eps_bearer_id = NOT_ASSIGNED; diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 76fc7d97c..57c400cff 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -179,6 +179,13 @@ void gw::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) int gw::setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str) { int err; + + // Make sure the worker thread is terminated before spawning a new one. + if (running) { + run_enable = false; + thread_cancel(); + wait_thread_finish(); + } if (pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6) { err = setup_if_addr4(ip_addr, err_str); if (err != SRSRAN_SUCCESS) { @@ -195,6 +202,7 @@ int gw::setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr default_eps_bearer_id = static_cast(eps_bearer_id); // Setup a thread to receive packets from the TUN device + run_enable = true; start(GW_THREAD_PRIO); return SRSRAN_SUCCESS; @@ -446,6 +454,9 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) } } + if (sock > 0) { + close(sock); + } // Setup the IP address sock = socket(AF_INET, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET; @@ -495,6 +506,9 @@ int gw::setup_if_addr6(uint8_t* ipv6_if_id, char* err_str) } } + if (sock > 0) { + close(sock); + } // Setup the IP address sock = socket(AF_INET6, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET6;