diff options
author | Shobhit Adlakha <ShobhitAd@users.noreply.github.com> | 2020-09-04 12:43:03 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-04 12:43:03 -0400 |
commit | b94d63a0f3e73dc03e7e49d74bf39e2423eb844f (patch) | |
tree | 0aad8837c646a0b1e7eea3d4d6aa2f58a351ed2e /src/components/connection_handler/src | |
parent | b683e7c3f25ef9dbbff4df4a8749bee2ebbf2450 (diff) | |
download | sdl_core-b94d63a0f3e73dc03e7e49d74bf39e2423eb844f.tar.gz |
Feature/Add reason param to All protocol NAKs (#3462)
* Add reason param to StartService and EndService NAK payloads
* Update the default protocol version
* Fix unit tests
* Implement minor version check for reason param
* Fix unit tests
* Apply suggestions from code review
Co-authored-by: Collin <iCollin@users.noreply.github.com>
* Make semantic versions const and fix handshake NAK reason messages
* Make reason a required param
* Add error check for protocolversionused call
* Use full version for reason param version check
* Get protocol NAK reason from OnSessionEndedCallback
* Fix failing unit tests
* Remove unnecessary condition from protected/unprotected reason check
* Add unit tests for NACK reason param
* Add unit test for EndServiceNAK with reason param
* Fix calltimes in StartSession_NACKReason_SessionObserverReject
* Get reason string for service start failed
* Add more details to the invalid cert nak reason
Co-authored-by: Collin <iCollin@users.noreply.github.com>
Diffstat (limited to 'src/components/connection_handler/src')
-rw-r--r-- | src/components/connection_handler/src/connection.cc | 61 | ||||
-rw-r--r-- | src/components/connection_handler/src/connection_handler_impl.cc | 87 |
2 files changed, 140 insertions, 8 deletions
diff --git a/src/components/connection_handler/src/connection.cc b/src/components/connection_handler/src/connection.cc index c366496056..14e2b83848 100644 --- a/src/components/connection_handler/src/connection.cc +++ b/src/components/connection_handler/src/connection.cc @@ -165,11 +165,15 @@ uint32_t Connection::RemoveSession(uint8_t session_id) { bool Connection::AddNewService(uint8_t session_id, protocol_handler::ServiceType service_type, const bool request_protection, - transport_manager::ConnectionUID connection_id) { + transport_manager::ConnectionUID connection_id, + std::string* err_reason) { // Ignore wrong services if (protocol_handler::kControl == service_type || protocol_handler::kInvalidServiceType == service_type) { SDL_LOG_WARN("Wrong service " << static_cast<int>(service_type)); + if (err_reason) { + *err_reason = "Wrong service type " + std::to_string(service_type); + } return false; } @@ -182,6 +186,11 @@ bool Connection::AddNewService(uint8_t session_id, SessionMap::iterator session_it = session_map_.find(session_id); if (session_it == session_map_.end()) { SDL_LOG_WARN("Session not found in this connection!"); + if (err_reason) { + *err_reason = "Session " + std::to_string(session_id) + + " not found for connection " + + std::to_string(connection_id); + } return false; } Session& session = session_it->second; @@ -206,12 +215,22 @@ bool Connection::AddNewService(uint8_t session_id, SDL_LOG_WARN("Session " << static_cast<int>(session_id) << " already has unprotected service " << static_cast<int>(service_type)); + if (err_reason) { + *err_reason = "Session " + std::to_string(session_id) + + " already has an unprotected service of type " + + std::to_string(service_type); + } return false; } if (service->is_protected_) { SDL_LOG_WARN("Session " << static_cast<int>(session_id) << " already has protected service " << static_cast<int>(service_type)); + if (err_reason) { + *err_reason = "Session " + std::to_string(session_id) + + " already has a protected service of type " + + std::to_string(service_type); + } return false; } // For unproteced service could be start protection @@ -442,6 +461,33 @@ void Connection::UpdateProtocolVersionSession(uint8_t session_id, } Session& session = session_it->second; session.protocol_version = protocol_version; + if (session.full_protocol_version.major_version_ != + session.protocol_version) { + session.full_protocol_version = + utils::SemanticVersion(protocol_version, 0, 0); + } +} + +void Connection::UpdateProtocolVersionSession( + uint8_t session_id, const utils::SemanticVersion& full_protocol_version) { + SDL_LOG_AUTO_TRACE(); + + if (!full_protocol_version.isValid()) { + SDL_LOG_WARN("Invalid version: " << full_protocol_version.toString()); + return; + } + + sync_primitives::AutoLock lock(session_map_lock_); + SessionMap::iterator session_it = session_map_.find(session_id); + if (session_map_.end() == session_it) { + SDL_LOG_WARN("Session not found in this connection!"); + return; + } + + Session& session = session_it->second; + session.protocol_version = + static_cast<uint8_t>(full_protocol_version.major_version_); + session.full_protocol_version = full_protocol_version; } bool Connection::SupportHeartBeat(uint8_t session_id) { @@ -471,6 +517,19 @@ bool Connection::ProtocolVersion(uint8_t session_id, return true; } +bool Connection::ProtocolVersion( + uint8_t session_id, utils::SemanticVersion& full_protocol_version) { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoLock lock(session_map_lock_); + SessionMap::iterator session_it = session_map_.find(session_id); + if (session_map_.end() == session_it) { + SDL_LOG_WARN("Session not found in this connection!"); + return false; + } + full_protocol_version = (session_it->second).full_protocol_version; + return true; +} + ConnectionHandle Connection::primary_connection_handle() const { return primary_connection_handle_; } diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index a57f7c73e0..b9d1de8332 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -457,7 +457,11 @@ void ConnectionHandlerImpl::OnSessionStartedCallback( #ifdef ENABLE_SECURITY if (!AllowProtection(get_settings(), service_type, is_protected)) { - protocol_handler_->NotifySessionStarted(context, rejected_params); + protocol_handler_->NotifySessionStarted( + context, + rejected_params, + "Service of type " + std::to_string(service_type) + " cannot be " + + (is_protected ? "protected" : "unprotected")); return; } #endif // ENABLE_SECURITY @@ -466,7 +470,10 @@ void ConnectionHandlerImpl::OnSessionStartedCallback( connection_list_.find(primary_connection_handle); if (connection_list_.end() == it) { SDL_LOG_ERROR("Unknown connection!"); - protocol_handler_->NotifySessionStarted(context, rejected_params); + protocol_handler_->NotifySessionStarted( + context, + rejected_params, + "Unknown connection " + std::to_string(primary_connection_handle)); return; } @@ -479,21 +486,33 @@ void ConnectionHandlerImpl::OnSessionStartedCallback( connection->AddNewSession(primary_connection_handle); if (0 == context.new_session_id_) { SDL_LOG_ERROR("Couldn't start new session!"); - protocol_handler_->NotifySessionStarted(context, rejected_params); + protocol_handler_->NotifySessionStarted( + context, rejected_params, "Unable to create new session"); return; } context.hash_id_ = KeyFromPair(primary_connection_handle, context.new_session_id_); } else { // Could be create new service or protected exists one - if (!connection->AddNewService( - session_id, service_type, is_protected, connection_handle)) { + std::string err_reason; + if (!connection->AddNewService(session_id, + service_type, + is_protected, + connection_handle, + &err_reason)) { SDL_LOG_ERROR("Couldn't establish " #ifdef ENABLE_SECURITY << (is_protected ? "protected" : "non-protected") #endif // ENABLE_SECURITY << " service " << static_cast<int>(service_type) << " for session " << static_cast<int>(session_id)); - protocol_handler_->NotifySessionStarted(context, rejected_params); + + protocol_handler_->NotifySessionStarted( + context, + rejected_params, + "Cannot start " + + std::string(is_protected ? "a protected" : " an unprotected") + + " service of type " + std::to_string(service_type) + ". " + + err_reason); return; } context.new_session_id_ = session_id; @@ -650,7 +669,8 @@ uint32_t ConnectionHandlerImpl::OnSessionEndedCallback( const transport_manager::ConnectionUID connection_handle, const uint8_t session_id, uint32_t* hashCode, - const protocol_handler::ServiceType& service_type) { + const protocol_handler::ServiceType& service_type, + std::string* err_reason) { SDL_LOG_AUTO_TRACE(); // In case this is a Session running on a Secondary Transport, we need to @@ -666,6 +686,9 @@ uint32_t ConnectionHandlerImpl::OnSessionEndedCallback( SDL_LOG_WARN( "OnSessionEndedCallback could not find Session in the " "Session/Connection Map!"); + if (err_reason) { + *err_reason = "Could not find Session in the Session/Connection Map!"; + } } else { SDL_LOG_INFO("OnSessionEndedCallback found session " << static_cast<int>(session_id) @@ -683,6 +706,9 @@ uint32_t ConnectionHandlerImpl::OnSessionEndedCallback( if (connection_list_.end() == it) { SDL_LOG_WARN("Unknown connection!"); connection_list_lock_.Release(); + if (err_reason) { + *err_reason = "Could not find Connection in the Connection Map!"; + } return 0; } std::pair<int32_t, Connection*> connection_item = *it; @@ -704,12 +730,21 @@ uint32_t ConnectionHandlerImpl::OnSessionEndedCallback( "Wrong hash_id for session " << static_cast<uint32_t>(session_id)); *hashCode = protocol_handler::HASH_ID_WRONG; + + if (err_reason) { + *err_reason = "Wrong hash_id for session " + + std::to_string(static_cast<uint32_t>(session_id)); + } return 0; } } if (!connection->RemoveSession(session_id)) { SDL_LOG_WARN("Couldn't remove session " << static_cast<uint32_t>(session_id)); + if (err_reason) { + *err_reason = "Couldn't remove session " + + std::to_string(static_cast<uint32_t>(session_id)); + } return 0; } } else { @@ -720,6 +755,10 @@ uint32_t ConnectionHandlerImpl::OnSessionEndedCallback( SDL_LOG_WARN( "Couldn't remove service " << static_cast<uint32_t>(service_type)); + if (err_reason) { + *err_reason = "Couldn't remove service " + + std::to_string(static_cast<uint32_t>(service_type)); + } return 0; } } @@ -1715,6 +1754,21 @@ void ConnectionHandlerImpl::BindProtocolVersionWithSession( } } +void ConnectionHandlerImpl::BindProtocolVersionWithSession( + uint32_t connection_key, + const utils::SemanticVersion& full_protocol_version) { + SDL_LOG_AUTO_TRACE(); + uint32_t connection_handle = 0; + uint8_t session_id = 0; + PairFromKey(connection_key, &connection_handle, &session_id); + + sync_primitives::AutoReadLock lock(connection_list_lock_); + auto connection = GetPrimaryConnection(connection_handle); + if (connection) { + connection->UpdateProtocolVersionSession(session_id, full_protocol_version); + } +} + bool ConnectionHandlerImpl::IsHeartBeatSupported( transport_manager::ConnectionUID connection_handle, uint8_t session_id) const { @@ -1748,6 +1802,25 @@ bool ConnectionHandlerImpl::ProtocolVersionUsed( return false; } +bool ConnectionHandlerImpl::ProtocolVersionUsed( + uint32_t connection_id, + uint8_t session_id, + utils::SemanticVersion& full_protocol_version) const { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoReadLock lock(connection_list_lock_); + auto connection = GetPrimaryConnection(connection_id); + + if (connection) { + return connection->ProtocolVersion(session_id, full_protocol_version); + } else if (ending_connection_ && + static_cast<uint32_t>(ending_connection_->connection_handle()) == + connection_id) { + return ending_connection_->ProtocolVersion(session_id, + full_protocol_version); + } + return false; +} + #ifdef BUILD_TESTS ConnectionList& ConnectionHandlerImpl::getConnectionList() { return connection_list_; |