summaryrefslogtreecommitdiff
path: root/src/components/connection_handler/src
diff options
context:
space:
mode:
authorShobhit Adlakha <ShobhitAd@users.noreply.github.com>2020-09-04 12:43:03 -0400
committerGitHub <noreply@github.com>2020-09-04 12:43:03 -0400
commitb94d63a0f3e73dc03e7e49d74bf39e2423eb844f (patch)
tree0aad8837c646a0b1e7eea3d4d6aa2f58a351ed2e /src/components/connection_handler/src
parentb683e7c3f25ef9dbbff4df4a8749bee2ebbf2450 (diff)
downloadsdl_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.cc61
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc87
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_;