Commit a69056a0 authored by gauthier's avatar gauthier
Browse files

Bug deadlock SPGW-C context, itti health_ping (TODO)

parent c2c583c3
......@@ -78,17 +78,23 @@ void async_cmd_task (void* args_p)
}
}
break;
case TIME_OUT:
if (itti_msg_timeout* to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::async_cmd().info( "TIME-OUT event timer id %d", to->timer_id);
}
break;
case TERMINATE:
if (itti_msg_terminate *terminate = dynamic_cast<itti_msg_terminate*>(msg)) {
Logger::async_cmd().info( "Received terminate message");
return;
}
break;
case HEALTH_PING:
break;
default:
Logger::sgwc_app().info( "no handler for msg type %d", msg->msg_type);
}
......
......@@ -632,6 +632,7 @@ void gtpv2c_stack::time_out_event(const uint32_t timer_id, const task_id_t& task
if (it_proc != pending_procedures.end()) {
if (it_proc->second.retry_count < GTPV2C_N3_REQUESTS) {
it_proc->second.retry_count++;
it_proc->second.retry_timer_id = 0;
start_msg_retry_timer(it_proc->second, GTPV2C_T3_RESPONSE_MS, task_id, it_proc->second.retry_msg->get_sequence_number());
// send again message
Logger::gtpv2_c().trace( "Retry %d Sending msg type %d, seq %d",
......
......@@ -120,13 +120,12 @@ void pgw_app::set_seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_con
seid2pgw_context[seid] = pc;
}
//------------------------------------------------------------------------------
bool pgw_app::seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_context>& pc, std::shared_lock<std::shared_mutex>& lock_found) const
bool pgw_app::seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_context>& pc) const
{
std::shared_lock lock(m_seid2pgw_context);
std::map<seid_t, std::shared_ptr<pgw_context>>::const_iterator it = seid2pgw_context.find(seid);
if (it != seid2pgw_context.end()) {
pc = it->second;
lock_found.swap(lock);
return true;
}
return false;
......@@ -259,6 +258,7 @@ void pgw_app_task (void*)
Logger::pgwc_app().info( "Received terminate message");
return;
}
case HEALTH_PING:
break;
default:
Logger::pgwc_app().info( "no handler for msg type %d", msg->msg_type);
......@@ -564,10 +564,8 @@ void pgw_app::handle_itti_msg (itti_s5s8_downlink_data_notification_acknowledge&
void pgw_app::handle_itti_msg (itti_sxab_session_establishment_response& seresp)
{
std::shared_ptr<pgw_context> pc = {};
std::shared_lock<std::shared_mutex> lpc;
if (seid_2_pgw_context(seresp.seid, pc, lpc)) {
if (seid_2_pgw_context(seresp.seid, pc)) {
pc.get()->handle_itti_msg(seresp);
lpc.unlock();
} else {
Logger::pgwc_app().debug("Received SXAB SESSION ESTABLISHMENT RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", pgw_context not found, discarded!", seresp.seid, seresp.trxn_id);
}
......@@ -576,10 +574,8 @@ void pgw_app::handle_itti_msg (itti_sxab_session_establishment_response& seresp)
void pgw_app::handle_itti_msg (itti_sxab_session_modification_response& smresp)
{
std::shared_ptr<pgw_context> pc = {};
std::shared_lock<std::shared_mutex> lpc;
if (seid_2_pgw_context(smresp.seid, pc, lpc)) {
if (seid_2_pgw_context(smresp.seid, pc)) {
pc.get()->handle_itti_msg(smresp);
lpc.unlock();
} else {
Logger::pgwc_app().debug("Received SXAB SESSION MODIFICATION RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", pgw_context not found, discarded!", smresp.seid, smresp.trxn_id);
}
......@@ -588,10 +584,12 @@ void pgw_app::handle_itti_msg (itti_sxab_session_modification_response& smresp)
void pgw_app::handle_itti_msg (itti_sxab_session_deletion_response& smresp)
{
std::shared_ptr<pgw_context> pc = {};
std::shared_lock<std::shared_mutex> lpc;
if (seid_2_pgw_context(smresp.seid, pc, lpc)) {
if (seid_2_pgw_context(smresp.seid, pc)) {
pc.get()->handle_itti_msg(smresp);
lpc.unlock();
if (pc->apns.size() == 0) {
delete_pgw_context(pc);
}
} else {
Logger::pgwc_app().debug("Received SXAB SESSION DELETION RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", pgw_context not found, discarded!", smresp.seid, smresp.trxn_id);
}
......@@ -601,10 +599,8 @@ void pgw_app::handle_itti_msg (itti_sxab_session_deletion_response& smresp)
void pgw_app::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request> snr)
{
std::shared_ptr<pgw_context> pc = {};
std::shared_lock<std::shared_mutex> lpc;
if (seid_2_pgw_context(snr->seid, pc, lpc)) {
if (seid_2_pgw_context(snr->seid, pc)) {
pc.get()->handle_itti_msg(snr);
lpc.unlock();
} else {
Logger::pgwc_app().debug("Received SXAB SESSION REPORT REQUEST seid" TEID_FMT " pfcp_tx_id %" PRIX64", pgw_context not found, discarded!", snr->seid, snr->trxn_id);
}
......
......@@ -105,7 +105,7 @@ public:
std::shared_ptr<pgw_context> s5s8cpgw_fteid_2_pgw_context(fteid_t& ls5s8_fteid);
void set_seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_context>& pc);
bool seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_context>& pc, std::shared_lock<std::shared_mutex>& lock_found) const;
bool seid_2_pgw_context(const seid_t& seid, std::shared_ptr<pgw_context>& pc) const;
void delete_pgw_context(std::shared_ptr<pgw_context> spc);
......
......@@ -226,29 +226,27 @@ std::string pgw_pdn_connection::toString() const
//------------------------------------------------------------------------------
void apn_context::insert_pdn_connection(std::shared_ptr<pgw_pdn_connection>& sp)
{
std::unique_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
pdn_connections.push_back(sp);
}
//------------------------------------------------------------------------------
bool apn_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, std::shared_ptr<pgw_pdn_connection>& pdn, std::shared_lock<std::shared_mutex>& lock_found)
bool apn_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, std::shared_ptr<pgw_pdn_connection>& pdn)
{
pdn = {};
if (is_local_teid) {
std::shared_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto it : pdn_connections) {
if (xgw_s5s8c_teid == it->pgw_fteid_s5_s8_cp.teid_gre_key) {
pdn = it;
lock_found.swap(lock);
return true;
}
}
return false;
} else {
std::shared_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto it : pdn_connections) {
if (xgw_s5s8c_teid == it->sgw_fteid_s5_s8_cp.teid_gre_key) {
pdn = it;
lock_found.swap(lock);
return true;
}
}
......@@ -257,15 +255,12 @@ bool apn_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is
}
//------------------------------------------------------------------------------
bool apn_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found)
bool apn_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi)
{
std::shared_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto pit : pdn_connections) {
std::shared_lock<std::shared_mutex> lock_pdn = {};
if (pit->has_eps_bearer(pdr_id, ebi)) {
pdn = pit; // May make pair
lock_found.swap(lock_pdn);
return true;
}
}
......@@ -278,7 +273,7 @@ void apn_context::delete_pdn_connection(std::shared_ptr<pgw_pdn_connection>& pdn
if (pdn_connection.get()) {
pdn_connection->deallocate_ressources(apn_in_use);
// remove it from collection
std::unique_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (std::vector<std::shared_ptr<pgw_pdn_connection>>::iterator it=pdn_connections.begin(); it!=pdn_connections.end(); ++it) {
if (pdn_connection.get() == (*it).get()) {
pdn_connection->deallocate_ressources(apn_in_use);
......@@ -291,7 +286,7 @@ void apn_context::delete_pdn_connection(std::shared_ptr<pgw_pdn_connection>& pdn
//------------------------------------------------------------------------------
void apn_context::deallocate_ressources()
{
std::unique_lock lock(m_pdn_connections);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (std::vector<std::shared_ptr<pgw_pdn_connection>>::iterator it=pdn_connections.begin(); it!=pdn_connections.end(); ++it) {
(*it)->deallocate_ressources(apn_in_use);
}
......@@ -315,15 +310,13 @@ std::string apn_context::toString() const
}
//------------------------------------------------------------------------------
bool pgw_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found)
bool pgw_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection)
{
std::shared_lock lock(m_apns);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto ait : apns) {
std::shared_ptr<pgw_pdn_connection> sp;
std::shared_lock<std::shared_mutex> lock_pdn = {};
if (ait->find_pdn_connection(xgw_s5s8c_teid, is_local_teid, sp, lock_pdn)) {
if (ait->find_pdn_connection(xgw_s5s8c_teid, is_local_teid, sp)) {
pdn_connection = make_pair(ait, sp);
lock_found.swap(lock_pdn);
return true;
}
}
......@@ -331,15 +324,13 @@ bool pgw_context::find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is
}
//------------------------------------------------------------------------------
bool pgw_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found)
bool pgw_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi)
{
std::shared_lock lock(m_apns);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto ait : apns) {
std::shared_ptr<pgw_pdn_connection> sp;
std::shared_lock<std::shared_mutex> lock_pdn = {};
if (ait->find_pdn_connection(pdr_id, sp, ebi, lock_pdn)) {
if (ait->find_pdn_connection(pdr_id, sp, ebi)) {
pdn = sp; // May make pair
lock_found.swap(lock_pdn);
return true;
}
}
......@@ -347,17 +338,15 @@ bool pgw_context::find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_
}
//------------------------------------------------------------------------------
bool pgw_context::find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found)
bool pgw_context::find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection)
{
pdn_connection = {};
std::shared_lock<std::shared_mutex> lock_sapn = {};
std::unique_lock<std::recursive_mutex> lock(m_context);
std::shared_ptr<apn_context> sa;
if (find_apn_context(apn, sa, lock_sapn)) {
if (find_apn_context(apn, sa)) {
std::shared_ptr<pgw_pdn_connection> sp;
if (sa.get()) {
std::shared_lock<std::shared_mutex> lock_spdn;
if (sa->find_pdn_connection(xgw_s5s8c_teid, is_local_teid, sp, lock_spdn)) {
lock_found.swap(lock_spdn);
if (sa->find_pdn_connection(xgw_s5s8c_teid, is_local_teid, sp)) {
// would need to make a pair of mutexes ?
pdn_connection = make_pair(sa, sp);
return true;
......@@ -370,7 +359,7 @@ bool pgw_context::find_pdn_connection(const std::string& apn, const teid_t xgw_s
void pgw_context::delete_apn_context(std::shared_ptr<apn_context>& sa)
{
if (sa.get()) {
std::unique_lock lock(m_apns);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (std::vector<std::shared_ptr<apn_context>>::iterator ait=apns.begin(); ait!=apns.end(); ++ait) {
//for (auto ait : apns) {
if ((*ait).get() == sa.get()) {
......@@ -394,17 +383,16 @@ void pgw_context::delete_pdn_connection(std::shared_ptr<apn_context>& sa , std::
//------------------------------------------------------------------------------
void pgw_context::insert_apn(std::shared_ptr<apn_context>& sa)
{
std::unique_lock lock(m_apns);
std::unique_lock<std::recursive_mutex> lock(m_context);
apns.push_back(sa);
}
//------------------------------------------------------------------------------
bool pgw_context::find_apn_context(const std::string& apn, std::shared_ptr<apn_context>& apn_context, std::shared_lock<std::shared_mutex>& lock_found)
bool pgw_context::find_apn_context(const std::string& apn, std::shared_ptr<apn_context>& apn_context)
{
std::shared_lock lock(m_apns);
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto it : apns) {
if (0 == apn.compare(it->apn_in_use)) {
apn_context = it;
lock_found.swap(lock);
return true;
}
}
......@@ -413,17 +401,17 @@ bool pgw_context::find_apn_context(const std::string& apn, std::shared_ptr<apn_c
//------------------------------------------------------------------------------
void pgw_context::insert_procedure(std::shared_ptr<pgw_procedure>& sproc)
{
std::unique_lock lock(m_pending_procedures);
std::unique_lock<std::recursive_mutex> lock(m_context);
pending_procedures.push_back(sproc);
}
//------------------------------------------------------------------------------
bool pgw_context::find_procedure(const uint64_t& trxn_id, std::shared_ptr<pgw_procedure>& proc, std::shared_lock<std::shared_mutex>& lock_found)
bool pgw_context::find_procedure(const uint64_t& trxn_id, std::shared_ptr<pgw_procedure>& proc)
{
std::shared_lock lock(m_pending_procedures);
auto found = std::find_if(pending_procedures.begin(), pending_procedures.end(), [trxn_id](std::shared_ptr<pgw_procedure> const& i) -> bool { return i->trxn_id == trxn_id;});
std::unique_lock<std::recursive_mutex> lock(m_context);
auto found = std::find_if(pending_procedures.begin(), pending_procedures.end(),
[trxn_id](std::shared_ptr<pgw_procedure> const& i) -> bool { return i->trxn_id == trxn_id;});
if (found != pending_procedures.end()) {
proc = *found;
lock_found.swap(lock);
return true;
}
return false;
......@@ -431,7 +419,7 @@ bool pgw_context::find_procedure(const uint64_t& trxn_id, std::shared_ptr<pgw_pr
//------------------------------------------------------------------------------
void pgw_context::remove_procedure(pgw_procedure* proc)
{
std::unique_lock lock(m_pending_procedures);
std::unique_lock<std::recursive_mutex> lock(m_context);
auto found = std::find_if(pending_procedures.begin(), pending_procedures.end(), [proc](std::shared_ptr<pgw_procedure> const& i) {
return i.get() == proc;
});
......@@ -446,8 +434,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_create_session_requ
itti_s5s8_create_session_request* csreq = s5_trigger.get();
// If PCEF integrated in PGW, TODO create a procedure
pdn_duo_t apn_pdn;
std::shared_lock<std::shared_mutex> lock_pdn = {};
bool found_pdn = find_pdn_connection(csreq->gtp_ies.apn.access_point_name, csreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn, lock_pdn);
bool found_pdn = find_pdn_connection(csreq->gtp_ies.apn.access_point_name, csreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn);
std::shared_ptr<apn_context> sa = apn_pdn.first;
std::shared_ptr<pgw_pdn_connection> sp = apn_pdn.second;
......@@ -495,7 +482,6 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_create_session_requ
} else {
// TODO bearer context to be removed
}
if (found_pdn) lock_pdn.unlock();
// for (auto it : csreq->gtp_ies.bearer_contexts_to_be_created) {
// pgw_eps_bearer& eps_bearer = sp->get_eps_bearer(it.eps_bearer_id);
// eps_bearer.ebi = it.eps_bearer_id;
......@@ -739,12 +725,11 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_delete_session_requ
std::shared_ptr<apn_context> sa = {};
std::shared_ptr<pgw_pdn_connection> sp = {};
std::shared_lock<std::shared_mutex> lock_pdn;
bool found = false;
if (sender_fteid_present) {
found = find_pdn_connection(sender_fteid.teid_gre_key, IS_FIND_PDN_WITH_PEER_TEID, apn_pdn, lock_pdn);
found = find_pdn_connection(sender_fteid.teid_gre_key, IS_FIND_PDN_WITH_PEER_TEID, apn_pdn);
} else {
found = find_pdn_connection(dsreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn, lock_pdn);
found = find_pdn_connection(dsreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn);
}
if (found) {
sa = apn_pdn.first;
......@@ -752,7 +737,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_delete_session_requ
if (sp.get()) {
delete_session_procedure* proc = new delete_session_procedure(sp);
delete_session_procedure* proc = new delete_session_procedure(shared_from_this(), sp);
std::shared_ptr<pgw_procedure> sproc = std::shared_ptr<pgw_procedure>(proc);
insert_procedure(sproc);
......@@ -770,7 +755,6 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_delete_session_requ
Logger::pgwc_app().info( "S5S8 DELETE_SESSION_REQUEST procedure failed");
remove_procedure(proc);
}
lock_pdn.unlock();
}
} else {
if (sender_fteid_present) {
......@@ -784,11 +768,9 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_delete_session_requ
void pgw_context::handle_itti_msg (itti_s5s8_downlink_data_notification_acknowledge& ack)
{
std::shared_ptr<pgw_procedure> proc = {};
std::shared_lock<std::shared_mutex> lp;
if (find_procedure(ack.gtpc_tx_id, proc, lp)) {
if (find_procedure(ack.gtpc_tx_id, proc)) {
Logger::pgwc_app().debug("Received S5S8 DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE sender teid " TEID_FMT " gtpc_tx_id " PROC_ID_FMT " ", ack.teid, ack.gtpc_tx_id);
proc->handle_itti_msg(ack);
lp.unlock();
remove_procedure(proc.get());
} else {
Logger::pgwc_app().debug("Received S5S8 DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE sender teid " TEID_FMT " gtpc_tx_id " PROC_ID_FMT ", pgw_procedure not found, discarded!", ack.teid, ack.gtpc_tx_id);
......@@ -808,12 +790,11 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_modify_bearer_reque
std::shared_ptr<apn_context> sa = {};
std::shared_ptr<pgw_pdn_connection> sp = {};
std::shared_lock<std::shared_mutex> lock_pdn;
bool found = false;
if (sender_fteid_present) {
found = find_pdn_connection(sender_fteid.teid_gre_key, IS_FIND_PDN_WITH_PEER_TEID, apn_pdn, lock_pdn);
found = find_pdn_connection(sender_fteid.teid_gre_key, IS_FIND_PDN_WITH_PEER_TEID, apn_pdn);
} else {
found = find_pdn_connection(mbreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn, lock_pdn);
found = find_pdn_connection(mbreq->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn);
}
if (found) {
sa = apn_pdn.first;
......@@ -839,7 +820,6 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_modify_bearer_reque
Logger::pgwc_app().info( "S5S8 MODIFY_BEARER_REQUEST procedure failed");
remove_procedure(proc);
}
lock_pdn.unlock();
}
} else {
if (sender_fteid_present) {
......@@ -855,8 +835,7 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_release_access_bear
std::shared_ptr<apn_context> sa = {};
std::shared_ptr<pgw_pdn_connection> sp = {};
std::shared_lock<std::shared_mutex> lock_pdn;
bool found = find_pdn_connection(s5_trigger->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn, lock_pdn);
bool found = find_pdn_connection(s5_trigger->teid, IS_FIND_PDN_WITH_LOCAL_TEID, apn_pdn);
if (found) {
sa = apn_pdn.first;
sp = apn_pdn.second;
......@@ -887,7 +866,6 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_release_access_bear
pgw_app_inst->send_release_access_bearers_response_cause_request_accepted (s5_trigger->gtpc_tx_id, sp->sgw_fteid_s5_s8_cp.teid_gre_key,
s5_trigger->r_endpoint);
}
lock_pdn.unlock();
}
} else {
Logger::pgwc_app().info( "S5S8 RELEASE_ACCESS_BEARERS_REQUEST procedure failed, context not found");
......@@ -900,11 +878,9 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_s5s8_release_access_bear
void pgw_context::handle_itti_msg (itti_sxab_session_establishment_response& seresp)
{
std::shared_ptr<pgw_procedure> proc = {};
std::shared_lock<std::shared_mutex> lp;
if (find_procedure(seresp.trxn_id, proc, lp)) {
if (find_procedure(seresp.trxn_id, proc)) {
Logger::pgwc_app().debug("Received SXAB SESSION ESTABLISHMENT RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64"\n", seresp.seid, seresp.trxn_id);
proc->handle_itti_msg(seresp);
lp.unlock();
remove_procedure(proc.get());
} else {
Logger::pgwc_app().debug("Received SXAB SESSION ESTABLISHMENT RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", pgw_procedure not found, discarded!", seresp.seid, seresp.trxn_id);
......@@ -914,11 +890,9 @@ void pgw_context::handle_itti_msg (itti_sxab_session_establishment_response& ser
void pgw_context::handle_itti_msg (itti_sxab_session_modification_response& smresp)
{
std::shared_ptr<pgw_procedure> proc = {};
std::shared_lock<std::shared_mutex> lp;
if (find_procedure(smresp.trxn_id, proc, lp)) {
if (find_procedure(smresp.trxn_id, proc)) {
Logger::pgwc_app().debug("Received SXAB SESSION MODIFICATION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64"\n", smresp.seid, smresp.trxn_id);
proc->handle_itti_msg(smresp);
lp.unlock();
remove_procedure(proc.get());
} else {
Logger::pgwc_app().debug("Received SXAB SESSION MODIFICATION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", pgw_procedure not found, discarded!", smresp.seid, smresp.trxn_id);
......@@ -929,14 +903,12 @@ void pgw_context::handle_itti_msg (itti_sxab_session_modification_response& smre
void pgw_context::handle_itti_msg (itti_sxab_session_deletion_response& sdresp)
{
std::shared_ptr<pgw_procedure> proc = {};
std::shared_lock<std::shared_mutex> lp;
if (find_procedure(sdresp.trxn_id, proc, lp)) {
if (find_procedure(sdresp.trxn_id, proc)) {
Logger::pgwc_app().debug("Received SXAB SESSION DELETION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64"\n", sdresp.seid, sdresp.trxn_id);
proc->handle_itti_msg(sdresp);
lp.unlock();
remove_procedure(proc.get());
} else {
Logger::pgwc_app().debug("Received SXAB SESSION MODIFICATION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", pgw_procedure not found, discarded!", sdresp.seid, sdresp.trxn_id);
Logger::pgwc_app().debug("Received SXAB SESSION DELETION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", pgw_procedure not found, discarded!", sdresp.seid, sdresp.trxn_id);
}
std::cout << toString() << std::endl;
}
......@@ -952,16 +924,15 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_requ
if (req->pfcp_ies.get(data_report)) {
pfcp::pdr_id_t pdr_id;
if (data_report.get(pdr_id)) {
std::shared_lock<std::shared_mutex> lp;
std::shared_ptr<pgw_pdn_connection> ppc = {};
ebi_t ebi;
if (find_pdn_connection(pdr_id, ppc, ebi, lp)) {
if (find_pdn_connection(pdr_id, ppc, ebi)) {
downlink_data_report_procedure* p = new downlink_data_report_procedure(req);
std::shared_ptr<pgw_procedure> sproc = std::shared_ptr<pgw_procedure>(p);
insert_procedure(sproc);
if (p->run(shared_from_this(), ppc, ebi)) {
// TODO handle error code
Logger::pgwc_app().info( "S11 CREATE_SESSION_REQUEST procedure failed");
Logger::pgwc_app().info( "S5S8 DOWNLINK_DATA_REPORT procedure failed");
remove_procedure(p);
} else {
}
......@@ -987,11 +958,11 @@ void pgw_context::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_requ
//------------------------------------------------------------------------------
std::string pgw_context::toString() const
{
std::unique_lock<std::recursive_mutex> lock(m_context);
std::string s = {};
s.append("PGW CONTEXT:\n");
s.append("\tIMSI:\t\t\t\t").append(imsi.toString()).append("\n");
s.append("\tIMSI UNAUTHENTICATED:\t\t").append(std::to_string(imsi_unauthenticated_indicator)).append("\n");
std::shared_lock lock(m_apns);
for (auto it : apns) {
s.append(it->toString());
}
......
......@@ -31,7 +31,6 @@
#include <map>
#include <mutex>
#include <memory>
#include <shared_mutex>
#include <utility>
#include <vector>
......@@ -241,15 +240,15 @@ public:
class apn_context {
public:
apn_context() : m_pdn_connections(), in_use(false), pdn_connections() {
apn_context() : m_context(), in_use(false), pdn_connections() {
apn_ambr = {0};
}
apn_context(apn_context& b) = delete;
void insert_pdn_connection(std::shared_ptr<pgw_pdn_connection>& sp);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, std::shared_ptr<pgw_pdn_connection>& pdn, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, std::shared_ptr<pgw_pdn_connection>& pdn);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi);
void delete_pdn_connection(std::shared_ptr<pgw_pdn_connection>& pdn_connection);
int get_num_pdn_connections() const {return pdn_connections.size();};
// deallocate_ressources is for releasing LTE resources prior to the deletion of objects
......@@ -268,8 +267,7 @@ public:
// key is local s5s8 teid
//map<teid_t, shared_ptr<pgw_pdn_connection>> pdn_connections;
std::vector<std::shared_ptr<pgw_pdn_connection>> pdn_connections; // was list
mutable std::shared_mutex m_pdn_connections;
mutable std::recursive_mutex m_context;
};
class pgw_context;
......@@ -279,24 +277,23 @@ typedef std::pair<std::shared_ptr<apn_context>, std::shared_ptr<pgw_pdn_connecti
class pgw_context : public std::enable_shared_from_this<pgw_context> {
public:
pgw_context() : m_pending_procedures(), m_apns(),
imsi(), imsi_unauthenticated_indicator(false), apns(), pending_procedures(), msisdn() {}
pgw_context() : m_context(), imsi(), imsi_unauthenticated_indicator(false), apns(), pending_procedures(), msisdn() {}
pgw_context(pgw_context& b) = delete;
//void create_procedure(itti_s5s8_create_session_request& csreq);
void insert_procedure(std::shared_ptr<pgw_procedure>& sproc);
bool find_procedure(const uint64_t& trxn_id, std::shared_ptr<pgw_procedure>& proc, std::shared_lock<std::shared_mutex>& lock_found);
bool find_procedure(const uint64_t& trxn_id, std::shared_ptr<pgw_procedure>& proc);
void remove_procedure(pgw_procedure* proc);
#define IS_FIND_PDN_WITH_LOCAL_TEID true
#define IS_FIND_PDN_WITH_PEER_TEID false
bool find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi, std::shared_lock<std::shared_mutex>& lock_found);
bool find_pdn_connection(const std::string& apn, const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection);
bool find_pdn_connection(const teid_t xgw_s5s8c_teid, const bool is_local_teid, pdn_duo_t& pdn_connection);
bool find_pdn_connection(const pfcp::pdr_id_t& pdr_id, std::shared_ptr<pgw_pdn_connection>& pdn, ebi_t& ebi);
void insert_apn(std::shared_ptr<apn_context>& sa);
bool find_apn_context(const std::string& apn, std::shared_ptr<apn_context>& apn_context, std::shared_lock<std::shared_mutex>& lock_found);
bool find_apn_context(const std::string& apn, std::shared_ptr<apn_context>& apn_context);
int get_num_apn_contexts() {return apns.size();};
void delete_apn_context(std::shared_ptr<apn_context>& sa);
......@@ -327,12 +324,13 @@ public:
// NOT IMPLEMENTED OMC identity // Identifies the OMC that shall receive the trace record(s).
std::vector<std::shared_ptr<apn_context>> apns; // was list
mutable std::shared_mutex m_apns;
//--------------------------------------------
// internals
std::vector<std::shared_ptr<pgw_procedure>> pending_procedures;
mutable std::shared_mutex m_pending_procedures;
// Big recursive lock
mutable std::recursive_mutex m_context;
};
}
......
......@@ -100,6 +100,9 @@ void pgw_s5s8_task (void *args_p)
}
break;
case HEALTH_PING:
break;
default:
Logger::pgwc_s5s8().info( "no handler for msg type %d", msg->msg_type);
}
......@@ -163,6 +166,8 @@ void pgw_s5s8::handle_receive_create_session_request(gtpv2c_msg& msg, const endp
if (RETURNok != ret) {
Logger::pgwc_s5s8().error( "Could not send ITTI message %s to task TASK_PGWC_APP", i->get_msg_name());
}
} else {
Logger::pgwc_s5s8().error( "Error signalled by lower layer while receiving CREATE_SESSION_REQUEST");
}
// else ignore
}
......
......@@ -932,6 +932,14 @@ void delete_session_procedure::handle_itti_msg (itti_sxab_session_deletion_respo
if (RETURNok != ret) {
Logger::pgwc_app().error( "Could not send ITTI message %s to task TASK_PGWC_S5S8", s5_triggered_pending->gtp_ies.get_msg_name());
}
// find APN context
pdn_duo_t pdn_duo = {};
if (pc->find_pdn_connection(ppc->pgw_fteid_s5_s8_cp.teid_gre_key, IS_FIND_PDN_WITH_LOCAL_TEID, pdn_duo)) {
pc->delete_pdn_connection(pdn_duo.first, pdn_duo.second);