X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fprotector-plugin%2FNetworkProtector.cc;fp=src%2Fprotector-plugin%2FNetworkProtector.cc;h=6412fd4488eb569e6888b805b063a0ae85f00a2a;hb=b9d7e9c232a4371ddfed51c58e5a57f87b057229;hp=0000000000000000000000000000000000000000;hpb=59f84608ec15c016958a6e0e0ddd813f376c0925;p=ric-app%2Fadmin.git diff --git a/src/protector-plugin/NetworkProtector.cc b/src/protector-plugin/NetworkProtector.cc new file mode 100644 index 0000000..6412fd4 --- /dev/null +++ b/src/protector-plugin/NetworkProtector.cc @@ -0,0 +1,177 @@ +/* +================================================================================== + + Copyright (c) 2018-2019 AT&T Intellectual Property. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================== +*/ + + +#include "NetworkProtector.h" + + +#include // std::mutex +#include // For time() +#include // For srand() and rand() + + +protector::protector(bool enforce, int windowSize_, int threshold_, double blockRate_): m_enforce(enforce), m_windowSize(windowSize_), m_threshold(threshold_), m_blockRate(blockRate_), m_req(0), m_rej(0) +{ + m_counter = 0; + m_window_ref = std::make_unique(m_windowSize); + m_access = std::make_unique(); +} + + +bool protector::operator()(unsigned char *msg_ref, size_t msg_size, unsigned char * buffer, size_t *buf_size ) +{ + + bool res = true; + + std::lock_guard lck(*(m_access.get())); + + X2AP_PDU_t * x2ap_recv = 0; + + // /* Decode */ + asn_dec_rval_t dec_res = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_X2AP_PDU, (void **)&x2ap_recv, msg_ref, msg_size); + + /* Is this an SgNB Addition request ? */ + if (dec_res.code == RC_OK){ + if (x2ap_recv->present == X2AP_PDU_PR_initiatingMessage){ + if (x2ap_recv->choice.initiatingMessage->procedureCode == ProcedureCode_id_sgNBAdditionPreparation ){ + if (x2ap_recv->choice.initiatingMessage->value.present == X2InitiatingMessage__value_PR_SgNBAdditionRequest){ + mdclog_write(MDCLOG_INFO, "Processing X2AP SgNB Addition Request message\n"); + res = true; + } + else{ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: X2AP Message (%d) not an SgNB Addition Request\n", __FILE__, __LINE__, x2ap_recv->choice.initiatingMessage->value.present); + res = false; + } + } + else{ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: X2AP procedure code %d does not match required %d\n", __FILE__, __LINE__, x2ap_recv->choice.initiatingMessage->procedureCode, ProcedureCode_id_sgNBAdditionPreparation); + res = false; + } + } + else{ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: Not an X2AP initiating message. X2AP Message type %d\n", __FILE__, __LINE__, x2ap_recv->present); + res = false; + } + } + else{ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: Could not decode X2AP PDU of size %lu bytes \n", __FILE__, __LINE__, msg_size); + res = false; + } + + if (res){ + + //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl; + //xer_fprint(stdout, &asn_DEF_X2AP_PDU, x2ap_recv); + //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl; + + res = sgnb_req.get_fields(x2ap_recv->choice.initiatingMessage, sgnb_data); + if (!res){ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: could not get fields from SgNB Addition Request. Reason = %s\n", __FILE__, __LINE__, sgnb_req.get_error().c_str()); + } + + if (res){ + // Admission control + + m_req ++; + // update sliding window + m_window_ref.get()->update_window(1); + if (m_window_ref.get()->net_events > m_threshold && m_enforce){ + res = selectiveBlock(); + } + else{ + res = true; + } + + if (!res){ + m_rej ++; + } + + /* + Generate response message + Do we need to do this ? + What if indication is report type ? + plugin is agnostic to subscription for now, so yes, we always generate + an appropriate response + */ + + // generate sgnb addition response message (ack or reject) + // if rejecting , we use cause = Misc and sub-cause = om_intervention + sgnb_data.cause = Cause_PR_misc; + sgnb_data.cause_desc = CauseMisc_om_intervention; + res = sgnb_resp.encode_sgnb_addition_response(buffer, buf_size, sgnb_data, res); + if (! res){ + mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: could not encode SgNB Addition Response PDU. Reason = %s\n", __FILE__, __LINE__, sgnb_resp.get_error().c_str()); + } + } + } + + ASN_STRUCT_FREE(asn_DEF_X2AP_PDU, x2ap_recv); + return res; + +} + +bool protector::configure(bool enforce, int windowSize_, int threshold_, double blockRate_) +{ + std::lock_guard lck(*(m_access.get())); + + + + m_windowSize=windowSize_; + bool res = m_window_ref.get()->resize_window(m_windowSize); + if (!res){ + return false; + } + + m_enforce = enforce; + m_threshold=threshold_; + m_blockRate=blockRate_; + + mdclog_write(MDCLOG_INFO, "Policy : Enforce mode set to %d\n", m_enforce); + mdclog_write(MDCLOG_INFO, "Policy: Trigger threshold set to %d\n", m_threshold); + mdclog_write(MDCLOG_INFO, "Policy : Blocking rate set to %f\n", m_blockRate); + mdclog_write(MDCLOG_INFO, "Policy : Window Size set to %d\n", m_windowSize); + return true; +} + +unsigned long int protector::get_requests(void) const { + return m_req; +} + +unsigned long int protector::get_rejects(void) const { + return m_rej; +} + +void protector::clear() +{ + std::lock_guard lck(*(m_access.get())); + m_req = 0; + m_rej = 0; + m_window_ref.get()->clear(); +} + + +bool protector::selectiveBlock() +{ + unsigned int num = (rand() % 100) + 1; + if (num > m_blockRate) //not blocking + return true; + else //blocking + return false; +} +