diff options
author | Juergen Gehring <juergen.gehring@bmw.de> | 2018-05-22 02:56:44 -0700 |
---|---|---|
committer | Juergen Gehring <juergen.gehring@bmw.de> | 2018-05-22 02:56:44 -0700 |
commit | 8826ddae04a88ca20bb8e571e6596ad9718a6077 (patch) | |
tree | 2358810e9409263f8dd38423086dd3c9fb494b98 | |
parent | afba9f6b5657334dab422715c0f01869b4242627 (diff) | |
download | vSomeIP-8826ddae04a88ca20bb8e571e6596ad9718a6077.tar.gz |
vsomeip 2.10.172.10.17
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | implementation/endpoints/src/tcp_client_endpoint_impl.cpp | 23 | ||||
-rw-r--r-- | implementation/endpoints/src/udp_client_endpoint_impl.cpp | 72 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_impl.cpp | 84 | ||||
-rw-r--r-- | implementation/service_discovery/src/service_discovery_impl.cpp | 10 |
6 files changed, 139 insertions, 58 deletions
@@ -1,5 +1,11 @@ Changes ======= + +v2.10.17 +- Speedup initial subscriptions to unreliable remote services +- Fix deadlock in conjunction with configured client ports +- Fix bug leading to usage of client port outside of configured range + v2.10.16 - Only map shared memory for client IDs once per process diff --git a/CMakeLists.txt b/CMakeLists.txt index 794bed3..734930c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project (vsomeip) set (VSOMEIP_MAJOR_VERSION 2) set (VSOMEIP_MINOR_VERSION 10) -set (VSOMEIP_PATCH_VERSION 16) +set (VSOMEIP_PATCH_VERSION 17) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in set (CMAKE_VERBOSE_MAKEFILE off) diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index ab7d9c3..80bc95f 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -113,13 +113,15 @@ void tcp_client_endpoint_impl::connect() { socket_->set_option(ip::tcp::no_delay(true), its_error);
if (its_error) {
VSOMEIP_WARNING << "tcp_client_endpoint::connect: couldn't disable "
- << "Nagle algorithm: " << its_error.message();
+ << "Nagle algorithm: " << its_error.message()
+ << " remote:" << get_address_port_remote();
}
socket_->set_option(boost::asio::socket_base::keep_alive(true), its_error);
if (its_error) {
VSOMEIP_WARNING << "tcp_client_endpoint::connect: couldn't enable "
- << "keep_alive: " << its_error.message();
+ << "keep_alive: " << its_error.message()
+ << " remote:" << get_address_port_remote();
}
// Enable SO_REUSEADDR to avoid bind problems with services going offline
@@ -128,7 +130,8 @@ void tcp_client_endpoint_impl::connect() { socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error);
if (its_error) {
VSOMEIP_WARNING << "tcp_client_endpoint::connect: couldn't enable "
- << "SO_REUSEADDR: " << its_error.message();
+ << "SO_REUSEADDR: " << its_error.message()
+ << " remote:" << get_address_port_remote();
}
// In case a client endpoint port was configured,
// bind to it before connecting
@@ -137,7 +140,17 @@ void tcp_client_endpoint_impl::connect() { socket_->bind(local_, its_bind_error);
if(its_bind_error) {
VSOMEIP_WARNING << "tcp_client_endpoint::connect: "
- "Error binding socket: " << its_bind_error.message();
+ "Error binding socket: " << its_bind_error.message()
+ << " remote:" << get_address_port_remote();
+ try {
+ // don't connect on bind error to avoid using a random port
+ service_.post(std::bind(&client_endpoint_impl::connect_cbk,
+ shared_from_this(), its_bind_error));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << "tcp_client_endpoint_impl::connect: "
+ << e.what() << " remote:" << get_address_port_remote();
+ }
+ return;
}
}
state_ = cei_state_e::CONNECTING;
@@ -151,7 +164,7 @@ void tcp_client_endpoint_impl::connect() { );
} else {
VSOMEIP_WARNING << "tcp_client_endpoint::connect: Error opening socket: "
- << its_error.message();
+ << its_error.message() << " remote:" << get_address_port_remote();
}
}
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index 6252b40..3c05357 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -41,41 +41,57 @@ bool udp_client_endpoint_impl::is_local() const { void udp_client_endpoint_impl::connect() {
std::lock_guard<std::mutex> its_lock(socket_mutex_);
- // In case a client endpoint port was configured,
- // bind to it before connecting
- if (local_.port() != ILLEGAL_PORT) {
- boost::system::error_code its_bind_error;
- socket_->bind(local_, its_bind_error);
- if(its_bind_error) {
- VSOMEIP_WARNING << "udp_client_endpoint::connect: "
- "Error binding socket: " << its_bind_error.message();
- }
- }
- state_ = cei_state_e::CONNECTING;
- socket_->async_connect(
- remote_,
- std::bind(
- &udp_client_endpoint_base_impl::connect_cbk,
- shared_from_this(),
- std::placeholders::_1
- )
- );
-}
-
-void udp_client_endpoint_impl::start() {
boost::system::error_code its_error;
- {
- std::lock_guard<std::mutex> its_lock(socket_mutex_);
- socket_->open(remote_.protocol(), its_error);
- }
+ socket_->open(remote_.protocol(), its_error);
if (!its_error || its_error == boost::asio::error::already_open) {
- connect();
+ // Enable SO_REUSEADDR to avoid bind problems with services going offline
+ // and coming online again and the user has specified only a small number
+ // of ports in the clients section for one service instance
+ socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error);
+ if (its_error) {
+ VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't enable "
+ << "SO_REUSEADDR: " << its_error.message() << " remote:"
+ << get_address_port_remote();
+ }
+ // In case a client endpoint port was configured,
+ // bind to it before connecting
+ if (local_.port() != ILLEGAL_PORT) {
+ boost::system::error_code its_bind_error;
+ socket_->bind(local_, its_bind_error);
+ if(its_bind_error) {
+ VSOMEIP_WARNING << "udp_client_endpoint::connect: "
+ "Error binding socket: " << its_bind_error.message()
+ << " remote:" << get_address_port_remote();
+ try {
+ // don't connect on bind error to avoid using a random port
+ service_.post(std::bind(&client_endpoint_impl::connect_cbk,
+ shared_from_this(), its_bind_error));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << "udp_client_endpoint_impl::connect: "
+ << e.what() << " remote:" << get_address_port_remote();
+ }
+ return;
+ }
+ }
+ state_ = cei_state_e::CONNECTING;
+ socket_->async_connect(
+ remote_,
+ std::bind(
+ &udp_client_endpoint_base_impl::connect_cbk,
+ shared_from_this(),
+ std::placeholders::_1
+ )
+ );
} else {
VSOMEIP_WARNING << "udp_client_endpoint::connect: Error opening socket: "
- << its_error.message();
+ << its_error.message() << " remote:" << get_address_port_remote();
}
}
+void udp_client_endpoint_impl::start() {
+ connect();
+}
+
void udp_client_endpoint_impl::restart() {
if (state_ == cei_state_e::CONNECTING) {
return;
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index add0fb9..08cfe95 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -1474,7 +1474,6 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se its_unreliable_endpoint = its_info->get_endpoint(false); } - // Trigger "del_routing_info" either over SD or static if (discovery_) { if (its_info) { if (its_info->get_major() == _major && its_info->get_minor() == _minor) { @@ -1482,11 +1481,9 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se discovery_->stop_offer_service(_service, _instance, its_info); } } - } else { - del_routing_info(_service, _instance, - (its_reliable_endpoint != nullptr), - (its_unreliable_endpoint != nullptr)); } + del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr), + (its_unreliable_endpoint != nullptr)); // Cleanup reliable & unreliable server endpoints hold before if (its_info) { @@ -1973,7 +1970,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_remote_client( if( its_remote_port != ILLEGAL_PORT) { // if client port range for remote service port range is configured // and remote port is in range, determine unused client port - std::lock_guard<std::mutex> its_lock(used_client_ports_mutex_); + std::unique_lock<std::mutex> its_lock(used_client_ports_mutex_); if (configuration_->get_client_port(_service, _instance, its_remote_port, _reliable, used_client_ports_, its_local_port)) { if(its_endpoint_def) { @@ -1987,6 +1984,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_remote_client( if (its_endpoint) { used_client_ports_[_reliable].insert(its_local_port); + its_lock.unlock(); service_instances_[_service][its_endpoint.get()] = _instance; remote_services_[_service][_instance][_client][_reliable] = its_endpoint; if (_client == VSOMEIP_ROUTING_CLIENT) { @@ -2051,6 +2049,11 @@ std::shared_ptr<endpoint> routing_manager_impl::find_remote_client( remote_services_[_service][_instance][_client][_reliable] = its_endpoint; service_instances_[_service][its_endpoint.get()] = _instance; + // add endpoint to serviceinfo object + auto found_service_info = find_service(_service,_instance); + if (found_service_info) { + found_service_info->set_endpoint(its_endpoint, _reliable); + } } } } @@ -2240,6 +2243,10 @@ void routing_manager_impl::add_routing_info( if(!connected) { find_or_create_remote_client(_service, _instance, true, VSOMEIP_ROUTING_CLIENT); + if (udp_inserted) { + find_or_create_remote_client(_service, _instance, + false, VSOMEIP_ROUTING_CLIENT); + } connected = true; } its_info->add_client(client_id.first); @@ -2268,20 +2275,23 @@ void routing_manager_impl::add_routing_info( && (major_minor_pair.second <= _minor || _minor == DEFAULT_MINOR || major_minor_pair.second == ANY_MINOR)) { - on_availability(_service, _instance, - true, its_info->get_major(), its_info->get_minor()); if (!stub_->contained_in_routing_info( VSOMEIP_ROUTING_CLIENT, _service, _instance, its_info->get_major(), its_info->get_minor())) { + on_availability(_service, _instance, + true, its_info->get_major(), its_info->get_minor()); stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, its_info->get_major(), its_info->get_minor()); if (discovery_) { - discovery_->on_endpoint_connected( - _service, _instance, - its_info->get_endpoint(true)); + std::shared_ptr<endpoint> ep = its_info->get_endpoint(true); + if (ep && ep->is_connected()) { + discovery_->on_endpoint_connected( + _service, _instance, + ep); + } } } break; @@ -2302,6 +2312,7 @@ void routing_manager_impl::add_routing_info( } // check if service was requested and increase requester count if necessary { + bool connected(false); std::lock_guard<std::mutex> its_lock(requested_services_mutex_); for (const auto &client_id : requested_services_) { const auto found_service = client_id.second.find(_service); @@ -2317,6 +2328,11 @@ void routing_manager_impl::add_routing_info( || _minor == DEFAULT_MINOR || major_minor_pair.second == ANY_MINOR)) { + if(!connected) { + find_or_create_remote_client(_service, _instance, + false, VSOMEIP_ROUTING_CLIENT); + connected = true; + } its_info->add_client(client_id.first); break; } @@ -2331,9 +2347,49 @@ void routing_manager_impl::add_routing_info( stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); } if (discovery_) { - discovery_->on_endpoint_connected( - _service, _instance, - its_info->get_endpoint(false)); + std::shared_ptr<endpoint> ep = its_info->get_endpoint(false); + if (ep && ep->is_connected()) { + discovery_->on_endpoint_connected(_service, _instance, ep); + } + } + } else if (_unreliable_port != ILLEGAL_PORT && is_unreliable_known) { + std::lock_guard<std::mutex> its_lock(requested_services_mutex_); + for(const auto &client_id : requested_services_) { + auto found_service = client_id.second.find(_service); + if (found_service != client_id.second.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (const auto &major_minor_pair : found_instance->second) { + if ((major_minor_pair.first == _major + || _major == DEFAULT_MAJOR + || major_minor_pair.first == ANY_MAJOR) + && (major_minor_pair.second <= _minor + || _minor == DEFAULT_MINOR + || major_minor_pair.second == ANY_MINOR)) { + if (!stub_->contained_in_routing_info( + VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), + its_info->get_minor())) { + on_availability(_service, _instance, + true, its_info->get_major(), its_info->get_minor()); + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, + _service, _instance, + its_info->get_major(), + its_info->get_minor()); + if (discovery_) { + std::shared_ptr<endpoint> ep = its_info->get_endpoint(false); + if (ep && ep->is_connected()) { + discovery_->on_endpoint_connected( + _service, _instance, + ep); + } + } + } + break; + } + } + } + } } } } diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 04ae7d7..da8c9a8 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -1837,21 +1837,11 @@ bool service_discovery_impl::insert_offer_service( if (its_reliable) { insert_option(_message, its_entry, unicast_, its_reliable->get_local_port(), true); - if ((0 == _info->get_ttl() && !is_diagnosis_) - && (0 == _info->get_ttl() && !is_suspended_)) { - host_->del_routing_info(_service, - _instance, true, false); - } } if (its_unreliable) { insert_option(_message, its_entry, unicast_, its_unreliable->get_local_port(), false); - if ((0 == _info->get_ttl() && !is_diagnosis_) - && (0 == _info->get_ttl() && !is_suspended_)) { - host_->del_routing_info(_service, - _instance, false, true); - } } // This would be a clean solution but does _not_ work with the ANDi tool //unsubscribe_all(_service, _instance); |