| 363 | } |
| 364 | |
| 365 | void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection, std::shared_ptr<endpoint_type> _remote_ep, |
| 366 | boost::system::error_code const& _error) { |
| 367 | |
| 368 | if (!_error) { |
| 369 | // Remote endpoint was captured by the kernel at accept() time via the peer-endpoint |
| 370 | // overload of async_accept, so it is valid even if the client already disconnected. |
| 371 | boost::system::error_code its_error; |
| 372 | const endpoint_type remote(*_remote_ep); |
| 373 | { |
| 374 | std::unique_lock its_socket_lock(_connection->get_socket_lock()); |
| 375 | tcp_socket& connection_socket_ = _connection->get_socket(); |
| 376 | _connection->set_remote_info(remote); |
| 377 | // Nagle algorithm off |
| 378 | connection_socket_.set_option(ip::tcp::no_delay(true), its_error); |
| 379 | if (its_error) { |
| 380 | VSOMEIP_ERROR_P << instance_name_ << "Set option TCP_NODELAY failed, " << its_error.message(); |
| 381 | } |
| 382 | |
| 383 | connection_socket_.set_option(boost::asio::socket_base::keep_alive(true), its_error); |
| 384 | if (its_error) { |
| 385 | VSOMEIP_ERROR_P << instance_name_ << "Set option SO_KEEPALIVE failed, " << its_error.message(); |
| 386 | } |
| 387 | |
| 388 | // force always TCP RST on close/shutdown, in order to: |
| 389 | // 1) avoid issues with TIME_WAIT, which otherwise lasts for 120 secs with a |
| 390 | // non-responding endpoint (see also 4396812d2) |
| 391 | // 2) handle by default what needs to happen at suspend/shutdown |
| 392 | connection_socket_.set_option(boost::asio::socket_base::linger(true, 0), its_error); |
| 393 | if (its_error) { |
| 394 | VSOMEIP_ERROR_P << instance_name_ << "Set option SO_LINGER failed, " << its_error.message(); |
| 395 | } |
| 396 | |
| 397 | #if defined(__linux__) |
| 398 | // set a user timeout |
| 399 | // along the keep alives, this ensures connection closes if endpoint is unreachable |
| 400 | if (!connection_socket_.set_user_timeout(configuration_->get_external_tcp_user_timeout())) { |
| 401 | VSOMEIP_ERROR_P << instance_name_ << "Set option TCP_USER_TIMEOUT failed, errno=" << errno; |
| 402 | } |
| 403 | |
| 404 | // override kernel settings |
| 405 | // unfortunate, but there are plenty of custom keep-alive settings, and need to |
| 406 | // enforce some sanity here |
| 407 | if (!connection_socket_.set_keepidle(configuration_->get_external_tcp_keepidle())) { |
| 408 | VSOMEIP_ERROR_P << instance_name_ << "Set option TCP_KEEPIDLE failed, errno=" << errno; |
| 409 | } |
| 410 | if (!connection_socket_.set_keepintvl(configuration_->get_external_tcp_keepintvl())) { |
| 411 | VSOMEIP_ERROR_P << instance_name_ << "Set option TCP_KEEPINTVL failed, errno=" << errno; |
| 412 | } |
| 413 | if (!connection_socket_.set_keepcnt(configuration_->get_external_tcp_keepcnt())) { |
| 414 | VSOMEIP_ERROR_P << instance_name_ << "Set option TCP_KEEPCNT failed, errno=" << errno; |
| 415 | } |
| 416 | #endif |
| 417 | } |
| 418 | if (!its_error) { |
| 419 | { |
| 420 | std::scoped_lock its_lock(connections_mutex_); |
| 421 | connections_[remote] = _connection; |
| 422 | } |
no test coverage detected