fix byte buffer double free in EPC

master
Francisco 4 years ago committed by Francisco Paisana
parent d2ddcb0d4e
commit 798f1e57e6

@ -196,6 +196,7 @@ public:
print_error("Error deallocating PDU: Addr=0x%p, name=%s not found in pool", (void*)b, b->debug_name); print_error("Error deallocating PDU: Addr=0x%p, name=%s not found in pool", (void*)b, b->debug_name);
#else #else
print_error("Error deallocating PDU: Addr=0x%p", (void*)b); print_error("Error deallocating PDU: Addr=0x%p", (void*)b);
srslog::fetch_basic_logger("EPC").error("ERROR deallocating PDU: Addr=0x%p\n", (void*)b);
#endif #endif
} }
} }

@ -108,13 +108,13 @@ public:
virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4) = 0; virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4) = 0;
virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4) = 0; virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4) = 0;
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue) = 0; std::queue<srslte::unique_byte_buffer_t>& pkt_queue) = 0;
}; };
class gtpc_interface_gtpu // GTP-U -> GTP-C class gtpc_interface_gtpu // GTP-U -> GTP-C
{ {
public: public:
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg) = 0; virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) = 0;
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0; virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0;
}; };

@ -55,8 +55,8 @@ public:
const srslte::gtpc_header& header, const srslte::gtpc_header& header,
const srslte::gtpc_downlink_data_notification_failure_indication& not_fail); const srslte::gtpc_downlink_data_notification_failure_indication& not_fail);
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg); virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) override;
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid); virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) override;
spgw_tunnel_ctx_t* create_gtpc_ctx(const srslte::gtpc_create_session_request& cs_req); spgw_tunnel_ctx_t* create_gtpc_ctx(const srslte::gtpc_create_session_request& cs_req);
bool delete_gtpc_ctx(uint32_t ctrl_teid); bool delete_gtpc_ctx(uint32_t ctrl_teid);

@ -37,7 +37,7 @@ public:
int get_sgi(); int get_sgi();
int get_s1u(); int get_s1u();
void handle_sgi_pdu(srslte::byte_buffer_t* msg); void handle_sgi_pdu(srslte::unique_byte_buffer_t msg);
void handle_s1u_pdu(srslte::byte_buffer_t* msg); void handle_s1u_pdu(srslte::byte_buffer_t* msg);
void send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer_t* msg); void send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer_t* msg);
@ -47,7 +47,7 @@ public:
virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4); virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4);
virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4); virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4);
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue); std::queue<srslte::unique_byte_buffer_t>& pkt_queue);
spgw* m_spgw; spgw* m_spgw;
gtpc_interface_gtpu* m_gtpc; gtpc_interface_gtpu* m_gtpc;

@ -50,7 +50,7 @@ typedef struct spgw_tunnel_ctx {
srslte::gtp_fteid_t dw_ctrl_fteid; srslte::gtp_fteid_t dw_ctrl_fteid;
srslte::gtp_fteid_t dw_user_fteid; srslte::gtp_fteid_t dw_user_fteid;
bool paging_pending; bool paging_pending;
std::queue<srslte::byte_buffer_t*> paging_queue; std::queue<srslte::unique_byte_buffer_t> paging_queue;
} spgw_tunnel_ctx_t; } spgw_tunnel_ctx_t;
class spgw : public srslte::thread class spgw : public srslte::thread

@ -230,8 +230,7 @@ void mbms_gw::run_thread()
{ {
// Mark the thread as running // Mark the thread as running
m_running = true; m_running = true;
srslte::byte_buffer_t* msg; srslte::unique_byte_buffer_t msg = srslte::make_byte_buffer();
msg = new srslte::byte_buffer_t();
uint8_t seq = 0; uint8_t seq = 0;
while (m_running) { while (m_running) {
@ -245,10 +244,9 @@ void mbms_gw::run_thread()
m_logger.error("Error reading from TUN interface. Error: %s", strerror(errno)); m_logger.error("Error reading from TUN interface. Error: %s", strerror(errno));
} else { } else {
msg->N_bytes = n; msg->N_bytes = n;
handle_sgi_md_pdu(msg); handle_sgi_md_pdu(msg.get());
} }
} }
delete msg;
return; return;
} }

@ -197,7 +197,7 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
const nas_if_t& itf) const nas_if_t& itf)
{ {
nas* nas_ctx; nas* nas_ctx;
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS"); auto& nas_logger = srslog::fetch_basic_logger("NAS");
// Interfaces // Interfaces
@ -260,7 +260,6 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
nas_ctx->m_sec_ctx.xres)) { nas_ctx->m_sec_ctx.xres)) {
srslte::console("User not found. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); srslte::console("User not found. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi);
nas_logger.info("User not found. IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); nas_logger.info("User not found. IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi);
delete nas_ctx;
return false; return false;
} }
@ -274,13 +273,12 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
// Pack NAS Authentication Request in Downlink NAS Transport msg // Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_authentication_request(nas_tx); nas_ctx->pack_authentication_request(nas_tx.get());
// Send reply to eNB // Send reply to eNB
s1ap->send_downlink_nas_transport( s1ap->send_downlink_nas_transport(
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri); nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri);
delete nas_tx;
nas_logger.info("Downlink NAS: Sending Authentication Request"); nas_logger.info("Downlink NAS: Sending Authentication Request");
srslte::console("Downlink NAS: Sending Authentication Request\n"); srslte::console("Downlink NAS: Sending Authentication Request\n");
@ -328,7 +326,7 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t
{ {
nas* nas_ctx; nas* nas_ctx;
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
// Interfaces // Interfaces
s1ap_interface_nas* s1ap = itf.s1ap; s1ap_interface_nas* s1ap = itf.s1ap;
@ -384,11 +382,10 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
// Send Identity Request // Send Identity Request
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_identity_request(nas_tx); nas_ctx->pack_identity_request(nas_tx.get());
s1ap->send_downlink_nas_transport( s1ap->send_downlink_nas_transport(
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri); nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri);
delete nas_tx;
return true; return true;
} }
@ -403,7 +400,7 @@ bool nas::handle_guti_attach_request_known_ue(nas*
const nas_if_t& itf) const nas_if_t& itf)
{ {
bool msg_valid = false; bool msg_valid = false;
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS"); auto& nas_logger = srslog::fetch_basic_logger("NAS");
emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx;
@ -461,12 +458,12 @@ bool nas::handle_guti_attach_request_known_ue(nas*
nas_logger.info(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)"); nas_logger.info(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)");
// Send reply // Send reply
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
if (ecm_ctx->eit) { if (ecm_ctx->eit) {
srslte::console("Secure ESM information transfer requested.\n"); srslte::console("Secure ESM information transfer requested.\n");
nas_logger.info("Secure ESM information transfer requested."); nas_logger.info("Secure ESM information transfer requested.");
nas_ctx->pack_esm_information_request(nas_tx); nas_ctx->pack_esm_information_request(nas_tx.get());
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
} else { } else {
// Get subscriber info from HSS // Get subscriber info from HSS
uint8_t default_bearer = 5; uint8_t default_bearer = 5;
@ -476,7 +473,6 @@ bool nas::handle_guti_attach_request_known_ue(nas*
gtpc->send_create_session_request(emm_ctx->imsi); gtpc->send_create_session_request(emm_ctx->imsi);
} }
sec_ctx->ul_nas_count++; sec_ctx->ul_nas_count++;
delete nas_tx;
return true; return true;
} else { } else {
if (emm_ctx->state != EMM_STATE_DEREGISTERED) { if (emm_ctx->state != EMM_STATE_DEREGISTERED) {
@ -535,12 +531,11 @@ bool nas::handle_guti_attach_request_known_ue(nas*
// Restarting security context. Reseting eKSI to 0. // Restarting security context. Reseting eKSI to 0.
sec_ctx->eksi = 0; sec_ctx->eksi = 0;
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::unique_byte_buffer_t();
nas_ctx->pack_authentication_request(nas_tx); nas_ctx->pack_authentication_request(nas_tx.get());
// Send reply to eNB // Send reply to eNB
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
delete nas_tx;
nas_logger.info("Downlink NAS: Sent Authentication Request"); nas_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n"); srslte::console("Downlink NAS: Sent Authentication Request\n");
return true; return true;
@ -585,10 +580,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
delete nas_tx;
return true; return true;
} }
@ -600,10 +594,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
delete nas_tx;
return true; return true;
} }
emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx;
@ -685,10 +678,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx);
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); nas_ctx->pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
delete nas_tx;
srslte::console("Service Request -- Short MAC invalid. Sending service reject.\n"); srslte::console("Service Request -- Short MAC invalid. Sending service reject.\n");
nas_logger.warning("Service Request -- Short MAC invalid. Sending service reject."); nas_logger.warning("Service Request -- Short MAC invalid. Sending service reject.");
@ -790,10 +782,9 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); nas_tmp.pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
delete nas_tx;
return true; return true;
} }
@ -894,12 +885,12 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx)
m_s1ap->add_nas_ctx_to_imsi_map(this); m_s1ap->add_nas_ctx_to_imsi_map(this);
// Pack NAS Authentication Request in Downlink NAS Transport msg // Pack NAS Authentication Request in Downlink NAS Transport msg
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx); pack_authentication_request(nas_tx.get());
// Send reply to eNB // Send reply to eNB
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
delete nas_tx; m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
m_logger.info("Downlink NAS: Sending Authentication Request"); m_logger.info("Downlink NAS: Sending Authentication Request");
srslte::console("Downlink NAS: Sending Authentication Request\n"); srslte::console("Downlink NAS: Sending Authentication Request\n");
@ -912,7 +903,7 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx)
bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx) bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
{ {
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp; LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp;
bool ue_valid = true; bool ue_valid = true;
@ -936,14 +927,14 @@ bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
} }
} }
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
if (!ue_valid) { if (!ue_valid) {
// Authentication rejected // Authentication rejected
srslte::console("UE Authentication Rejected.\n"); srslte::console("UE Authentication Rejected.\n");
m_logger.warning("UE Authentication Rejected."); m_logger.warning("UE Authentication Rejected.");
// Send back Athentication Reject // Send back Athentication Reject
pack_authentication_reject(nas_tx); pack_authentication_reject(nas_tx.get());
m_logger.info("Downlink NAS: Sending Authentication Reject."); m_logger.info("Downlink NAS: Sending Authentication Reject.");
} else { } else {
// Authentication accepted // Authentication accepted
@ -952,19 +943,19 @@ bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
// Send Security Mode Command // Send Security Mode Command
m_sec_ctx.ul_nas_count = 0; // Reset the NAS uplink counter for the right key k_enb derivation m_sec_ctx.ul_nas_count = 0; // Reset the NAS uplink counter for the right key k_enb derivation
pack_security_mode_command(nas_tx); pack_security_mode_command(nas_tx.get());
srslte::console("Downlink NAS: Sending NAS Security Mode Command.\n"); srslte::console("Downlink NAS: Sending NAS Security Mode Command.\n");
} }
// Send reply // Send reply
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
delete nas_tx; m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
return true; return true;
} }
bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx) bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
{ {
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp;
// Get NAS security mode complete // Get NAS security mode complete
@ -979,15 +970,16 @@ bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
srslte::console("Security Mode Command Complete -- IMSI: %015" PRIu64 "\n", m_emm_ctx.imsi); srslte::console("Security Mode Command Complete -- IMSI: %015" PRIu64 "\n", m_emm_ctx.imsi);
// Check wether secure ESM information transfer is required // Check wether secure ESM information transfer is required
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
if (m_ecm_ctx.eit == true) { if (m_ecm_ctx.eit == true) {
// Secure ESM information transfer is required // Secure ESM information transfer is required
srslte::console("Sending ESM information request\n"); srslte::console("Sending ESM information request\n");
m_logger.info("Sending ESM information request"); m_logger.info("Sending ESM information request");
// Packing ESM information request // Packing ESM information request
pack_esm_information_request(nas_tx); pack_esm_information_request(nas_tx.get());
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
} else { } else {
// Secure ESM information transfer not necessary // Secure ESM information transfer not necessary
// Sending create session request to SP-GW. // Sending create session request to SP-GW.
@ -997,7 +989,6 @@ bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
srslte::console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); srslte::console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
m_gtpc->send_create_session_request(m_emm_ctx.imsi); m_gtpc->send_create_session_request(m_emm_ctx.imsi);
} }
delete nas_tx;
return true; return true;
} }
@ -1006,7 +997,7 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx)
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp; LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp;
uint8_t pd, msg_type; uint8_t pd, msg_type;
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer;
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
// Get NAS authentication response // Get NAS authentication response
std::memset(&attach_comp, 0, sizeof(attach_comp)); std::memset(&attach_comp, 0, sizeof(attach_comp));
@ -1036,11 +1027,11 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx)
m_emm_ctx.imsi, act_bearer.eps_bearer_id, &m_esm_ctx[act_bearer.eps_bearer_id].enb_fteid); m_emm_ctx.imsi, act_bearer.eps_bearer_id, &m_esm_ctx[act_bearer.eps_bearer_id].enb_fteid);
// Send reply to EMM Info to UE // Send reply to EMM Info to UE
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
pack_emm_information(nas_tx); pack_emm_information(nas_tx.get());
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
delete nas_tx; m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
srslte::console("Sending EMM Information\n"); srslte::console("Sending EMM Information\n");
m_logger.info("Sending EMM Information"); m_logger.info("Sending EMM Information");
@ -1085,7 +1076,7 @@ bool nas::handle_esm_information_response(srslte::byte_buffer_t* nas_rx)
bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx)
{ {
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp;
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &id_resp); LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &id_resp);
@ -1125,12 +1116,12 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx)
m_s1ap->add_nas_ctx_to_imsi_map(this); m_s1ap->add_nas_ctx_to_imsi_map(this);
// Pack NAS Authentication Request in Downlink NAS Transport msg // Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx); pack_authentication_request(nas_tx.get());
// Send reply to eNB // Send reply to eNB
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
delete nas_tx; m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
m_logger.info("Downlink NAS: Sent Authentication Request"); m_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n"); srslte::console("Downlink NAS: Sent Authentication Request\n");
@ -1142,16 +1133,16 @@ bool nas::handle_tracking_area_update_request(srslte::byte_buffer_t* nas_rx)
srslte::console("Warning: Tracking Area Update Request messages not handled yet.\n"); srslte::console("Warning: Tracking Area Update Request messages not handled yet.\n");
m_logger.warning("Warning: Tracking Area Update Request messages not handled yet."); m_logger.warning("Warning: Tracking Area Update Request messages not handled yet.");
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
/* TAU handling unsupported, therefore send TAU reject with cause IMPLICITLY DETACHED. /* TAU handling unsupported, therefore send TAU reject with cause IMPLICITLY DETACHED.
* this will trigger full re-attach by the UE, instead of going to a TAU request loop */ * this will trigger full re-attach by the UE, instead of going to a TAU request loop */
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
// TODO we could enable integrity protection in some cases, but UE should comply anyway // TODO we could enable integrity protection in some cases, but UE should comply anyway
pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
// Send reply // Send reply
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_s1ap->send_downlink_nas_transport(
delete nas_tx; m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
return true; return true;
} }
@ -1160,7 +1151,7 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx)
{ {
m_logger.info("Received Authentication Failure"); m_logger.info("Received Authentication Failure");
srslte::byte_buffer_t* nas_tx; srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail; LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail;
LIBLTE_ERROR_ENUM err; LIBLTE_ERROR_ENUM err;
@ -1203,13 +1194,12 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx)
m_sec_ctx.eksi = (m_sec_ctx.eksi + 1) % 6; m_sec_ctx.eksi = (m_sec_ctx.eksi + 1) % 6;
// Pack NAS Authentication Request in Downlink NAS Transport msg // Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t(); nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx); pack_authentication_request(nas_tx.get());
// Send reply to eNB // Send reply to eNB
m_s1ap->send_downlink_nas_transport( m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
delete nas_tx;
m_logger.info("Downlink NAS: Sent Authentication Request"); m_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n"); srslte::console("Downlink NAS: Sent Authentication Request\n");

@ -82,14 +82,14 @@ bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg
{ {
bool err, mac_valid; bool err, mac_valid;
uint8_t pd, msg_type, sec_hdr_type; uint8_t pd, msg_type, sec_hdr_type;
srslte::byte_buffer_t* nas_msg = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer();
memcpy(nas_msg->msg, init_ue.protocol_ies.nas_pdu.value.data(), init_ue.protocol_ies.nas_pdu.value.size()); memcpy(nas_msg->msg, init_ue.protocol_ies.nas_pdu.value.data(), init_ue.protocol_ies.nas_pdu.value.size());
nas_msg->N_bytes = init_ue.protocol_ies.nas_pdu.value.size(); nas_msg->N_bytes = init_ue.protocol_ies.nas_pdu.value.size();
uint64_t imsi = 0; uint64_t imsi = 0;
uint32_t m_tmsi = 0; uint32_t m_tmsi = 0;
uint32_t enb_ue_s1ap_id = init_ue.protocol_ies.enb_ue_s1ap_id.value.value; uint32_t enb_ue_s1ap_id = init_ue.protocol_ies.enb_ue_s1ap_id.value.value;
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type); liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type);
srslte::console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); srslte::console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type));
m_logger.info("Initial UE message: %s", liblte_nas_msg_type_to_string(msg_type)); m_logger.info("Initial UE message: %s", liblte_nas_msg_type_to_string(msg_type));
@ -102,29 +102,29 @@ bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg
case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST:
srslte::console("Received Initial UE message -- Attach Request\n"); srslte::console("Received Initial UE message -- Attach Request\n");
m_logger.info("Received Initial UE message -- Attach Request"); m_logger.info("Received Initial UE message -- Attach Request");
err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if); err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break; break;
case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST:
srslte::console("Received Initial UE message -- Service Request\n"); srslte::console("Received Initial UE message -- Service Request\n");
m_logger.info("Received Initial UE message -- Service Request"); m_logger.info("Received Initial UE message -- Service Request");
err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if); err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break; break;
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
srslte::console("Received Initial UE message -- Detach Request\n"); srslte::console("Received Initial UE message -- Detach Request\n");
m_logger.info("Received Initial UE message -- Detach Request"); m_logger.info("Received Initial UE message -- Detach Request");
err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if); err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break; break;
case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST:
srslte::console("Received Initial UE message -- Tracking Area Update Request\n"); srslte::console("Received Initial UE message -- Tracking Area Update Request\n");
m_logger.info("Received Initial UE message -- Tracking Area Update Request"); m_logger.info("Received Initial UE message -- Tracking Area Update Request");
err = nas::handle_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if); err = nas::handle_tracking_area_update_request(
m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break; break;
default: default:
m_logger.info("Unhandled Initial UE Message 0x%x ", msg_type); m_logger.info("Unhandled Initial UE Message 0x%x ", msg_type);
srslte::console("Unhandled Initial UE Message 0x%x \n", msg_type); srslte::console("Unhandled Initial UE Message 0x%x \n", msg_type);
err = false; err = false;
} }
delete nas_msg;
return err; return err;
} }
@ -150,13 +150,13 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_ctx_t* sec_ctx = &nas_ctx->m_sec_ctx; sec_ctx_t* sec_ctx = &nas_ctx->m_sec_ctx;
// Parse NAS message header // Parse NAS message header
srslte::byte_buffer_t* nas_msg = new srslte::byte_buffer_t(); srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer();
memcpy(nas_msg->msg, ul_xport.protocol_ies.nas_pdu.value.data(), ul_xport.protocol_ies.nas_pdu.value.size()); memcpy(nas_msg->msg, ul_xport.protocol_ies.nas_pdu.value.data(), ul_xport.protocol_ies.nas_pdu.value.size());
nas_msg->N_bytes = ul_xport.protocol_ies.nas_pdu.value.size(); nas_msg->N_bytes = ul_xport.protocol_ies.nas_pdu.value.size();
bool msg_encrypted = false; bool msg_encrypted = false;
// Parse the message security header // Parse the message security header
liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &sec_hdr_type);
// Invalid Security Header Type simply return function // Invalid Security Header Type simply return function
if (!(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS || if (!(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS ||
@ -165,7 +165,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT)) { sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT)) {
m_logger.error("Unhandled security header type in Uplink NAS Transport: %d", sec_hdr_type); m_logger.error("Unhandled security header type in Uplink NAS Transport: %d", sec_hdr_type);
delete nas_msg;
return false; return false;
} }
// Todo: Check on count mismatch of uplink count and do resync nas counter... // Todo: Check on count mismatch of uplink count and do resync nas counter...
@ -175,7 +174,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) {
mac_valid = nas_ctx->integrity_check(nas_msg); mac_valid = nas_ctx->integrity_check(nas_msg.get());
if (mac_valid == false) { if (mac_valid == false) {
m_logger.warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: " m_logger.warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: "
"Identity Response or Authentication Response)"); "Identity Response or Authentication Response)");
@ -186,13 +185,13 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) {
m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Encrypted"); m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Encrypted");
nas_ctx->cipher_decrypt(nas_msg); nas_ctx->cipher_decrypt(nas_msg.get());
msg_encrypted = true; msg_encrypted = true;
m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Decrypted"); m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Decrypted");
} }
// Now parse message header and handle message // Now parse message header and handle message
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type); liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type);
// Find UE EMM context if message is security protected. // Find UE EMM context if message is security protected.
if (sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { if (sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) {
@ -205,7 +204,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.warning( m_logger.warning(
"Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d", "Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d",
mme_ue_s1ap_id); mme_ue_s1ap_id);
delete nas_msg;
return false; return false;
} }
} }
@ -231,17 +229,17 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST:
m_logger.info("UL NAS: Attach Request"); m_logger.info("UL NAS: Attach Request");
srslte::console("UL NAS: Attach Resquest\n"); srslte::console("UL NAS: Attach Resquest\n");
nas_ctx->handle_attach_request(nas_msg); nas_ctx->handle_attach_request(nas_msg.get());
break; break;
case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE:
m_logger.info("UL NAS: Received Identity Response"); m_logger.info("UL NAS: Received Identity Response");
srslte::console("UL NAS: Received Identity Response\n"); srslte::console("UL NAS: Received Identity Response\n");
nas_ctx->handle_identity_response(nas_msg); nas_ctx->handle_identity_response(nas_msg.get());
break; break;
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE:
m_logger.info("UL NAS: Received Authentication Response"); m_logger.info("UL NAS: Received Authentication Response");
srslte::console("UL NAS: Received Authentication Response\n"); srslte::console("UL NAS: Received Authentication Response\n");
nas_ctx->handle_authentication_response(nas_msg); nas_ctx->handle_authentication_response(nas_msg.get());
// In case of a successful authentication response, security mode command follows. // In case of a successful authentication response, security mode command follows.
// Reset counter for incoming security mode complete // Reset counter for incoming security mode complete
sec_ctx->ul_nas_count = 0; sec_ctx->ul_nas_count = 0;
@ -252,21 +250,21 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE:
m_logger.info("UL NAS: Authentication Failure"); m_logger.info("UL NAS: Authentication Failure");
srslte::console("UL NAS: Authentication Failure\n"); srslte::console("UL NAS: Authentication Failure\n");
nas_ctx->handle_authentication_failure(nas_msg); nas_ctx->handle_authentication_failure(nas_msg.get());
break; break;
// Detach request can be sent not integrity protected when "power off" option is used // Detach request can be sent not integrity protected when "power off" option is used
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
m_logger.info("UL NAS: Detach Request"); m_logger.info("UL NAS: Detach Request");
srslte::console("UL NAS: Detach Request\n"); srslte::console("UL NAS: Detach Request\n");
// TODO: check integrity protection in detach request // TODO: check integrity protection in detach request
nas_ctx->handle_detach_request(nas_msg); nas_ctx->handle_detach_request(nas_msg.get());
break; break;
case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE:
m_logger.info("UL NAS: Received Security Mode Complete"); m_logger.info("UL NAS: Received Security Mode Complete");
srslte::console("UL NAS: Received Security Mode Complete\n"); srslte::console("UL NAS: Received Security Mode Complete\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT && if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT &&
mac_valid == true) { mac_valid == true) {
nas_ctx->handle_security_mode_complete(nas_msg); nas_ctx->handle_security_mode_complete(nas_msg.get());
} else { } else {
// Security Mode Complete was not integrity protected // Security Mode Complete was not integrity protected
srslte::console("Security Mode Complete %s. Discard message.\n", srslte::console("Security Mode Complete %s. Discard message.\n",
@ -280,7 +278,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.info("UL NAS: Received Attach Complete"); m_logger.info("UL NAS: Received Attach Complete");
srslte::console("UL NAS: Received Attach Complete\n"); srslte::console("UL NAS: Received Attach Complete\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) { if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) {
nas_ctx->handle_attach_complete(nas_msg); nas_ctx->handle_attach_complete(nas_msg.get());
} else { } else {
// Attach Complete was not integrity protected // Attach Complete was not integrity protected
srslte::console("Attach Complete not integrity protected. Discard message.\n"); srslte::console("Attach Complete not integrity protected. Discard message.\n");
@ -292,7 +290,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.info("UL NAS: Received ESM Information Response"); m_logger.info("UL NAS: Received ESM Information Response");
srslte::console("UL NAS: Received ESM Information Response\n"); srslte::console("UL NAS: Received ESM Information Response\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) { if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) {
nas_ctx->handle_esm_information_response(nas_msg); nas_ctx->handle_esm_information_response(nas_msg.get());
} else { } else {
// Attach Complete was not integrity protected // Attach Complete was not integrity protected
srslte::console("ESM Information Response %s. Discard message.\n", srslte::console("ESM Information Response %s. Discard message.\n",
@ -305,12 +303,11 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST:
m_logger.info("UL NAS: Tracking Area Update Request"); m_logger.info("UL NAS: Tracking Area Update Request");
srslte::console("UL NAS: Tracking Area Update Request\n"); srslte::console("UL NAS: Tracking Area Update Request\n");
nas_ctx->handle_tracking_area_update_request(nas_msg); nas_ctx->handle_tracking_area_update_request(nas_msg.get());
break; break;
default: default:
m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type)); m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type));
srslte::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type)); srslte::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type));
delete nas_msg;
return false; return false;
} }
@ -319,7 +316,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
if (increase_ul_nas_cnt == true) { if (increase_ul_nas_cnt == true) {
sec_ctx->ul_nas_count++; sec_ctx->ul_nas_count++;
} }
delete nas_msg;
return true; return true;
} }

@ -484,7 +484,7 @@ bool spgw::gtpc::delete_gtpc_ctx(uint32_t ctrl_teid)
/* /*
* Queueing functions * Queueing functions
*/ */
bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t* msg) bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::unique_byte_buffer_t msg)
{ {
spgw_tunnel_ctx_t* tunnel_ctx; spgw_tunnel_ctx_t* tunnel_ctx;
if (!m_teid_to_tunnel_ctx.count(ctrl_teid)) { if (!m_teid_to_tunnel_ctx.count(ctrl_teid)) {
@ -498,7 +498,7 @@ bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t
} }
if (tunnel_ctx->paging_queue.size() < m_max_paging_queue) { if (tunnel_ctx->paging_queue.size() < m_max_paging_queue) {
tunnel_ctx->paging_queue.push(msg); tunnel_ctx->paging_queue.push(std::move(msg));
m_logger.debug( m_logger.debug(
"Queued packet. IMSI %" PRIu64 ", Packets in Queue %zd", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size()); "Queued packet. IMSI %" PRIu64 ", Packets in Queue %zd", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size());
} else { } else {
@ -509,7 +509,6 @@ bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t
return true; return true;
pkt_discard: pkt_discard:
delete msg;
return false; return false;
} }
@ -520,9 +519,8 @@ bool spgw::gtpc::free_all_queued_packets(spgw_tunnel_ctx_t* tunnel_ctx)
} }
while (!tunnel_ctx->paging_queue.empty()) { while (!tunnel_ctx->paging_queue.empty()) {
srslte::byte_buffer_t* pkt = tunnel_ctx->paging_queue.front(); srslte::unique_byte_buffer_t pkt = std::move(tunnel_ctx->paging_queue.front());
m_logger.debug("Dropping packet. Bytes %d", pkt->N_bytes); m_logger.debug("Dropping packet. Bytes %d", pkt->N_bytes);
delete pkt;
tunnel_ctx->paging_queue.pop(); tunnel_ctx->paging_queue.pop();
} }
return true; return true;

@ -186,7 +186,7 @@ int spgw::gtpu::init_s1u(spgw_args_t* args)
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg) void spgw::gtpu::handle_sgi_pdu(srslte::unique_byte_buffer_t msg)
{ {
bool usr_found = false; bool usr_found = false;
bool ctr_found = false; bool ctr_found = false;
@ -227,24 +227,17 @@ void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg)
// Handle SGi packet // Handle SGi packet
if (usr_found == false && ctr_found == false) { if (usr_found == false && ctr_found == false) {
m_logger.debug("Packet for unknown UE."); m_logger.debug("Packet for unknown UE.");
goto pkt_discard_out;
} else if (usr_found == false && ctr_found == true) { } else if (usr_found == false && ctr_found == true) {
m_logger.debug("Packet for attached UE that is not ECM connected."); m_logger.debug("Packet for attached UE that is not ECM connected.");
m_logger.debug("Triggering Donwlink Notification Requset."); m_logger.debug("Triggering Donwlink Notification Requset.");
m_gtpc->send_downlink_data_notification(spgw_teid); m_gtpc->send_downlink_data_notification(spgw_teid);
m_gtpc->queue_downlink_packet(spgw_teid, msg); m_gtpc->queue_downlink_packet(spgw_teid, std::move(msg));
return; return;
} else if (usr_found == false && ctr_found == true) { } else if (usr_found == false && ctr_found == true) {
m_logger.error("User plane tunnel found without a control plane tunnel present."); m_logger.error("User plane tunnel found without a control plane tunnel present.");
goto pkt_discard_out;
} else { } else {
send_s1u_pdu(enb_fteid, msg); send_s1u_pdu(enb_fteid, msg.get());
} }
return;
pkt_discard_out:
delete msg;
return;
} }
void spgw::gtpu::handle_s1u_pdu(srslte::byte_buffer_t* msg) void spgw::gtpu::handle_s1u_pdu(srslte::byte_buffer_t* msg)
@ -298,17 +291,16 @@ void spgw::gtpu::send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer
out: out:
m_logger.debug("Deallocating packet after sending S1-U message"); m_logger.debug("Deallocating packet after sending S1-U message");
delete msg;
return; return;
} }
void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue) std::queue<srslte::unique_byte_buffer_t>& pkt_queue)
{ {
m_logger.debug("Sending all queued packets"); m_logger.debug("Sending all queued packets");
while (!pkt_queue.empty()) { while (!pkt_queue.empty()) {
srslte::byte_buffer_t* msg = pkt_queue.front(); srslte::unique_byte_buffer_t msg = std::move(pkt_queue.front());
send_s1u_pdu(dw_user_fteid, msg); send_s1u_pdu(dw_user_fteid, msg.get());
pkt_queue.pop(); pkt_queue.pop();
} }
return; return;

@ -136,7 +136,7 @@ void spgw::run_thread()
m_logger.debug("Message received at SPGW: SGi Message"); m_logger.debug("Message received at SPGW: SGi Message");
sgi_msg = srslte::make_byte_buffer("spgw::run_thread::sgi_msg"); sgi_msg = srslte::make_byte_buffer("spgw::run_thread::sgi_msg");
sgi_msg->N_bytes = read(sgi, sgi_msg->msg, buf_len); sgi_msg->N_bytes = read(sgi, sgi_msg->msg, buf_len);
m_gtpu->handle_sgi_pdu(sgi_msg.get()); m_gtpu->handle_sgi_pdu(std::move(sgi_msg));
} }
if (FD_ISSET(s1u, &set)) { if (FD_ISSET(s1u, &set)) {
m_logger.debug("Message received at SPGW: S1-U Message"); m_logger.debug("Message received at SPGW: S1-U Message");

Loading…
Cancel
Save