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_): 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>();
37 bool protector::operator()(unsigned char *msg_ref, size_t msg_size, unsigned char * buffer, size_t *buf_size )
42 std::lock_guard<std::mutex> lck(*(m_access.get()));
44 X2AP_PDU_t * x2ap_recv = 0;
47 asn_dec_rval_t dec_res = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_X2AP_PDU, (void **)&x2ap_recv, msg_ref, msg_size);
49 /* Is this an SgNB Addition request ? */
50 if (dec_res.code == RC_OK){
51 if (x2ap_recv->present == X2AP_PDU_PR_initiatingMessage){
52 if (x2ap_recv->choice.initiatingMessage->procedureCode == ProcedureCode_id_sgNBAdditionPreparation ){
53 if (x2ap_recv->choice.initiatingMessage->value.present == X2InitiatingMessage__value_PR_SgNBAdditionRequest){
54 mdclog_write(MDCLOG_INFO, "Processing X2AP SgNB Addition Request message\n");
58 mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: X2AP Message (%d) not an SgNB Addition Request\n", __FILE__, __LINE__, x2ap_recv->choice.initiatingMessage->value.present);
63 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);
68 mdclog_write(MDCLOG_ERR, "Error :: %s, %d:: Not an X2AP initiating message. X2AP Message type %d\n", __FILE__, __LINE__, x2ap_recv->present);
73 mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: Could not decode X2AP PDU of size %lu bytes \n", __FILE__, __LINE__, msg_size);
79 //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl;
80 //xer_fprint(stdout, &asn_DEF_X2AP_PDU, x2ap_recv);
81 //std::cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl;
83 res = sgnb_req.get_fields(x2ap_recv->choice.initiatingMessage, sgnb_data);
85 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());
92 // update sliding window
93 m_window_ref.get()->update_window(1);
94 if (m_window_ref.get()->net_events > m_threshold && m_enforce){
95 res = selectiveBlock();
106 Generate response message
107 Do we need to do this ?
108 What if indication is report type ?
109 plugin is agnostic to subscription for now, so yes, we always generate
110 an appropriate response
113 // generate sgnb addition response message (ack or reject)
114 // if rejecting , we use cause = Misc and sub-cause = om_intervention
115 sgnb_data.cause = Cause_PR_misc;
116 sgnb_data.cause_desc = CauseMisc_om_intervention;
117 res = sgnb_resp.encode_sgnb_addition_response(buffer, buf_size, sgnb_data, res);
119 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());
124 ASN_STRUCT_FREE(asn_DEF_X2AP_PDU, x2ap_recv);
129 bool protector::configure(bool enforce, int windowSize_, int threshold_, double blockRate_)
131 std::lock_guard<std::mutex> lck(*(m_access.get()));
135 m_windowSize=windowSize_;
136 bool res = m_window_ref.get()->resize_window(m_windowSize);
142 m_threshold=threshold_;
143 m_blockRate=blockRate_;
145 mdclog_write(MDCLOG_INFO, "Policy : Enforce mode set to %d\n", m_enforce);
146 mdclog_write(MDCLOG_INFO, "Policy: Trigger threshold set to %d\n", m_threshold);
147 mdclog_write(MDCLOG_INFO, "Policy : Blocking rate set to %f\n", m_blockRate);
148 mdclog_write(MDCLOG_INFO, "Policy : Window Size set to %d\n", m_windowSize);
152 unsigned long int protector::get_requests(void) const {
156 unsigned long int protector::get_rejects(void) const {
160 void protector::clear()
162 std::lock_guard<std::mutex> lck(*(m_access.get()));
165 m_window_ref.get()->clear();
169 bool protector::selectiveBlock()
171 unsigned int num = (rand() % 100) + 1;
172 if (num > m_blockRate) //not blocking