summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Gehring <juergen.gehring@bmw.de>2018-05-22 02:56:44 -0700
committerJuergen Gehring <juergen.gehring@bmw.de>2018-05-22 02:56:44 -0700
commit8826ddae04a88ca20bb8e571e6596ad9718a6077 (patch)
tree2358810e9409263f8dd38423086dd3c9fb494b98
parentafba9f6b5657334dab422715c0f01869b4242627 (diff)
downloadvSomeIP-8826ddae04a88ca20bb8e571e6596ad9718a6077.tar.gz
vsomeip 2.10.172.10.17
-rw-r--r--CHANGES6
-rw-r--r--CMakeLists.txt2
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp23
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp72
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp84
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp10
6 files changed, 139 insertions, 58 deletions
diff --git a/CHANGES b/CHANGES
index a55daff..b73ed27 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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);