2 ==================================================================================
4 Copyright (c) 2018-2019 AT&T Intellectual Property.
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 ==================================================================================
21 #include "NetworkProtector.h"
24 #include <mutex> // std::mutex
25 #include <ctime> // For time()
26 #include <cstdlib> // For srand() and rand()
29 protector::protector(bool enforce, int windowSize_, int threshold_, double blockRate_, bool report): m_enforce(enforce), m_windowSize(windowSize_), m_threshold(threshold_), m_blockRate(blockRate_), m_req(0), m_rej(0)
32 m_window_ref = std::make_unique<sliding_window>(m_windowSize);
33 m_access = std::make_unique<std::mutex>();
34 report_mode_only = report;
38 bool protector::operator()(unsigned char *msg_ref, size_t msg_size, unsigned char * buffer, size_t *buf_size )
43 std::lock_guard<std::mutex> lck(*(m_access.get()));
45 X2N_X2AP_PDU_t * x2ap_recv = 0;
46 asn_dec_rval_t dec_res;
49 dec_res = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_X2N_X2AP_PDU, (void **)&x2ap_recv, msg_ref, msg_size);
51 if (dec_res.code == RC_OK){
52 /* Is this an SgNB Addition request ? */
53 mdclog_write(MDCLOG_DEBUG, "Decoded X2AP PDU successfully. Processing X2 message fields to ascertain type etc ...\n");
54 if (x2ap_recv->present == X2N_X2AP_PDU_PR_initiatingMessage){
55 if (x2ap_recv->choice.initiatingMessage->procedureCode == X2N_ProcedureCode_id_sgNBAdditionPreparation ){
56 if (x2ap_recv->choice.initiatingMessage->value.present == X2N_InitiatingMessage__value_PR_SgNBAdditionRequest){
57 mdclog_write(MDCLOG_DEBUG, "Processing X2AP SgNB Addition Request message\n");
61 mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: X2AP Message (%d) not an SgNB Addition Request\n", __FILE__, __LINE__, x2ap_recv->choice.initiatingMessage->value.present);
66 mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: X2AP procedure code %ld does not match required %ld\n", __FILE__, __LINE__, x2ap_recv->choice.initiatingMessage->procedureCode, X2N_ProcedureCode_id_sgNBAdditionPreparation);
71 mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: Not an X2AP initiating message. X2AP Message type %d\n", __FILE__, __LINE__, x2ap_recv->present);
76 mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: Could not decode X2AP PDU of size %lu bytes\n", __FILE__, __LINE__, msg_size);
82 mdclog_write(MDCLOG_DEBUG, "Extracting SgNB Addition Request fields...");
84 //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl;
85 //xer_fprint(stdout, &asn_DEF_X2AP_PDU, x2ap_recv);
86 //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl;
88 res = sgnb_req.get_fields(x2ap_recv->choice.initiatingMessage, sgnb_data);
90 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());
94 mdclog_write(MDCLOG_DEBUG, "Decoded and extracted X2AP PDU data. Number of erabs = %u\n", sgnb_data.get_list()->size());
95 mdclog_write(MDCLOG_DEBUG, "Applying admission control logic ...");
100 // update sliding window
101 m_window_ref.get()->update_window(1);
102 if ( m_enforce && m_window_ref.get()->net_events > m_threshold){
103 res = selectiveBlock();
113 mdclog_write(MDCLOG_DEBUG, "Plugin decision for sgnb request = %d\n", res);
116 Generate response message if flag is set
119 if(! report_mode_only){
120 // generate sgnb addition response message (ack or reject)
121 // if rejecting , we use cause = Misc and sub-cause = om_intervention
122 mdclog_write(MDCLOG_DEBUG, "Generating X2AP response ..\n");
123 sgnb_data.cause = X2N_Cause_PR_misc;
124 sgnb_data.cause_desc = X2N_CauseMisc_om_intervention;
126 res = sgnb_resp.encode_sgnb_addition_response(buffer, buf_size, sgnb_data, res);
128 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());
131 catch(std::exception &e){
132 mdclog_write(MDCLOG_ERR, "Error:: %s, %d : Caught exception %s\n", __FILE__, __LINE__, e.what());
142 ASN_STRUCT_FREE(asn_DEF_X2N_X2AP_PDU, x2ap_recv);
147 bool protector::configure(bool enforce, int windowSize_, int threshold_, double blockRate_)
149 std::lock_guard<std::mutex> lck(*(m_access.get()));
153 m_windowSize=windowSize_;
154 bool res = m_window_ref.get()->resize_window(m_windowSize);
160 m_threshold=threshold_;
161 m_blockRate=blockRate_;
163 mdclog_write(MDCLOG_INFO, "Policy : Enforce mode set to %d\n", m_enforce);
164 mdclog_write(MDCLOG_INFO, "Policy: Trigger threshold set to %d\n", m_threshold);
165 mdclog_write(MDCLOG_INFO, "Policy : Blocking rate set to %f\n", m_blockRate);
166 mdclog_write(MDCLOG_INFO, "Policy : Window Size set to %d\n", m_windowSize);
170 unsigned long int protector::get_requests(void) const {
174 unsigned long int protector::get_rejects(void) const {
178 void protector::clear()
180 std::lock_guard<std::mutex> lck(*(m_access.get()));
183 m_window_ref.get()->clear();
187 bool protector::selectiveBlock()
189 unsigned int num = (rand() % 100) + 1;
190 if (num > m_blockRate) //not blocking