diff options
8 files changed, 149 insertions, 59 deletions
diff --git a/customer-specific/pasa/src/appMain/smartDeviceLink.ini b/customer-specific/pasa/src/appMain/smartDeviceLink.ini index fb8d43ce7a..2700afd42d 100644 --- a/customer-specific/pasa/src/appMain/smartDeviceLink.ini +++ b/customer-specific/pasa/src/appMain/smartDeviceLink.ini @@ -142,9 +142,19 @@ ConnectionWaitTimeout = 10 ; 1488 = 1500 - 12 = TCP MTU - header size MaximumPayloadSize = 1488 ; Application shall send less #FrequencyCount messages per #FrequencyTime mSecs -; Frequency check could be disable by setting FrequencyTime to Zero +; Frequency check could be disable by setting #FrequencyTime or +; #FrequencyCount to Zero FrequencyCount = 1000 FrequencyTime = 1000 +; Enable filtering transport dta stream +; On #MalformedMessageFiltering disable SDl disconnect with the first +; malformed message detection +MalformedMessageFiltering = true +; Boundary values of malformed message detection for connection close +; Can be disable by setting #MalformedFrequencyTime or +; #MalformedFrequencyCountto Zero +MalformedFrequencyCount = 10 +MalformedFrequencyTime = 1000 [ApplicationManager] ApplicationListUpdateTimeout = 2 diff --git a/src/appMain/life_cycle.cc b/src/appMain/life_cycle.cc index 3f48abe3e9..0358f6ef8c 100644 --- a/src/appMain/life_cycle.cc +++ b/src/appMain/life_cycle.cc @@ -97,6 +97,7 @@ bool LifeCycle::StartComponents() { new protocol_handler::ProtocolHandlerImpl(transport_manager_, profile::Profile::instance()->message_frequency_time(), profile::Profile::instance()->message_frequency_count(), + profile::Profile::instance()->malformed_message_filtering(), profile::Profile::instance()->malformed_frequency_time(), profile::Profile::instance()->malformed_frequency_count()); DCHECK(protocol_handler_ != NULL); diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini index 51c70c3d74..d7507dcc6e 100644 --- a/src/appMain/smartDeviceLink.ini +++ b/src/appMain/smartDeviceLink.ini @@ -162,12 +162,17 @@ IAP2HubConnectAttempts = 3 ; 1488 = 1500 - 12 = TCP MTU - header size MaximumPayloadSize = 1488 ; Application shall send less #FrequencyCount messages per #FrequencyTime mSecs -; Frequency check could be disable by setting #FrequencyTime to Zero +; Frequency check could be disable by setting #FrequencyTime or +; #FrequencyCount to Zero FrequencyCount = 1000 FrequencyTime = 1000 -; Application can send less #MalformedFrequencyCount malformed messages per -; #MalformedFrequencyTime mSecs -; Frequency check could be disable by setting #MalformedFrequencyTime to Zero +; Enable filtering transport dta stream +; On #MalformedMessageFiltering disable SDl disconnect with the first +; malformed message detection +MalformedMessageFiltering = true +; Boundary values of malformed message detection for connection close +; Can be disable by setting #MalformedFrequencyTime or +; #MalformedFrequencyCountto Zero MalformedFrequencyCount = 10 MalformedFrequencyTime = 1000 diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h index 8ae8318274..8e5c3ffe8a 100644 --- a/src/components/config_profile/include/config_profile/profile.h +++ b/src/components/config_profile/include/config_profile/profile.h @@ -475,6 +475,8 @@ class Profile : public utils::Singleton<Profile> { size_t message_frequency_time() const; + bool malformed_message_filtering() const; + size_t malformed_frequency_count() const; size_t malformed_frequency_time() const; diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc index de5636126e..a29c4f5cf8 100644 --- a/src/components/config_profile/src/profile.cc +++ b/src/components/config_profile/src/profile.cc @@ -154,6 +154,7 @@ const char* kTTSGlobalPropertiesTimeoutKey = "TTSGlobalPropertiesTimeout"; const char* kMaximumPayloadSizeKey = "MaximumPayloadSize"; const char* kFrequencyCount = "FrequencyCount"; const char* kFrequencyTime = "FrequencyTime"; +const char* kMalformedMessageFiltering = "MalformedMessageFiltering"; const char* kMalformedFrequencyCount = "MalformedFrequencyCount"; const char* kMalformedFrequencyTime = "MalformedFrequencyTime"; const char* kHashStringSizeKey = "HashStringSize"; @@ -215,6 +216,7 @@ const uint16_t kDefaultTTSGlobalPropertiesTimeout = 20; const size_t kDefaultMaximumPayloadSize = 1500 - 12; const size_t kDefaultFrequencyCount = 1000; const size_t kDefaultFrequencyTime = 1000; +const bool kDefaulMalformedMessageFiltering = true; const size_t kDefaultMalformedFrequencyCount = 10; const size_t kDefaultMalformedFrequencyTime = 1000; const uint16_t kDefaultAttemptsToOpenPolicyDB = 5; @@ -610,6 +612,13 @@ size_t Profile::message_frequency_time() const { return message_frequency_time; } +bool Profile::malformed_message_filtering() const { + bool malformed_message_filtering = 0; + ReadBoolValue(&malformed_message_filtering, kDefaulMalformedMessageFiltering, + kProtocolHandlerSection, kMalformedMessageFiltering); + return malformed_message_filtering; +} + size_t Profile::malformed_frequency_count() const { size_t malformed_frequency_count = 0; ReadUIntValue(&malformed_frequency_count, kDefaultMalformedFrequencyCount, diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h index 427dec9d34..2d43c65093 100644 --- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h +++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h @@ -134,6 +134,7 @@ class ProtocolHandlerImpl * \param message_frequency_time used as time for flood filtering * \param message_frequency_count used as maximum value of messages * per message_frequency_time period + * \param malformed_message_filtering used for malformed filtering enabling * \param malformed_message_frequency_time used as time for malformed flood filtering * \param malformed_message_frequency_count used as maximum value of malformed * messages per message_frequency_time period @@ -142,6 +143,7 @@ class ProtocolHandlerImpl explicit ProtocolHandlerImpl( transport_manager::TransportManager *transport_manager_param, size_t message_frequency_time, size_t message_frequency_count, + bool malformed_message_filtering, size_t malformed_message_frequency_time, size_t malformed_message_frequency_count); @@ -530,9 +532,12 @@ class ProtocolHandlerImpl // Use uint32_t as application identifier utils::MessageMeter<uint32_t> message_meter_; size_t message_max_frequency_; + size_t message_frequency_time_; + bool malformed_message_filtering_; // Use uint32_t as connection identifier utils::MessageMeter<uint32_t> malformed_message_meter_; size_t malformed_message_max_frequency_; + size_t malformed_message_frequency_time_; #ifdef ENABLE_SECURITY security_manager::SecurityManager *security_manager_; diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index ca44f330c8..1c00184089 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -65,12 +65,17 @@ const size_t kStackSize = 32768; ProtocolHandlerImpl::ProtocolHandlerImpl( transport_manager::TransportManager *transport_manager_param, size_t message_frequency_time, size_t message_frequency_count, + bool malformed_message_filtering, size_t malformed_message_frequency_time, size_t malformed_message_frequency_count) : protocol_observers_(), session_observer_(0), transport_manager_(transport_manager_param), kPeriodForNaviAck(5), - message_max_frequency_(0), + message_max_frequency_(message_frequency_count), + message_frequency_time_(message_frequency_time), + malformed_message_filtering_(malformed_message_filtering), + malformed_message_max_frequency_(malformed_message_frequency_count), + malformed_message_frequency_time_(malformed_message_frequency_time), #ifdef ENABLE_SECURITY security_manager_(NULL), #endif // ENABLE_SECURITY @@ -86,34 +91,28 @@ ProtocolHandlerImpl::ProtocolHandlerImpl( LOG4CXX_AUTO_TRACE(logger_); protocol_header_validator_.set_max_payload_size(profile::Profile::instance()->maximum_payload_size()); incoming_data_handler_.set_validator(&protocol_header_validator_); - const size_t time_range_msecs = message_frequency_time; - message_meter_.set_time_range(time_range_msecs); - if (time_range_msecs > 0) { - message_max_frequency_ = message_frequency_count; - if (message_max_frequency_ > 0) { - LOG4CXX_DEBUG(logger_, "Frequency meter is enabled ( " << message_max_frequency_ - << " per " << time_range_msecs << " mSecond)"); - } else { - LOG4CXX_WARN(logger_, "Invalid massage frequency value. MessageMeter will be disabled"); - message_meter_.set_time_range(0u); - } + + if (message_frequency_time_ > 0u && + message_max_frequency_ > 0u) { + message_meter_.set_time_range(message_frequency_time_); + LOG4CXX_DEBUG(logger_, "Frequency meter is enabled ( " << message_max_frequency_ + << " per " << message_frequency_time_ << " mSecond)"); } else { LOG4CXX_WARN(logger_, "Frequency meter is disabled"); } - const size_t malformed_time_range_msecs = malformed_message_frequency_time; - malformed_message_meter_.set_time_range(malformed_time_range_msecs); - if (malformed_time_range_msecs > 0) { - malformed_message_max_frequency_ = malformed_message_frequency_count; - if (malformed_message_max_frequency_ > 0) { - LOG4CXX_DEBUG(logger_, "Malformed frequency meter is enabled ( " << message_max_frequency_ - << " per " << malformed_time_range_msecs << " mSecond)"); + + if (malformed_message_filtering_) { + if(malformed_message_frequency_time_ > 0u && + malformed_message_max_frequency_ > 0u) { + malformed_message_meter_.set_time_range(malformed_message_frequency_time_); + LOG4CXX_DEBUG(logger_, "Malformed frequency meter is enabled ( " << malformed_message_max_frequency_ + << " per " << malformed_message_frequency_time_ << " mSecond)"); } else { - LOG4CXX_WARN(logger_, "Invalid malformed massage frequency value." - <<" MalformedMessageMeter will be disabled"); - malformed_message_meter_.set_time_range(0u); + LOG4CXX_WARN(logger_, "Malformed frequency meter is disabled"); } } else { - LOG4CXX_WARN(logger_, "Malformed frequency meter is disabled"); + LOG4CXX_WARN(logger_, "Malformed message filtering is disabled." + << "Connection will be close on first malformed message detection"); } } @@ -423,11 +422,7 @@ void ProtocolHandlerImpl::SendMessageToMobileApp(const RawMessagePtr message, void ProtocolHandlerImpl::OnTMMessageReceived(const RawMessagePtr tm_message) { LOG4CXX_AUTO_TRACE(logger_); - if (tm_message) { - LOG4CXX_DEBUG(logger_, - "Received data from TM with connection id " << tm_message->connection_key() << - " msg data_size " << tm_message->data_size()); - } else { + if (!tm_message) { LOG4CXX_ERROR( logger_, "Invalid incoming message received in" @@ -435,19 +430,31 @@ void ProtocolHandlerImpl::OnTMMessageReceived(const RawMessagePtr tm_message) { return; } + const uint32_t connection_key = tm_message->connection_key(); + LOG4CXX_DEBUG(logger_, + "Received data from TM with connection id " << connection_key << + " msg data_size " << tm_message->data_size()); + RESULT_CODE result; const std::list<ProtocolFramePtr> protocol_frames = incoming_data_handler_.ProcessData(*tm_message, &result); + LOG4CXX_DEBUG(logger_, "Proccessed " << protocol_frames.size() << "frames"); if (result != RESULT_OK) { if (result == RESULT_MALFORMED_OCCURS) { - LOG4CXX_WARN(logger_, "Malformed message occurs."); + LOG4CXX_WARN(logger_, "Malformed message occurs, connection id " + << connection_key); + if (!malformed_message_filtering_) { + LOG4CXX_DEBUG(logger_, "Malformed message filterign disabled"); + if (session_observer_) { + session_observer_->OnMalformedMessageCallback(connection_key); + } // For tracking only malformed occurrence check outpute - if(!protocol_frames.empty()) { - TrackMalformedMessage(tm_message->connection_key()); + } else if(!protocol_frames.empty()) { + TrackMalformedMessage(connection_key); } } else { LOG4CXX_ERROR(logger_, "Incoming data processing failed."); - transport_manager_->DisconnectForce(tm_message->connection_key()); + transport_manager_->DisconnectForce(connection_key); } } @@ -1089,31 +1096,38 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageHeartBeat( bool ProtocolHandlerImpl::TrackMessage(const uint32_t& connection_key) { LOG4CXX_AUTO_TRACE(logger_); - const size_t message_frequency = message_meter_.TrackMessage(connection_key); - LOG4CXX_DEBUG(logger_, "Frequency of " << connection_key << " is " << message_frequency); - if (message_frequency > message_max_frequency_) { - LOG4CXX_WARN(logger_, "Frequency of " << connection_key << " is marked as high."); - if (session_observer_) { - session_observer_->OnApplicationFloodCallBack(connection_key); + if (message_frequency_time_ > 0u && + message_max_frequency_ > 0u) { + const size_t message_frequency = message_meter_.TrackMessage(connection_key); + LOG4CXX_DEBUG(logger_, "Frequency of " << connection_key << " is " << message_frequency); + if (message_frequency > message_max_frequency_) { + LOG4CXX_WARN(logger_, "Frequency of " << connection_key << " is marked as high."); + if (session_observer_) { + session_observer_->OnApplicationFloodCallBack(connection_key); + } + message_meter_.RemoveIdentifier(connection_key); + return true; } - message_meter_.RemoveIdentifier(connection_key); - return true; } return false; } bool ProtocolHandlerImpl::TrackMalformedMessage(const uint32_t &connection_key) { LOG4CXX_AUTO_TRACE(logger_); - const size_t message_frequency = malformed_message_meter_.TrackMessage(connection_key); - LOG4CXX_DEBUG(logger_, "Malformed frequency of " << connection_key - << " is " << message_frequency); - if (message_frequency > malformed_message_max_frequency_) { - LOG4CXX_WARN(logger_, "Malformed frequency of " << connection_key << " is marked as high."); - if (session_observer_) { - session_observer_->OnMalformedMessageCallback(connection_key); + if (malformed_message_frequency_time_ > 0u && + malformed_message_max_frequency_ > 0u) { + const size_t message_frequency = malformed_message_meter_.TrackMessage(connection_key); + LOG4CXX_DEBUG(logger_, "Malformed frequency of " << connection_key + << " is " << message_frequency); + if (!malformed_message_filtering_ || + message_frequency > malformed_message_max_frequency_) { + LOG4CXX_WARN(logger_, "Malformed frequency of " << connection_key << " is marked as high."); + if (session_observer_) { + session_observer_->OnMalformedMessageCallback(connection_key); + } + malformed_message_meter_.RemoveIdentifier(connection_key); + return true; } - malformed_message_meter_.RemoveIdentifier(connection_key); - return true; } return false; } diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc index 144003c63b..43dfcca55b 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -62,11 +62,13 @@ class ProtocolHandlerImplTest : public ::testing::Test { protected: void InitProtocolHandlerImpl( const size_t period_msec, const size_t max_messages, + bool malformed_message_filtering = false, const size_t malformd_period_msec = 0u, const size_t malformd_max_messages = 0u) { protocol_handler_impl.reset( new ProtocolHandlerImpl(&transport_manager_mock, period_msec, max_messages, + malformed_message_filtering, malformd_period_msec, malformd_max_messages)); protocol_handler_impl->set_session_observer(&session_observer_mock); tm_listener = protocol_handler_impl.get(); @@ -757,10 +759,31 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, + MalformedVerificationDisable) { + const size_t period_msec = 10000; + const size_t max_messages = 100; + InitProtocolHandlerImpl(0u, 0u, false, period_msec, max_messages); + AddConnection(); + AddSession(); + + // expect malformed notification to CH + EXPECT_CALL(session_observer_mock, + OnMalformedMessageCallback(connection_id)). + Times(max_messages); + + const uint8_t malformed_version = PROTOCOL_VERSION_MAX; + for (size_t i = 0; i < max_messages; ++i) { + SendTMMessage(connection_id, malformed_version, PROTECTION_OFF, FRAME_TYPE_SINGLE, + kControl, FRAME_DATA_SINGLE, session_id, + some_data.size(), message_id, &some_data[0]); + } +} + +TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification) { const size_t period_msec = 10000; const size_t max_messages = 100; - InitProtocolHandlerImpl(0u, 0u, period_msec, max_messages); + InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); AddSession(); @@ -787,7 +810,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_MalformedStock) { const size_t period_msec = 10000; const size_t max_messages = 100; - InitProtocolHandlerImpl(0u, 0u, period_msec, max_messages); + InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); AddSession(); @@ -825,7 +848,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_MalformedOnly) { const size_t period_msec = 10000; const size_t max_messages = 100; - InitProtocolHandlerImpl(0u, 0u, period_msec, max_messages); + InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); AddSession(); @@ -857,10 +880,31 @@ TEST_F(ProtocolHandlerImplTest, } TEST_F(ProtocolHandlerImplTest, - MalformedLimitVerificationDisabled) { + MalformedLimitVerification_NullTimePeriod) { const size_t period_msec = 0; + const size_t max_messages = 1000; + InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); + AddConnection(); + AddSession(); + + // expect no malformed notification to CH + EXPECT_CALL(session_observer_mock, + OnMalformedMessageCallback(connection_id)). + Times(0); + + // Sending malformed packets + const uint8_t malformed_version = PROTOCOL_VERSION_MAX; + for (size_t i = 0; i < max_messages + 1; ++i) { + SendTMMessage(connection_id, malformed_version, PROTECTION_OFF, FRAME_TYPE_SINGLE, + kControl, FRAME_DATA_SINGLE, session_id, + some_data.size(), message_id, &some_data[0]); + } +} +TEST_F(ProtocolHandlerImplTest, + MalformedLimitVerification_NullCount) { + const size_t period_msec = 10000; const size_t max_messages = 0; - InitProtocolHandlerImpl(0u, 0u, period_msec, max_messages); + InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); AddSession(); |