diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c8e23ea82..90e61ebb3 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: [ubuntu-18.04] + runs-on: [ubuntu-22.04] steps: - uses: actions/checkout@v2 diff --git a/AUTHORS b/AUTHORS index 632e4798e..cc7c12659 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Bayerische Motoren Werke Aktiengesellschaft (BMW AG) \ No newline at end of file +Bayerische Motoren Werke Aktiengesellschaft (BMW AG) diff --git a/Android.bp b/Android.bp index 038c78751..a6a9ba30d 100644 --- a/Android.bp +++ b/Android.bp @@ -1,14 +1,19 @@ libvsomeip_srcs = [ "implementation/endpoints/**/*.cpp", - "implementation/logging/**/*.cpp", + "implementation/logger/**/*.cpp", "implementation/tracing/**/*.cpp", "implementation/message/**/*.cpp", "implementation/routing/**/*.cpp", "implementation/runtime/**/*.cpp", "implementation/utility/**/*.cpp", "implementation/plugin/**/*.cpp", + "implementation/protocol/**/*.cpp", "implementation/security/**/*.cpp", - "implementation/logger/**/*.cpp", +] + +libvsomeip_compat_srcs = [ + "implementation/compat/message/src/*.cpp", + "implementation/compat/runtime/src/*.cpp", ] libvsomeip_cfg_srcs = [ @@ -26,19 +31,8 @@ libvsomeip_sd_srcs = [ cc_defaults { name: "vsomeip_defaults", - header_libs: [ - "libboost_headers", - ], - - local_include_dirs: [ - "interface", - "implementation/helper/1.70", - ], - - rtti: true, - cppflags: [ - "-std=c++11", + "-std=c++14", "-fexceptions", "-Wno-non-virtual-dtor", "-Wno-unused-const-variable", @@ -51,7 +45,25 @@ cc_defaults { "-Wno-format", "-Wno-header-guard", "-Wno-overloaded-virtual", - "-Wno-implicit-fallthrough" + "-Wno-implicit-fallthrough", + "-Wno-error", + "-Wno-shorten-64-to-32", + "-D_GTHREAD_USE_MUTEX_INIT_FUNC", + "-D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC", + ] +} + +cc_defaults { + name: "vsomeip_lib_defaults", + + cflags: [ + "-DVSOMEIP_BOOST_VERSION=107100", + "-DVSOMEIP_INTERNAL_SUPPRESS_DEPRECATED", + ], + + local_include_dirs: [ + "interface", + "implementation/helper" ] } @@ -62,53 +74,50 @@ cc_library_shared { srcs: libvsomeip_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], cflags: [ - "-DWITHOUT_SYSTEMD" + "-DWITHOUT_SYSTEMD", + "-DVSOMEIP_COMPAT_VERSION=\"3.3.0\"", + "-DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\"", + "-DUSE_DLT", ], - rtti: true, - - local_include_dirs: [ - "interface", - "implementation/helper/1.70" + ldflags: [ + "-Wl,-wrap,socket", + "-Wl,-wrap,accept" ], + rtti: true, + export_include_dirs: [ - "interface" + "interface" ], - static_libs: [ + shared_libs: [ "libboost_system", "libboost_thread", "libboost_filesystem", - ], - - shared_libs: [ "liblog", "libutils" ] } cc_library_shared { - name: "libvsomeip3-cfg", + name: "libvsomeip_cfg", vendor: true, srcs: libvsomeip_cfg_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ "libvsomeip3", "libboost_system", @@ -117,112 +126,61 @@ cc_library_shared { } cc_library_shared { - name: "libvsomeip3-e2e", + name: "libvsomeip_e2e", vendor: true, srcs: libvsomeip_e2e_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ - "libvsomeip3", - "liblog" + "libvsomeip3" ] } cc_library_shared { - name: "libvsomeip3-sd", + name: "libvsomeip_sd", vendor: true, srcs: libvsomeip_sd_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ "libvsomeip3", - "liblog", - "libboost_thread" + "libboost_system" ] } -cc_defaults { - name: "vsomeip_example_defaults", +cc_library_shared { + name: "libvsomeip", vendor: true, - owner: "ts", - - shared_libs: [ - "libvsomeip3" - ], -} - -cc_binary { - name: "vsomeip-helloworld-client", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/hello_world/hello_world_client_main.cpp", - ], -} -cc_binary { - name: "vsomeip-helloworld-service", - defaults: ["vsomeip_example_defaults"], + srcs: libvsomeip_compat_srcs, - srcs: [ - "examples/hello_world/hello_world_service_main.cpp", - ], -} - -cc_binary { - name: "vsomeip-notify-sample", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/notify-sample.cpp", - ], -} - -cc_binary { - name: "vsomeip-request-sample", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/request-sample.cpp", + defaults: [ + "vsomeip_defaults", + "vsomeip_lib_defaults" ], -} -cc_binary { - name: "vsomeip-response-sample", - defaults: ["vsomeip_example_defaults"], + rtti: true, - srcs: [ - "examples/response-sample.cpp", + export_include_dirs: [ + "interface" ], -} - -cc_binary { - name: "vsomeip-subscribe-sample", - defaults: ["vsomeip_example_defaults"], - srcs: [ - "examples/subscribe-sample.cpp", - ], + shared_libs: [ + "libvsomeip3", + "libboost_system" + ] } diff --git a/Android.mk b/Android.mk new file mode 100644 index 000000000..720165b7f --- /dev/null +++ b/Android.mk @@ -0,0 +1,214 @@ +# Cannot convert to Android.bp as resource copying has not +# yet implemented for soong as of 12/16/2016 + +LOCAL_PATH := $(call my-dir) + +# config/vsomeip.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-local.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-local.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-local.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-tcp-client.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-tcp-client.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-tcp-client.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-tcp-service.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-tcp-service.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-tcp-service.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-udp-client.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-udp-client.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-udp-client.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-udp-service.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-udp-service.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-udp-service.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# +# libvsomeip3_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip3_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/endpoints) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/logger) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/tracing) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/message) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/routing) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/runtime) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/utility) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/plugin) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/security) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + +LOCAL_CFLAGS := \ + -std=c++14 \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + +include $(BUILD_SHARED_LIBRARY) + +# +# libvsomeip-cfg_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip-cfg_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/configuration) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + libvsomeip3_dlt \ + +LOCAL_CFLAGS := \ + -std=c++14 \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + +include $(BUILD_SHARED_LIBRARY) + +# +# libvsomeip_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/compat/message) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/compat/runtime) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + libvsomeip3_dlt \ + +LOCAL_CFLAGS := \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_COMPAT_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + -Wl,-wrap,socket \ + +include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/CHANGES b/CHANGES index f5868f9b3..2b917d0d0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,147 +1,240 @@ Changes ======= -v3.1.37.1 -- Support REQUEST_ACK message type (PR #237) -- Fix typo in error message (PR #238) -- Fix for bug #239, as one process use two stubs for different vlans (PR #247, Issues #223 #239 #241) -- Fix multicast timeout crash on Windows caused by bad use of reinterpret_cast (PR #272) -- Update configuration paths to reside on vendor partition (PR #274) -- Retry failed netlink operations (PR #283) -- Fixed android build error (PR #288) -- Fix for configuration option deserialize bug (PR #300, Issue #263) -- Accept return codes within range 0x20-0x5E as valid (PR #312) -- Add support for broadcast (PR #314) -- Fix for TC8 test case SOMEIPSRV_RPC_07 and SOMEIPSRV_SD_BEHAVIOR_03 (PR #316, Issue #315) -- Support boost 1.76 (PR #318) -- Fix big endian support in byteorder.hpp (PR #320) -- Use Reference to Prevent Copying (PR #356) -- Add CI using github actions (PR #140) - -v3.1.37 -- Added dependency from network tests to e2e library (plugin). -- Avoid services becoming available when the daemon is suspended -- Handling with some udp errors in send_cbk process, - restarting the connection. - -v3.1.36 -- Fix for ELVIS-339712: Fix handling of subscription objects - during unsubscribe. - -v3.1.35 -- Reworked fix for ELVIS-3310053 -- Improve checking for matching responses. - - When sending a response, vSomeIP only checked for a request with - the corresponding combination of client and session identifiers. - - This led to the possibility, that a response was sent for the - wrong service and/or method because of matching client and session - identifiers. - - This commit implements a full check of service, method, client and - session identifiers to ensure a response fits to the received - request. -- Rework to get rid of clang-tidy (llvm14) warnings. -- Facilitate manual execution of (some) subscription tests. - - Switch log level from "debug" to "warning" to facilitate the selection - of the script name that must be executed on client side. -- Do not send initial events for rejected subscriptions. - -v3.1.34 -- Use default ports if an acceptance configuration does not specify any. -- Prevent StopSubscribe/Subscribe on first offer reception. -- Ignore routing state settings to the current state. -- Explicitely clean subscriptions if a service removal is reported. -- Use SOL_RECBUFFORCE instead of SOL_RECVBUF. - -v3.1.33 -- Corrected flag initialization to avoid wait time when re-establishing - connections. - -v3.1.32 -- Fix bug which could lead to deleting requested services of routing - manager. -- Add Jenkins pipeline. -- Fix race condition which could lead to false positive security - warnings. -- Fix handling of remote subscriptions for unoffered services: Fix bug - which could lead to erroneously not accepting remote subscriptions - after a service was stop being offered and offered again. - -v3.1.31 + +v3.3.0 +- Do not erase while iterating. +- Changed invalid call of deserialize to serialize +- Fixed the the problem in policy::deserialize counts down the given policy size, +and after deserializing the policy it is 0. +- Monitor session IDs in SD messages and log missing IDs +- Fix timestamp format of log message +- Prevent crash when logging with DLT +- load_security_update_whitelist Unit and Benchmark Tests +- Added protection when a message is destroyed. +- Rework the addition of services when in suspended mode +- Remove const qualifier from function return types +- Adapt to boost 1.81.0 +- Removed VSOMEIP_DEPRECATED_UID_GID from some elements. +- Add nullptr guards to receive_cbk. +- Add nullptr check to receive_cbk. +- Fix network test build for g++11.3. +- Remove mutexes from logger_impl and security_impl. +- Fix VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE buffer. +- Fix range-loop-construct warning for g++11.3. +- Implementation of support for header-only tracing. +- Fix applied regarding the timeout in endpoints connections. +- Use standard reliability_type_e on service_discovery_impl. +- Added receive operation for UDP server endpoints. +- Reduce log level of some vsomeip messages. +- Change dependency on LINK UP. +- Change rejoining mechanism in UDP server endpoint. +- Fixed android build issues +- Added more DLT log info on credentials error +- Fixed ICON register issues. +- Added an unlocked method to get the policy extension path +- Manage E2E Profile04 counters per instance +- Fix handling of subscription objects during unsubscribe. +- Remove subscription on connection resets. +- Reuse local client ports. +- Add try block in message deserialization. +- Remove unneeded / unused structure servicegroup. +- Optimize event/field registration. +- Add dependency from network tests to e2e library (plugin). +- re-introduce the definition of socket timeout. +- pu/event-tests: Avoid deadlock. +- Linux: avoid static initialization of std::mutex. +- Improve robustness when stopping initial-event tests. +- Fixed various unused-variable warnings. +- Handling with some udp errors in send_cbk process. +- Avoid services becoming available when the daemon is suspended. +- refactor: remove `set_bound_sec_client()` from `local_tcp_server_endpoint_impl`. +- Refactor `plugin_manager_impl::load_symbol()` +- Use consistent naming for `security::is_client_allowed_to_access()` +- Raise C++ standard used to C++17 on non-Windows platforms +- Prefer using reinterpret_cast instead of C-style casts +- DRYer approach to loading `libvsomeip_sec` hook functions +- Indent with 4-spaces +- Hide `symbol_table` inside `security::load()` +- `policy_manager::get()` should call `policy_manager_impl::get()` +- Fix integer conversion warning +- Refine silencing MSVC warning C4101 +- Add `VSOMEIP_DISABLE_SECURITY` in a few remaining spots +- Add support for `vsomeip_sec_client_t` to subscription handlers +- Disable security unit/benchmark tests when `DISABLE_SECURITY` +- Disable security network tests when `DISABLE_SECURITY` +- Make the sec client a member of the connection +- Add support for TCP clients in the default security hooks +- Fix security checks when using internal TCP sockets +- Introduced protocol classes +- Extended interface to allow application specific configurations +- Allow to switch off internal routing +- Added ACL plugin +- Respect subscription status handler for ANY_EVENT +- Corrected handling of ANY_[SERVICE|INSTANCE|EVENTGROUP|EVENT] when handling subscription status +- Fix handling of lock files +- Add subnet support for IPv6 networks (boost 1.66+ only for now) +- Fix client specific debouncing +- Set SO_REUSEADDR before binding socket +- Specify local IP/interface when joining multicast group +- Avoid false positives when warning about not having loaded acceptance data +- Extended buffer size adaptation for UDP sockets +- Removed leftover from attempt to fix setsockopt blocking +- Implemented a cache for is_client_allowed +- Adapted version in OSS information +- Log errors (connection reset, end of file, bad descriptor) as such +- Rename extended "subscribe" method to "subscribe_with_debounce" + +v3.2.15 +- Unit/Benchmark tests for Security::Check Credentials +- Client dependent usage of session handling +- Fix Windows build +- Fix for multicast_socket bug +- Fixed spam messages of security policy extensions +- Added OSS information for RSE + +v3.2.14 +- Implementation of support for header-only tracing +- Replaced exceptions with error messages +- Asynchronously set join/leave options +- React on failed option setting +- Prevented StopSubscribe/Subscribe on first offer reception +- Implemented a cache for is_client_allowed operations + +v3.2.13 +- Fixed lock_guard and mutexes on lazy load policies + +v3.2.12 +- Fixed race condition on startup of suspend_resume_test +- Added a default initialize in tcp_client_endpoint_impl::is_sending +- Updated the log "Maximum number of dispatchers exceeded" +- Refactored the policy extensions map +- Added protection for Received buffer size and buffer capacity +- Added nullptr checks to some pointers in the eventgroupinfo +- Fixed Windows build +- Removed print error messages for unneeded endpoints +- Wrapped accept method to use accept4 +- Improved reliability of multicast leave group + +v3.2.11 +- Fix incorrect load of policies +- Fix unlocked access to multicast_info +- Rework the join mechanism. +- Fix receiving of routing info messages in TCP mode. +- Make routing client port range configurable ("routing-client-ports"). +- Allow to configure event update properties. + +v3.2.10.1 +- Fix false positive security warning + +v3.2.10 - Fix race condition which could lead to not establishing a TCP connection to a remote service -v3.1.30 +v3.2.9 +- Send StopSubscribe and clear subscribed_ map on STR +- Added suspend/resume test +- Erase subscribed_ map on received StopOffer +- Select new local port on bind error for uce + +v3.2.8 +- Fixed credentials::receive_credentials() error handling +- Ensured to call prepare_stop handler for TCP server endpoints + +v3.2.7 - Fixed lock order inversion -- Fixed UDP socket bind error handling -v3.1.29 -- Do not send re-subscriptions on suspend +v3.2.6 +- Adapted helloworld references within user guide +- Added nullptr check for remote subscription pointers -v3.1.28 +v3.2.5 - Fixed race condition in client endpoint send queue - Improved robustness when receiving malformed remote subscriptions - Cleanup remote subscribers on suspend - -v3.1.27 -- Performance improvement: Added service partitioning: - Each configured partition will lead to a separate client port being used - to connect to a remote server port -- Improve handling of expired subscriptions -- Fixed race condition when starting "last message received" - timer. - -v3.1.26 -- Improve handling of expired subscriptions - -v3.1.25 +- Make sure that the connection (and thus the policy loading) + has taken place before checking something against the policies + +v3.2.4 +- Removed load of the vsomeip_ext policies from the start +- Allow to partition service instances. Each partition uses a separate client + port, even if service instances from different partitions are offered on the + same server port of a remote device. +- Fixed timer restart (detection of last received SD message) +- Optimized distribution of credentials- Improve handling of expired subscriptions - Fix event payload caching at proxy - -v3.1.24 +- Select a free client port that was not used recently +- Fixed invalid insertion in known_clients_ map +- Fixed clearing of client endpoints +- Rework for expire_subscriptions() +- Rework map insertions +- Avoid deadlocks during expiration of subscriptions + +v3.2.3 +- Optimized updating the sent counter for FindService messages in requested_ map +- Improved log messages +- Enabled tracing for initial values of shadow events for subsequent subscribers. +- Reduced the vsomeip security logging +- Fixed race condition in the logger - Fix for initial events - -v3.1.23 - Fixed crash in TCP client endpoint - Fixed TCP socket bind error handling - -v3.1.22 -- Fixed joining multicast group for udp server endpoints - -v3.1.21 -- Fixed missing DLT logs if DLT was enabled in config in parallel with file or console logging. -- Avoid heap-buffer-overflow in look_ahead() when deserializing SD entry / option type. -- Restart UDP client endpoint on connection refused error. -- Select a free client port that was not used recently. -- Limit the number of possible remote subscribers from same remote IP address - to an eventgroup provided by a service/instance if the remote - subscriber uses different ports for its subscriptions. - -v3.1.20.3 -- Correct detection payload changes (Issue #164) - -v3.1.20.2 -- Removed special way of detecting boost within NDK (PR #187) -- Allow events/eventgroups to be specified in arbitrary order (Issue #68) -- Allow port 65536 to be used (Issue #80) -- Support IPv6 (Issue #162, PR #179) -- Fix handling of local service history (Issue #163) -- Fix referencing of placeholder events (Issue #175) -- Corrected handling of debounced requests when releasing (Issue #181) -- Fixed possible race when disconnecting (Issue #182) -- Align order of acknowledgement and value sending (Issue #183) - -v3.1.20.1 -- CMakeLists.txt fixes - (by Martin Haase) -- Mark all services unavailable when the routing manager goes down - (by Philip Werner & dannyrhubarb) - -v3.1.20 -- SomeIP/TP optimization -- Fix for expired subscriptions - -v3.1.19 -- Log statistics for high frequent received remote events -- Avoid unintended deletion of all service instances in release_service() -- Prevent deletion of server endpoint on SubscribeEventGroupACK with multicast endpoint +- Selected new local port on bind error for tce. +- Ignored subscribes when suspended +- Added subscriber count to log / extended config switches +- Limited subscriptions to same service, instance, eventgroup depending on remote IP +- Synchronized update_remote_subscription / send_(un)subscription() +- Fixed lazy loading on daemon + +v3.2.2 +- Fixed the loading of the security policies at the start +- Fixed the tags in the android logging +- Added the additional client ports in the ipsec-plugin default configuration +- Removed the unneeded socket option IPPROTO_IP/IPPKTINFO. +- Removed the libdlt dependency from android +- Improved the documentation of debouncer configuration. +- Check the port to send notifications +- Fixed the nullptr on multicast_socket +- Improved the sending of STOP_OFFER messages + +v3.2.1 +- Updated cmake minimum required version +- Fixed expire_subscriptions(address) +- Updated examples +- Ensured to clear previous error before calling dlsym (plugin_manager) +- Always send values after subscription acknowledgment- +- Added support to logs in Android +- Updated android build files +- Ensured to forward logs to DLT independently of FILE / CONSOLE log configuration +- Avoided heap-buffer-overflow in look_ahead() when deserializing SD entry +- Adapted the reader of the config to put always logging in Android +- Used error code when starting main phase timer +- Added some SomeIP/TP optimization +- Changed the loglevel for blocked incoming notifications +- Restarted UDP client endpoint on connection refused error +- Acquired mutex before change sd_acceptance_rules_active_ +- Fixed getEnv returning empty value + +v3.2.0 +- Dropped support for boost 1.65 and below - Do not lock the multicast mutex twice +- Disable warnings for boost and DLT headers +- Fix security credentials update in rm::proxy +- Prevent deletion of server endpoint +- Fix instance removal in local_services_history_ map +- Lazy load security policies +- Use a configuration variable for the SOME/IP-TP maximum segment length +- Use instance based SOME/IP-TP configuration +- Use service configuration within server endpoint +- Ensure maximum segment length is a multiple of 16 (SIP_RPC_772) +- Use configured separation times +- Added debounce test and refined debouncing +- Fix hostname transmission +- Do _NOT_ remove subscription on a received StopOffer +- serviceinfo: Removed unused & undefined member group_ +- Implemented socket wrapper using ld(1)'s "--wrap" +- Set the android LOG_TAG to VSIP +- Added message statistics +- Reworked android logging v3.1.18 - Support boost 1.74 @@ -156,10 +249,6 @@ v3.1.17 - Fixed race condition between service instances offered on the same endpoint(s). -v3.1.16.1 -- Restore IPv6 within UDP server endpoint -- AOSP build adaptation to vsomeip3 libraries - v3.1.16 - Fixed race condition when leaving multicast group - Do not busy loop when receiving garbage data on local endpoint @@ -170,30 +259,13 @@ v3.1.15 - Speedup security policy handling - Enable building with boost v1.73.0 -v3.1.14.1 -- Merged extended support for static routing (versioning) - (by Jean-Patrice Laude jean-patrice.laude@renault.com) -- Merged simplification of build process for hello_world example - (by Nikolay Khilyuk nkh@ua.fm) -- Updated Android.bp to use boost 1.70 or higher -- Merged Android support for hello_world example - (by Nikolay Khilyuk nkh@ua.fm) -- Align response sample to documentation (do not specify application name) - (by JayHou houjie@lixiang.com) -- Call dlerror before calling dlsym to clear previous error - (by Oleg Kharitonov Oleg.Kharitonov@elektrobit.com) -- Get base path from environment variable for Android NDK - (by Nikolay Khilyuk nkh@ua.fm) -- Fixed wrong library naming - (by Nikolay Khilyuk nkh@ua.fm) - v3.1.14 - Fixed race conditions (application registration, subscription) v3.1.13 - Abort operation when doing a full rejoin - Protect access when consuming a policy -- Decrease wait time for composite send operations +- Decrease wait time for composite send operations - Reimplemented logger without using boost::log v3.1.12 @@ -227,10 +299,10 @@ v3.1.7 v3.1.6 - Fix possible busy loop when expiring subscriptions - Use set of serializers to avoid deadlock situation -- Improve client identifier handling +- Improve client identifier handling - Check whether corresponding socket is available - Implement retry if a client identifier cannot be used -- Log buffer fill levels if they exceed a configurable threshold (default=67%). +- Log buffer fill levels if they exceed a configurable threshold (default=67%). v3.1.5 - Ensure subscriptions to remote services are correctly reset when @@ -506,7 +578,7 @@ v2.10.20 v2.10.19 - Catch exceptions on shutdown (especially from boost::log) -- Fixed handling of malformed packets in TCP client endpoint in conjunction +- Fixed handling of malformed packets in TCP client endpoint in conjunction with magic cookies v2.10.18 @@ -921,8 +993,8 @@ v2.2.2 to be used for unicasts instead of relying on the configured routes v2.2.1 -- Backward compatibility fixes - +- Backward compatibility fixes + v2.2.0 - Implemented Peer-to-Peer data exchange for notifications - Fixed handling of minor version during service discovery @@ -1037,7 +1109,7 @@ v1.3.0 v1.2.0 - Added (optional) thread pool for distribution of messages to the application -- Made configuration of service groups optional (as it is unneeded in pure +- Made configuration of service groups optional (as it is unneeded in pure client applications) - Support specification of transportation mode (reliable (TCP) / unreliable (UDP)) when creating messages diff --git a/CMakeLists.txt b/CMakeLists.txt index 36cf6acb7..6b0004136 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,16 +3,16 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.12...3.23.3) +cmake_minimum_required (VERSION 3.10) project (vsomeip) set (VSOMEIP_NAME vsomeip3) set (VSOMEIP_COMPAT_NAME vsomeip) set (VSOMEIP_MAJOR_VERSION 3) -set (VSOMEIP_MINOR_VERSION 1) -set (VSOMEIP_PATCH_VERSION 37) -set (VSOMEIP_HOTFIX_VERSION 1) +set (VSOMEIP_MINOR_VERSION 3) +set (VSOMEIP_PATCH_VERSION 0) +set (VSOMEIP_HOTFIX_VERSION 0) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentation/doxygen.in @@ -31,9 +31,9 @@ endif() ################################################################################################### # Offer the user the choice of overriding the installation directories -set (INSTALL_LIB_DIR lib CACHE STRING "Installation directory for libraries") -set (INSTALL_BIN_DIR bin CACHE STRING "Installation directory for executables") -set (INSTALL_INCLUDE_DIR include CACHE STRING "Installation directory for header files") +set (INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") +set (INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") +set (INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") if (WIN32 AND NOT CYGWIN) set (DEF_INSTALL_CMAKE_DIR CMake) @@ -41,7 +41,15 @@ else () set (DEF_INSTALL_CMAKE_DIR lib/cmake/${VSOMEIP_NAME}) endif () -set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE STRING "Installation directory for CMake files") +set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") + +# Make relative paths absolute (needed later on) +foreach (p LIB BIN INCLUDE CMAKE) + set (var INSTALL_${p}_DIR) + if (NOT IS_ABSOLUTE "${${var}}") + set (ABSOLUTE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") # Add all targets to the build-tree export set + endif () +endforeach () ################################################################################################### # Set a default build type if none was specified @@ -55,27 +63,24 @@ endif() # OS if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(OS "LINUX") set(DL_LIBRARY "dl") + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # This is only relevant for GCC and causes warnings on Clang set(EXPORTSYMBOLS "-Wl,-export-dynamic -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exportmap.gcc") - set(NO_DEPRECATED "") - set(OPTIMIZE "") - set(OS_CXX_FLAGS "-D_GLIBCXX_USE_NANOSLEEP -pthread -O -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector-strong -fasynchronous-unwind-tables -fno-omit-frame-pointer -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security -fPIE -pie -Wl,-z,relro,-z,now") -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(OS_CXX_FLAGS "${OS_CXX_FLAGS} -pie -Wl,-z,relro,-z,now") +endif() -if (${CMAKE_SYSTEM_NAME} MATCHES "Android") - set(OS "ANDROID") - set(DL_LIBRARY "") - set(EXPORTSYMBOLS "") set(NO_DEPRECATED "") set(OPTIMIZE "") + set(OS_CXX_FLAGS "${OS_CXX_FLAGS} -D_GLIBCXX_USE_NANOSLEEP -pthread -O -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector-strong -fasynchronous-unwind-tables -fno-omit-frame-pointer -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Wpedantic -Werror -fPIE") - find_library(ANDROID_LOG_LIB log) - set(OS_LIBS ${ANDROID_LOG_LIB}) -endif(${CMAKE_SYSTEM_NAME} MATCHES "Android") + # force all use of std::mutex and std::recursive_mutex to use runtime init + # instead of static initialization so mutexes can be hooked to enable PI as needed + add_definitions(-D_GTHREAD_USE_MUTEX_INIT_FUNC -D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) +endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - set(OS "FREEBSD") set(DL_LIBRARY "") set(EXPORTSYMBOLS "") set(NO_DEPRECATED "-Wno-deprecated") @@ -83,7 +88,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set(OS_CXX_FLAGS "-pthread") endif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") -################################################################################ +############################################My lib link flags#################################### # Options ################################################################################ @@ -99,19 +104,20 @@ if (ENABLE_SIGNAL_HANDLING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_SIGNAL_HANDLING") endif () -# Sanitizer -if (ENABLE_THREAD_SANITIZER) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") -endif () +if (NOT MSVC) + # Sanitizer + if (ENABLE_THREAD_SANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + endif () -if (ENABLE_LEAK_SANITIZER) -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") -endif () + if (ENABLE_LEAK_SANITIZER) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") + endif () -# Configuration overlays -if (ENABLE_CONFIGURATION_OVERLAYS) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_CONFIGURATION_OVERLAYS") -endif () + if (ENABLE_PROFILING) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + endif () +endif (NOT MSVC) # Compatibility if (ENABLE_COMPAT) @@ -127,11 +133,14 @@ else () set (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS 0) endif () -# Session handling configuration -if (ENABLE_SESSION_HANDLING_CONFIG) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_HAS_SESSION_HANDLING_CONFIG") +# Security / Policy handling +if (DISABLE_SECURITY) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_DISABLE_SECURITY") endif () +# Suppress deprecation warnings for vSomeIP interfaces +add_definitions(-DVSOMEIP_INTERNAL_SUPPRESS_DEPRECATED) + ################################################################################ # Dependencies ################################################################################ @@ -164,19 +173,14 @@ else() endif() message( STATUS "Using boost version: ${VSOMEIP_BOOST_VERSION}" ) -if (${VSOMEIP_BOOST_VERSION} GREATER 107600) -message( ERROR "boost version ${VSOMEIP_BOOST_VERSION} is not (yet) supported. Latest supported version is 1.76.0" ) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 107500) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.76) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 107300) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.74) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 106999) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.70) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 106599) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.66) -else() -set(VSOMEIP_BOOST_HELPER implementation/helper/1.55) -endif() + +if (${VSOMEIP_BOOST_VERSION} LESS 106600) +include_directories(SYSTEM + implementation/helper +) +endif () + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_BOOST_VERSION=${VSOMEIP_BOOST_VERSION}") find_package(PkgConfig) @@ -191,12 +195,10 @@ endif() # SystemD pkg_check_modules(SystemD "libsystemd") -if(NOT SystemD_FOUND OR ${CMAKE_SYSTEM_NAME} MATCHES "Android") +if(NOT SystemD_FOUND) MESSAGE( STATUS "Systemd was not found, watchdog disabled!") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITHOUT_SYSTEMD") -else() -list(APPEND OS_LIBS ${SystemD_LIBRARIES}) -endif(NOT SystemD_FOUND OR ${CMAKE_SYSTEM_NAME} MATCHES "Android") +endif(NOT SystemD_FOUND) # Multiple routing managers if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 1) @@ -212,7 +214,6 @@ include_directories( ) include_directories(SYSTEM - ${VSOMEIP_BOOST_HELPER} ${DLT_INCLUDE_DIRS} ) @@ -230,16 +231,14 @@ if (MSVC) message("using MSVC Compiler") # add_definitions(-DVSOMEIP_DLL_COMPILATION) now it is controlled per target SET(BOOST_WINDOWS_VERSION "0x600" CACHE STRING "Set the same Version as the Version with which Boost was built, otherwise there will be errors. (normaly 0x600 is for Windows 7 and 0x501 is for Windows XP)") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") + # Disable warning C4250 since it warns that the compiler is correctly following the C++ Standard. It's a "We-Are-Doing-Things-By-The-Book" notice, not a real warning. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc /std:c++latest /wd4250") set(USE_RT "") link_directories(${Boost_LIBRARY_DIR_DEBUG}) ADD_DEFINITIONS( -DBOOST_ALL_DYN_LINK ) else() - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${OS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++11 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") - if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") - set(USE_RT "rt") - endif() + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++14 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") + set(USE_RT "rt") endif() ################################################################################ @@ -256,7 +255,7 @@ if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 0) set_target_properties(${VSOMEIP_NAME}-cfg PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif() - target_link_libraries(${VSOMEIP_NAME}-cfg ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) + target_link_libraries(${VSOMEIP_NAME}-cfg ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) endif () ################################################################################ @@ -268,6 +267,7 @@ file(GLOB ${VSOMEIP_NAME}_SRC "implementation/tracing/src/*.cpp" "implementation/message/src/*.cpp" "implementation/plugin/src/*.cpp" + "implementation/protocol/src/*.cpp" "implementation/routing/src/*.cpp" "implementation/runtime/src/*.cpp" "implementation/security/src/*.cpp" @@ -276,23 +276,30 @@ file(GLOB ${VSOMEIP_NAME}_SRC if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 1) list(APPEND ${VSOMEIP_NAME}_SRC "implementation/configuration/src/configuration_impl.cpp") endif() + +if (WIN32) +list(FILTER ${VSOMEIP_NAME}_SRC EXCLUDE REGEX ".*uds.*") +endif() + list(SORT ${VSOMEIP_NAME}_SRC) add_library(${VSOMEIP_NAME} SHARED ${${VSOMEIP_NAME}_SRC}) set_target_properties (${VSOMEIP_NAME} PROPERTIES VERSION ${VSOMEIP_VERSION} SOVERSION ${VSOMEIP_MAJOR_VERSION}) if (MSVC) set_target_properties(${VSOMEIP_NAME} PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION") +else () + set_target_properties(${VSOMEIP_NAME} PROPERTIES LINK_FLAGS "-Wl,-wrap,socket -Wl,-wrap,accept") endif () target_include_directories(${VSOMEIP_NAME} INTERFACE $ $ $) # PRIVATE means the listed libraries won't be included in the "link interface", -# meaning the exported vsomeip3Targets.cmake targets won't try to link against +# meaning the exported ${VSOMEIP_NAME}Targets.cmake targets won't try to link against # them (which shouldn't be required). ${Boost_LIBRARIES} includes absolute # build host paths as of writing, which also makes this important as it breaks # the build. -target_link_libraries(${VSOMEIP_NAME} PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${DLT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME} PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${DLT_LIBRARIES} ${SystemD_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ################################################################################ # Service Discovery library @@ -308,7 +315,7 @@ if (MSVC) set_target_properties(${VSOMEIP_NAME}-sd PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif () -target_link_libraries(${VSOMEIP_NAME}-sd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME}-sd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ################################################################################ @@ -325,7 +332,7 @@ if (MSVC) set_target_properties(${VSOMEIP_NAME}-e2e PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif () -target_link_libraries(${VSOMEIP_NAME}-e2e ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME}-e2e ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) ################################################################################ # Compatibility library @@ -356,7 +363,7 @@ target_include_directories( $ # for generated files in build mode $ # for clients in install mode ) -target_link_libraries(${VSOMEIP_COMPAT_NAME} PRIVATE ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_COMPAT_NAME} PRIVATE ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) endif () @@ -407,7 +414,7 @@ message("Predefined diagnosis address: ${VSOMEIP_DIAGNOSIS_ADDRESS}") ################################################################################ set(INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/interface/vsomeip") -file (GLOB_RECURSE vsomeip_INCLUDE RELATIVE ${INCLUDE_PATH} "interface/*.hpp" ) +file (GLOB_RECURSE vsomeip_INCLUDE RELATIVE ${INCLUDE_PATH} "interface/*.h*" ) list (SORT vsomeip_INCLUDE) foreach ( file ${vsomeip_INCLUDE} ) @@ -418,7 +425,7 @@ endforeach() install ( TARGETS ${VSOMEIP_NAME} # IMPORTANT: Add the vsomeip library to the "export-set" - EXPORT vsomeip3Targets + EXPORT ${VSOMEIP_NAME}Targets RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" @@ -485,15 +492,15 @@ install ( ) # Add all targets to the build-tree export set -export (TARGETS ${VSOMEIP_NAME} FILE "${PROJECT_BINARY_DIR}/vsomeip3Targets.cmake") +export (TARGETS ${VSOMEIP_NAME} FILE "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Targets.cmake") # Export the package for use from the build-tree # (this registers the build-tree with a global CMake-registry) export (PACKAGE ${VSOMEIP_NAME}) -# Create the vsomeip3Config.cmake and vsomeip3ConfigVersion files -configure_file (vsomeip3Config.cmake.in "${PROJECT_BINARY_DIR}/vsomeip3Config.cmake" @ONLY) -configure_file (vsomeip3ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/vsomeip3ConfigVersion.cmake" @ONLY) +# Create the ${VSOMEIP_NAME}Config.cmake and ${VSOMEIP_NAME}ConfigVersion files +configure_file (${VSOMEIP_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Config.cmake" @ONLY) +configure_file (${VSOMEIP_NAME}ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}ConfigVersion.cmake" @ONLY) # configure internal.hpp for correct version number configure_file ( @@ -501,18 +508,18 @@ configure_file ( "${PROJECT_SOURCE_DIR}/implementation/configuration/include/internal.hpp" ) -# Install the vsomeip3Config.cmake and vsomeip3ConfigVersion.cmake +# Install the ${VSOMEIP_NAME}Config.cmake and ${VSOMEIP_NAME}ConfigVersion.cmake install ( FILES - "${PROJECT_BINARY_DIR}/vsomeip3Config.cmake" - "${PROJECT_BINARY_DIR}/vsomeip3ConfigVersion.cmake" + "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}ConfigVersion.cmake" DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev ) # Install the export set for use with the install-tree install ( - EXPORT vsomeip3Targets + EXPORT ${VSOMEIP_NAME}Targets DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev ) @@ -581,32 +588,32 @@ endif() ############################################################################## # create pkg-config file if(NOT WIN32) - configure_file(vsomeip3.pc.in ${PROJECT_BINARY_DIR}/vsomeip3.pc @ONLY) - install(FILES ${PROJECT_BINARY_DIR}/vsomeip3.pc DESTINATION lib/pkgconfig) + configure_file(${VSOMEIP_NAME}.pc.in ${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}.pc @ONLY) + install(FILES ${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}.pc DESTINATION lib/pkgconfig) endif() ############################################################################## -if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") - # build routing manager daemon (Non-Windows only) - if (NOT MSVC) - add_subdirectory( examples/routingmanagerd ) - endif() +# build routing manager daemon (Non-Windows only) +if (NOT MSVC) +add_subdirectory( examples/routingmanagerd ) +endif() - # build tools - add_custom_target( tools ) - add_subdirectory( tools ) +# build tools +add_custom_target( tools ) +add_subdirectory( tools ) - # build examples - add_custom_target( examples ) - add_subdirectory( examples EXCLUDE_FROM_ALL ) - add_custom_target( hello_world ) - add_subdirectory( examples/hello_world EXCLUDE_FROM_ALL ) -endif() +# build examples +add_custom_target( examples ) +add_subdirectory( examples EXCLUDE_FROM_ALL ) ############################################################################## # Test section ############################################################################## +############################################################################## +# google benchmark +find_package(benchmark) + ############################################################################## # google test @@ -654,9 +661,9 @@ SET(TEST_IP_SLAVE "${TEST_IP_DEFAULT_VALUE}" CACHE STRING if((${TEST_IP_MASTER} STREQUAL ${TEST_IP_DEFAULT_VALUE}) OR (${TEST_IP_SLAVE} STREQUAL ${TEST_IP_DEFAULT_VALUE})) message(WARNING "TEST_IP_MASTER and/or TEST_IP_SLAVE isn't set. " - "Only local tests will be runnable " - "Please specify them via for example " - "-DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.125") + "Remote tests cannot be run. " + "To enable, please specify for example " + "-DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.2") endif() SET(TEST_IP_SLAVE_SECOND "${TEST_IP_DEFAULT_VALUE}" CACHE STRING @@ -673,15 +680,7 @@ else() set(TEST_SECOND_ADDRESS "ON") endif() -set(TEST_E2E_PROFILE_04 "OFF" CACHE BOOL - "Controls whether E2E Profile 04 tests should run or not") -if (ENABLE_SESSION_HANDLING_CONFIG) - set(TEST_E2E_PROFILE_04 "ON") -else () - message(WARNING "ENABLE_SESSION_HANDLING_CONFIG isn't set. " - "Test of E2E Profile 04 is not enabled.") -endif () - +set(TEST_E2E_PROFILE_04 "ON") SET(TEST_UID_DEFAULT_VALUE "123456789") SET(TEST_UID "${TEST_UID_DEFAULT_VALUE}" CACHE STRING @@ -694,7 +693,8 @@ SET(TEST_SECURITY "ON" CACHE BOOL "Controls whether security tests should run or not") if((${TEST_UID} STREQUAL ${TEST_UID_DEFAULT_VALUE}) OR - (${TEST_GID} STREQUAL ${TEST_GID_DEFAULT_VALUE})) + (${TEST_GID} STREQUAL ${TEST_GID_DEFAULT_VALUE}) OR + DISABLE_SECURITY) message(WARNING "TEST_UID and/or TEST_GID isn't set. " "Security Tests are not runnable " "Please specify them for example " @@ -703,14 +703,27 @@ if((${TEST_UID} STREQUAL ${TEST_UID_DEFAULT_VALUE}) OR endif() add_custom_target(build_tests) -add_dependencies(build_tests vsomeip3) -add_dependencies(build_tests vsomeip3-e2e) -add_dependencies(build_tests vsomeip3-sd) set(CMAKE_CTEST_COMMAND ctest -V) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) add_dependencies(check build_tests) +add_custom_target(build_network_tests) +add_dependencies(build_network_tests ${VSOMEIP_NAME}) +add_dependencies(build_network_tests ${VSOMEIP_NAME}-e2e) +add_dependencies(build_network_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_network_tests) + +add_custom_target(build_unit_tests) +add_dependencies(build_unit_tests ${VSOMEIP_NAME}) +add_dependencies(build_unit_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_unit_tests) + +add_custom_target(build_benchmark_tests) +add_dependencies(build_benchmark_tests ${VSOMEIP_NAME}) +add_dependencies(build_benchmark_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_benchmark_tests) + ############################################################################## # add test directory diff --git a/LICENSE b/LICENSE index 14e2f777f..a612ad981 100644 --- a/LICENSE +++ b/LICENSE @@ -35,7 +35,7 @@ Mozilla Public License Version 2.0 means any form of the work other than Source Code Form. 1.7. "Larger Work" - means a work that combines Covered Software with other material, in + means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" diff --git a/README.md b/README.md index 8036a1109..70be2290d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### vsomeip ##### Copyright -Copyright (C) 2015-2017, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) ##### License @@ -15,29 +15,24 @@ The vsomeip stack implements the http://some-ip.com/ (Scalable service-Oriented MiddlewarE over IP (SOME/IP)) protocol. The stack consists out of: * a shared library for SOME/IP (`libvsomeip3.so`) -* a second shared library for SOME/IP's service discovery (`libvsomeip3-sd.so`) - which is loaded during runtime if the service discovery is enabled. +* a shared library for SOME/IP's configuration module (`libvsomeip3-cfg.so`) +* a shared library for SOME/IP's service discovery (`libvsomeip3-sd.so`) +* a shared library for SOME/IP's E2E protection module (`libvsomeip3-e2e.so`) + +Optional: + +* a shared library for compatibility with vsomeip v2 (`libvsomeip.so`) ##### Build Instructions for Linux ###### Dependencies -- A C++11 enabled compiler like gcc >= 4.8 is needed. +- A C++14 enabled compiler is needed (default for gcc >= v6.1). - vsomeip uses CMake as buildsystem. -- vsomeip uses Boost >= 1.55: - -Ubuntu 14.04: +- vsomeip uses Boost >= 1.55.0: -`sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev libboost-log1.55-dev` - -Ubuntu 12.04: a PPA is necessary to use version 1.54 of Boost: --- URL: https://launchpad.net/~boost-latest/+archive/ubuntu/ppa ---`sudo add-apt-repository ppa:boost-latest/ppa` ---`sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev - libboost-log1.55-dev` - -For the tests Google's test framework https://code.google.com/p/googletest/[gtest] in version 1.7.0 is needed. --- URL: https://googletest.googlecode.com/files/gtest-1.7.0.zip +For the tests Google's test framework https://code.google.com/p/googletest/[gtest] is needed. +-- URL: https://googletest.googlecode.com/files/gtest-.zip To build the documentation asciidoc, source-highlight, doxygen and graphviz is needed: --`sudo apt-get install asciidoc source-highlight doxygen graphviz` @@ -114,5 +109,6 @@ In order that the vsomeip library is also included in the Android image, the lib PRODUCT_PACKAGES += \ libvsomeip \ libvsomeip_cfg \ - libvsomeip_sd -``` \ No newline at end of file + libvsomeip_sd \ + libvsomeip_e2e \ +``` diff --git a/documentation/vsomeipProtocol b/documentation/vsomeipProtocol new file mode 100644 index 000000000..2fc905ed0 --- /dev/null +++ b/documentation/vsomeipProtocol @@ -0,0 +1,372 @@ +vSomeIP command documentation +============================= + +VSOMEIP_ASSIGN_CLIENT (0x00) + +Command 00 +Version xx xx +Client xx xx +Size xx xx xx xx +Name xx ... xx ;#xx = Size + + +VSOMEIP_ASSIGN_CLIENT_ACK (0x01) + +Command 01 +Version xx xx +Client xx xx +Size 02 00 00 00 +Assigned xx xx + + +VSOMEIP_REGISTER_APPLICATION (0x02) + +Command 02 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_DEREGISTER_APPLICATION (0x03) + +Command 03 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_APPLICATION_LOST (0x04) + + + + +VSOMEIP_ROUTING_INFO (0x05) + +Command 05 +Version xx xx +Client xx xx +Size xx xx xx xx +Entries + SubCommand xx ; RIE_ADD_CLIENT (0x0) or RIE_DEL_CLIENT (0x1) + Size xx xx xx xx + Client xx xx + [Address] xx .. xx ; Size - sizeof(Client) - sizeof(Port) + [Port] xx + + SubCommand xx ; RIE_ADD_SERVICE_INSTANCE (0x2) or RIE_DEL_SERVICE_INSTANCE (0x3) + Size xx xx xx xx ; Command size + Size xx xx xx xx ; Client info size + Client xx xx + [Address] xx .. xx ; Client info size - sizeof(Client) - sizeof(Port) + [Port] xx + Size xx xx xx xx ; Services size + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +VSOMEIP_REGISTERED_ACK (0x06) + +Command 06 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_PING (0x07) + +Command 07 +Version xx xx +Client 00 00 +Size 00 00 00 00 + + +VSOMEIP_PONG (0x08) + +Command 08 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_OFFER_SERVICE (0x10) + +Command 10 +Version xx xx +Client xx xx +Size 09 00 00 00 +Service xx xx +Instance xx xx +Major xx +Minor xx xx xx xx + + +VSOMEIP_STOP_OFFER_SERVICE (0x11) + +Command 11 +Version xx xx +Client xx xx +Size 09 00 00 00 +Service xx xx +Instance xx xx +Major xx +Minor xx xx xx xx + + +VSOMEIP_SUBSCRIBE (0x12) + +Command 12 +Version xx xx +Client xx xx +Size xx xx xx xx +Service xx xx +Instance xx xx +Eventgroup xx xx +Major xx +Event xx xx +Pending ID xx xx +Filter + OnChange xx + OnChangeResetsInterval xx + Interval xx xx xx xx xx xx xx xx + Ignore (per entry) + Key xx xx xx xx xx xx xx xx + Value xx + + +VSOMEIP_UNSUBSCRIBE (0x13) +VSOMEIP_EXPIRE (0x2A) + +Command 13/2A +Version xx xx +Client xx xx +Size 0a 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Event xx xx +Pending ID xx xx + + +VSOMEIP_REQUEST_SERVICE (0x14) + +Command 14 +Version xx xx +Client xx xx +Size xx xx xx xx +Entries + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +VSOMEIP_RELEASE_SERVICE (0x15) + +Command 15 +Version xx xx +Client xx xx +Size 04 00 00 00 +Service xx xx +Instance xx xx + + +VSOMEIP_SUBSCRIBE_NACK (0x16) + +Command 16 +Version xx xx +Client xx xx +Size 0c 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Subscriber xx xx +Event xx xx +ID xx xx + + +VSOMEIP_SUBSCRIBE_ACK (0x17) + +Command 17 +Version xx xx +Client xx xx +Size 0c 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Subscriber xx xx +Event xx xx +ID xx xx + + +VSOMEIP_SEND (0x18) +VSOMEIP_NOTIFY (0x19) +VSOMEIP_NOTIFY_ONE (0x1A) + +Command 18|19|1a +Version xx xx +Client xx xx +Size xx xx xx xx +Instance xx xx +Reliable xx ; UDP (00) or TCP (01) +Status xx ; CRC of E2E - protected messages +Destination xx xx ; Client ID of the receiver +Payload xx ... xx + + +VSOMEIP_REGISTER_EVENT (0x1B) + +Command 1b +Version xx xx +Client xx xx +Size xx xx xx xx ; 10 + #eventgroups * 2 +Entries + Service xx xx + Instance xx xx + Notifier xx xx + Type xx ; ET_EVENT (00), ET_SELECTIVE_EVENT(01) or ET_FIELD(02) + Provided xx ; False (00) or True (01) + Reliability xx ; UDP (00) or TCP (01) + IsCyclic xx + Num Eventgroups xx xx + Entries + Eventgroup xx xx + + +VSOMEIP_UNREGISTER_EVENT (0x1C) + +Command 1c +Version xx xx +Client xx xx +Size 07 00 00 00 +Service xx xx +Instance xx xx +Notifier xx xx +Provided xx + + +VSOMEIP_ID_RESPONSE (0x1D) + + + + +VSOMEIP_ID_REQUEST (0x1E) + + + + +VSOMEIP_OFFERED_SERVICES_REQUEST (0x1F) + +Command 1f +Version xx xx +Client xx xx +Size 01 00 00 00 +OfferType xx (00 = LOCAL, 01 = REMOTE, 02 = ALL) + + +VSOMEIP_OFFERED_SERVICES_RESPONSE (0x20) + +Command 20 +Version xx xx +Client xx xx +Size xx xx xx xx +OfferedServices + Subcommand xx (00 = ADD CLIENT, 01 = ADD SERVICE INSTANCE, 02 = DELETE SERVICE INSTANCE, 03 = DELETE CLIENT) + Size xx xx xx xx + ServiceInstances + Service xx xx + Instance xx xx + Major xx xx + Minor xx xx + + +VSOMEIP_UNSUBSCRIBE_ACK (0x21) + +Command 21 +Version xx xx +Client xx xx +Size 08 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Id xx xx + + +VSOMEIP_RESEND_PROVIDED_EVENTS (0x22) + +Command 22 +Version xx xx +Client xx xx +Size 04 00 00 00 +PendingOfferId xx xx xx xx + + +VSOMEIP_UPDATE_SECURITY_POLICY (0x23) +VSOMEIP_UPDATE_SECURITY_POLICY_INT (0x29) + +Command 23/29 +Version xx xx +Client xx xx +Size xx xx xx xx +UpdateId xx xx xx xx +Policy xx ... xx + + +VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE (0x24) + +Command 24 +Version xx xx +Client xx xx +Size 04 00 00 00 +UpdateId xx xx xx xx + + +VSOMEIP_REMOVE_SECURITY_POLICY (0x25) + +Command 25 +Version xx xx +Client xx xx +Size 0c 00 00 00 +UpdateId xx xx xx xx +Uid xx xx xx xx +Gid xx xx xx xx + + +VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE (0x26) + +Command 26 +Version xx xx +Client xx xx +Size 04 00 00 00 +UpdateId xx xx xx xx + + +VSOMEIP_UPDATE_SECURITY_CREDENTIALS (0x27) + +Command 27 +Version xx xx +Client xx xx +Size xx xx xx xx +Credentials + Uid xx xx xx xx + Gid xx xx xx xx + + +VSOMEIP_DISTRIBUTE_SECURITY_POLICIES (0x28) + +Command 28 +Version xx xx +Client xx xx xx xx +Size xx xx xx xx +PoliciesCount xx xx xx xx +Policies + Size xx xx xx xx + Data xx ... xx + + +VSOMEIP_SUSPEND (0x30) + +Command 30 +Version xx xx +Size xx xx xx xx \ No newline at end of file diff --git a/documentation/vsomeipUserGuide b/documentation/vsomeipUserGuide index dd4f13d24..b98183a5c 100644 --- a/documentation/vsomeipUserGuide +++ b/documentation/vsomeipUserGuide @@ -15,7 +15,7 @@ vsomeip Copyright +++++++ -Copyright (C) 2015-2019, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) License +++++++ @@ -42,7 +42,7 @@ Build Instructions ------------------ Dependencies ~~~~~~~~~~~~ -* A C++11 enabled compiler like gcc >= 5.2 is needed. +* A C++14 enabled compiler is needed (default for gcc >= v6.1) * vsomeip uses cmake as buildsystem. * vsomeip uses Boost >= 1.55: ** Ubuntu 14.04: @@ -144,15 +144,6 @@ to be ready to send/receive messages, call cmake like: cmake -DROUTING_READY_MESSAGE= .. ---- -Compilation with configuration overlays -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To compile vsomeip with configuration overlays enabled, call cmake -like: -[source,bash] ----- -cmake -DENABLE_CONFIGURATION_OVERLAYS=1 .. ----- - Compilation with vSomeIP 2 compatibility layer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To compile vsomeip with enabled vSomeIP 2 compatibility layer, call @@ -272,6 +263,8 @@ On startup the following environment variables are read out: local configuration file `./vsomeip.json` and/or a local configuration folder `./vsomeip`. If `VSOMEIP_CONFIGURATION` is set to a valid file or directory path, this is used instead of the standard configuration (thus neither default nor local file/folder will be parsed). +* `VSOMEIP_CONFIGURATION_`: Application-specific version of `VSOMEIP_CONFIGURATION`. + Please note that must be valid as part of an environment variable. * `VSOMEIP_MANDATORY_CONFIGURATION_FILES`: vsomeip allows to specify mandatory configuration files to speed-up application startup. While mandatory configuration files are read by all applications, all other configuration files are only read by the application that is @@ -551,14 +544,6 @@ An application plug-in extends the functionality on application level. It gets i by vsomeip over the basic application states (INIT/START/STOP) and can, based on these notifications, access the standard "application"-API via the runtime. + -** 'overlay' (optional) -+ -Contains the path to a configuration that overwrites specific configuration elements -(unicast, netmask, device, network, diagnosis address & mask, service discovery) for the -application. This allows to manage different network addresses from a single process. -+ -NOTE: This feature is only available if vsomeip was compiled with ENABLE_CONFIGURATION_OVERLAYS. -+ * `services` (array) + Contains the services of the service provider. @@ -951,14 +936,15 @@ Event ID. *** `on_change` + -Specifies whether the event is only forwared on -paylaod change or not. (valid values: _true_, _false_). +Specifies whether the event is forwarded on +payload change or not. (valid values: _true_, _false_). +Default is _false_. *** `ignore` + Array of payload indexes with given bit mask (optional) to be ignored in payload change evaluation. -Instead of specifying an index / bitmask pair, one can only define the paylaod index +Instead of specifying an index / bitmask pair, one can only define the payload index which shall be ignored in the evaluation. **** `index` @@ -973,17 +959,64 @@ Example mask: 0x0f ignores payload changes in low nibble of the byte at given in *** `interval` + Specifies if the event shall be debounced based on elapsed time interval. -(valid values: _time in ms_, _never_). +(valid values: _time in ms_, _never_). Default is _never_. -*** `on_change_resets_interval_` (optional) +*** `on_change_resets_interval` (optional) Specifies if interval timer is reset when payload change was detected. -(valid values: _false_, _true_). +(valid values: _false_, _true_). Defaults to _false_. + +* `routing` (optional) ++ +Specifies the properties of the routing. Either a string that specifies the application that hosts the +routing component or a structure that specifies all properties of the routing. If the routing is not +specified, the first started application will host the routing component. + +** `host` ++ +Properties of the routing manager. + +*** `name` ++ +Name if the application that hosts the routing component. + +*** `uid` ++ +User identifier of the process that runs the routing component. Must be specified if credential checks +are enabled by _check_credentials_ set to true. + +*** `gid` ++ +Group identifier of the process that runs the routing component. Must be specified if credential checks +are enabled by _check_credentials_ set to true. + +*** `unicast` (optional) ++ +The unicast address that shall be used by the routing manager, if the internal communication shall be done +by using TCP connections. -* `routing` +*** `port` (optional) + -The name of the application that is responsible for the routing. +The port that shall be used by the routing manager, if the internal communication shall be done +by using TCP connections. -* `routing-credentials` +** `guests` (optional) ++ +Properties of all applications that do not host the routing component, if the internal communication shall be +done using TCP connections. + +*** `unicast` ++ +The unicast address that shall be used by the applications to connect to the routing manager. + +*** `ports` ++ +A set of port ranges that shall be used to connect to the routing manager. Each client application requires +two ports, one for receiving messages from other applications and one to send messages to other applications. +Notes: Each configured port range must contain an even number of ports. If an even port number is configured +to be the routing host port, the first port in the range must also be even. If an uneven port number is +configured to be the routing host port, the first port in the range must also be uneven. + +* `routing-credentials` (deprecated) + The UID / GID of the application acting as routing manager. (Must be specified if credentials checks are enabled using _check_credentials_ set to _true_ in order to successfully check the routing managers credentials passed on connect) @@ -1113,14 +1146,6 @@ Time which the stack collects new service offers before they enter the repetition phase. This can be used to reduce the number of sent messages during startup. The default setting is _500ms_. + - -** `max_remote_subscribers` -+ -Limit the number of possible remote subscribers from same remote IP address -to an eventgroup provided by a service/instance if the remote subscriber uses -different ports for its subscriptions. The default setting is _3_. -+ - //Watchdog * anchor:config-watchdog[]`watchdog` (optional) + @@ -1408,6 +1433,31 @@ They give a basic overview how to use the security related configuration tags de in this chapter to run a simple request/response or subscribe/notify example locally or remotely. + +Security policy extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +vsomeip policy extension configuration supports the definition of paths that contain additional +security policies to be loaded whenever a client with a yet unknown hostname connects to a local server endpoint. +The following configuration parameters are available and can be defined in a file named `vsomeip_policy_extensions.json`. + +// Security policy extension +* anchor:config-policy-extension[]`container_policies` (optional array) ++ +Specifies the additional configuration folders to be loaded for each container hostname / filesystem path pair. + +** `container` ++ +Specifies the linux hostname. + +** `path` ++ +Specifies a filesystem path (relative to vsomeip_policy_extensions.json or absolute) which contains +$UID_$GID subfolders that hold a `vsomeip_security.json` file. +Note: ($UID / $GID is the UID /GID of the vsomeip client application +to which a client from hostname defined with `container`connetcs to. + + Audit Mode ~~~~~~~~~~ vsomeip's security implementation can be put in a so called 'Audit Mode' where @@ -1551,7 +1601,7 @@ Service [source, bash] ---- -include::../examples/hello_world/hello_world_service.cpp[] +include::../examples/hello_world/hello_world_service_main.cpp[] ---- The service example results in the following program execution: @@ -1634,7 +1684,7 @@ Client ~~~~~~ [source, bash] ---- -include::../examples/hello_world/hello_world_client.cpp[] +include::../examples/hello_world/hello_world_client_main.cpp[] ---- The client example results in the following program execution: @@ -1829,17 +1879,17 @@ Example: ---- // get trace connector std::shared_ptr its_connector - = vsomeip::trace::connector::get(); + = vsomeip::trace::connector::get(); // add channel std::shared_ptr its_channel - = its_connector->create_channel("MC", "My channel"); + = its_connector->create_channel("MC", "My channel"); // add filter rule vsomeip::trace::match_t its_match = std::make_tuple(0x1234, 0xffff, 0x80e8); vsomeip::trace::filter_id_t its_filter_id - = its_channel->add_filter(its_match, true); + = its_channel->add_filter(its_match, true); // init trace connector its_connector->init(); diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4325dddfc..3ce54832c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - set(EXAMPLE_CONFIG_FILES "../config/vsomeip.json" "../config/vsomeip-local.json" diff --git a/examples/hello_world/Android.bp b/examples/hello_world/Android.bp index c7819c402..c095dc128 100644 --- a/examples/hello_world/Android.bp +++ b/examples/hello_world/Android.bp @@ -3,15 +3,15 @@ cc_defaults { vendor: true, cppflags: [ - "-std=c++11", + "-std=c++14", "-Wno-unused-parameter", ], shared_libs: [ "libvsomeip3", - "libvsomeip3-cfg", - "libvsomeip3-e2e", - "libvsomeip3-sd", + "libvsomeip_cfg", + "libvsomeip_e2e", + "libvsomeip_sd", "liblog", ], } @@ -33,10 +33,3 @@ cc_binary { "hello_world_client_main.cpp", ], } - -prebuilt_etc { - name: "helloworld-local.json", - vendor: true, - sub_dir: "vsomeip", - src: "helloworld-local.json", -} diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt index 44bd45d8c..d6e222df6 100644 --- a/examples/hello_world/CMakeLists.txt +++ b/examples/hello_world/CMakeLists.txt @@ -3,12 +3,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.7...3.23.2) +cmake_minimum_required (VERSION 2.8.7) project (vSomeIPHelloWorld) find_package(Threads REQUIRED) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(VSOMEIP_NAME "vsomeip3") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") include_directories(${VSOMEIP_INCLUDE_DIRS}) @@ -17,16 +19,17 @@ target_sources(vsomeip_hello_world_service INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/hello_world_service.hpp" ) target_include_directories(vsomeip_hello_world_service INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" ) add_library(vsomeip_hello_world_client INTERFACE) target_sources(vsomeip_hello_world_client INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/hello_world_client.hpp" ) + target_include_directories(vsomeip_hello_world_client INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}" - ) + "${CMAKE_CURRENT_SOURCE_DIR}" +) if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") # This will get us acces to diff --git a/examples/hello_world/readme b/examples/hello_world/readme index 1cb9d8fe7..afe92fda2 100644 --- a/examples/hello_world/readme +++ b/examples/hello_world/readme @@ -18,8 +18,11 @@ sudo make install 2. Build hello_world target ___________________________ -cmake --build . --target hello_world -cd ./examples/hello_world/ +cd /examples/hello_world$: + +mkdir build +cd build +cmake .. make Running Hello World Example diff --git a/examples/notify-sample.cpp b/examples/notify-sample.cpp index 0b9ed525f..2aafa9d1d 100644 --- a/examples/notify-sample.cpp +++ b/examples/notify-sample.cpp @@ -19,10 +19,9 @@ class service_sample { public: - service_sample(bool _use_tcp, uint32_t _cycle) : + service_sample(uint32_t _cycle) : app_(vsomeip::runtime::get()->create_application()), is_registered_(false), - use_tcp_(_use_tcp), cycle_(_cycle), blocked_(false), running_(true), @@ -166,12 +165,6 @@ class service_sample { } void notify() { - std::shared_ptr its_message - = vsomeip::runtime::get()->create_request(use_tcp_); - - its_message->set_service(SAMPLE_SERVICE_ID); - its_message->set_instance(SAMPLE_INSTANCE_ID); - its_message->set_method(SAMPLE_SET_METHOD_ID); vsomeip::byte_t its_data[10]; uint32_t its_size = 1; @@ -205,7 +198,6 @@ class service_sample { private: std::shared_ptr app_; bool is_registered_; - bool use_tcp_; uint32_t cycle_; std::mutex mutex_; @@ -235,23 +227,11 @@ class service_sample { #endif int main(int argc, char **argv) { - bool use_tcp = false; uint32_t cycle = 1000; // default 1s - std::string tcp_enable("--tcp"); - std::string udp_enable("--udp"); std::string cycle_arg("--cycle"); for (int i = 1; i < argc; i++) { - if (tcp_enable == argv[i]) { - use_tcp = true; - break; - } - if (udp_enable == argv[i]) { - use_tcp = false; - break; - } - if (cycle_arg == argv[i] && i + 1 < argc) { i++; std::stringstream converter; @@ -260,7 +240,7 @@ int main(int argc, char **argv) { } } - service_sample its_sample(use_tcp, cycle); + service_sample its_sample(cycle); #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING its_sample_ptr = &its_sample; signal(SIGINT, handle_signal); diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp index 96eadfddb..65d4b4cb9 100644 --- a/examples/request-sample.cpp +++ b/examples/request-sample.cpp @@ -64,7 +64,7 @@ class client_sample { std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload(); std::vector< vsomeip::byte_t > its_payload_data; for (std::size_t i = 0; i < 10; ++i) - its_payload_data.push_back(static_cast(i % 256)); + its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); request_->set_payload(its_payload); diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp index 8b3030232..6bd8ad26c 100644 --- a/examples/response-sample.cpp +++ b/examples/response-sample.cpp @@ -107,7 +107,7 @@ class service_sample { = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 120; ++i) - its_payload_data.push_back(static_cast(i % 256)); + its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); its_response->set_payload(its_payload); diff --git a/examples/routingmanagerd/CMakeLists.txt b/examples/routingmanagerd/CMakeLists.txt index 51504e5ea..e0d85aafb 100644 --- a/examples/routingmanagerd/CMakeLists.txt +++ b/examples/routingmanagerd/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - # Daemon add_executable(routingmanagerd routingmanagerd.cpp) target_link_libraries(routingmanagerd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${DL_LIBRARY} ${DLT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/routingmanagerd/routingmanagerd.cpp b/examples/routingmanagerd/routingmanagerd.cpp index b2118f6ff..7290808ff 100644 --- a/examples/routingmanagerd/routingmanagerd.cpp +++ b/examples/routingmanagerd/routingmanagerd.cpp @@ -16,8 +16,9 @@ #include #ifdef USE_DLT +#ifndef ANDROID #include - +#endif #endif static std::shared_ptr its_application; @@ -64,8 +65,10 @@ void routingmanagerd_stop(int _signal) { */ int routingmanagerd_process(bool _is_quiet) { #ifdef USE_DLT +#ifndef ANDROID if (!_is_quiet) DLT_REGISTER_APP(VSOMEIP_LOG_DEFAULT_APPLICATION_ID, VSOMEIP_LOG_DEFAULT_APPLICATION_NAME); +#endif #else (void)_is_quiet; #endif diff --git a/exportmap.gcc b/exportmap.gcc index a9a489ca7..8e8b99ba6 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -1,5 +1,5 @@ { -global: +global: extern "C++" { *vsomeip_v3::configuration; vsomeip_v3::configuration::*; @@ -25,6 +25,9 @@ global: *vsomeip_v3::payload_impl::*; *vsomeip_v3::policy_manager; vsomeip_v3::policy_manager::*; + *vsomeip_v3::policy_manager_impl; + vsomeip_v3::policy_manager_impl::*; + vsomeip_v3::security::authenticate_router; *vsomeip_v3::runtime; vsomeip_v3::runtime::get*; vsomeip_v3::runtime::set_property*; @@ -36,19 +39,13 @@ global: vsomeip_v3::eventgroupinfo::*; *vsomeip_v3::remote_subscription; vsomeip_v3::remote_subscription::*; - *vsomeip_v3::security; - vsomeip_v3::security::*; - *vsomeip_v3::security_impl; - vsomeip_v3::security_impl::*; - *vsomeip_v3::servicegroup; - vsomeip_v3::servicegroup::*; *vsomeip_v3::serviceinfo; vsomeip_v3::serviceinfo::*; *vsomeip_v3::sd::runtime; vsomeip_v3::sd::runtime::*; *vsomeip_v3::utility; vsomeip_v3::utility::is*; - vsomeip_v3::utility::parse*; + vsomeip_v3::utility::data*; *vsomeip_v3::plugin_manager; vsomeip_v3::plugin_manager::*; vsomeip_v3::tp::tp_reassembler::*; @@ -60,7 +57,7 @@ global: *vsomeip::runtime; vsomeip::logger::*; *vsomeip::logger; - }; + }; vsomeip_plugin_init; local: *; diff --git a/implementation/compat/runtime/src/application_impl.cpp b/implementation/compat/runtime/src/application_impl.cpp index ce6513693..f1934e446 100644 --- a/implementation/compat/runtime/src/application_impl.cpp +++ b/implementation/compat/runtime/src/application_impl.cpp @@ -638,7 +638,7 @@ application_impl::is_selective_event( if (its_service != eventgroups_.end()) { const auto its_instance = its_service->second.find(_instance); if (its_instance != its_service->second.end()) { - for (const auto& eg : _eventgroups) { + for (const auto eg : _eventgroups) { const auto its_egrp = its_instance->second.find(eg); if (its_egrp != its_instance->second.end()) { is_selective = true; diff --git a/implementation/configuration/include/application_configuration.hpp b/implementation/configuration/include/application_configuration.hpp new file mode 100644 index 000000000..f20afd524 --- /dev/null +++ b/implementation/configuration/include/application_configuration.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ +#define VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ + +#include +#include + +#include +#include + +#ifdef ANDROID +#include "internal_android.hpp" +#else +#include "internal.hpp" +#endif + +namespace vsomeip_v3 { + +struct debounce_filter_t; + +namespace cfg { + +struct application_configuration { + client_t client_; + std::size_t max_dispatchers_; + std::size_t max_dispatch_time_; + std::size_t thread_count_; + std::size_t request_debouncing_; + std::map > plugins_; + int nice_level_; + debounce_configuration_t debounces_; + bool has_session_handling_; +}; + +} // namespace cfg +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ diff --git a/implementation/configuration/include/client.hpp b/implementation/configuration/include/client.hpp index 872974ff3..5c0805dda 100644 --- a/implementation/configuration/include/client.hpp +++ b/implementation/configuration/include/client.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index e107e1734..ef597e13d 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,13 @@ #include #include #include +#include #include "trace.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" #include "e2e.hpp" -#include "debounce.hpp" #ifdef ANDROID #include "internal_android.hpp" @@ -40,6 +40,7 @@ namespace vsomeip_v3 { class event; +struct debounce_filter_t; class configuration { public: @@ -51,6 +52,9 @@ class configuration { #endif virtual bool load(const std::string &_name) = 0; +#ifndef VSOMEIP_DISABLE_SECURITY + virtual bool lazy_load_security(const std::string &_client_host) = 0; +#endif // !VSOMEIP_DISABLE_SECURITY virtual bool remote_offer_info_add(service_t _service, instance_t _instance, std::uint16_t _port, @@ -67,6 +71,7 @@ class configuration { virtual const boost::asio::ip::address & get_unicast_address() const = 0; virtual const boost::asio::ip::address& get_netmask() const = 0; + virtual unsigned short get_prefix() const = 0; virtual const std::string &get_device() const = 0; virtual diagnosis_t get_diagnosis_address() const = 0; virtual diagnosis_t get_diagnosis_mask() const = 0; @@ -76,34 +81,35 @@ class configuration { virtual bool has_console_log() const = 0; virtual bool has_file_log() const = 0; virtual bool has_dlt_log() const = 0; - virtual const std::string & get_logfile() const = 0; + virtual const std::string &get_logfile() const = 0; virtual logger::level_e get_loglevel() const = 0; - virtual const std::string & get_routing_host() const = 0; + virtual bool is_routing_enabled() const = 0; + virtual const std::string &get_routing_host_name() const = 0; + virtual const boost::asio::ip::address &get_routing_host_address() const = 0; + virtual port_t get_routing_host_port() const = 0; + + virtual const boost::asio::ip::address &get_routing_guest_address() const = 0; + virtual std::set > get_routing_guest_ports() const = 0; + + virtual bool is_local_routing() const = 0; virtual std::string get_unicast_address(service_t _service, instance_t _instance) const = 0; virtual uint16_t get_reliable_port(service_t _service, instance_t _instance) const = 0; - virtual bool has_enabled_magic_cookies(std::string _address, + virtual bool has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const = 0; virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0; - virtual major_version_t get_major_version(service_t _service, - instance_t _instance) const = 0; - virtual minor_version_t get_minor_version(service_t _service, - instance_t _instance) const = 0; - virtual ttl_t get_ttl(service_t _service, - instance_t _instance) const = 0; - virtual void get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const = 0; virtual void get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const = 0; @@ -122,6 +128,11 @@ class configuration { virtual uint8_t get_threshold(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const = 0; + virtual void get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change_) const = 0; + virtual client_t get_id(const std::string &_name) const = 0; virtual bool is_configured_client_id(client_t _id) const = 0; @@ -130,9 +141,7 @@ class configuration { virtual std::size_t get_io_thread_count(const std::string &_name) const = 0; virtual int get_io_thread_nice_level(const std::string &_name) const = 0; virtual std::size_t get_request_debouncing(const std::string &_name) const = 0; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG virtual bool has_session_handling(const std::string &_name) const = 0; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG virtual std::uint32_t get_max_message_size_local() const = 0; virtual std::uint32_t get_max_message_size_reliable(const std::string& _address, @@ -140,7 +149,7 @@ class configuration { virtual std::uint32_t get_max_message_size_unreliable() const = 0; virtual std::uint32_t get_buffer_shrink_threshold() const = 0; - virtual bool supports_selective_broadcasts(boost::asio::ip::address _address) const = 0; + virtual bool supports_selective_broadcasts(const boost::asio::ip::address &_address) const = 0; virtual bool is_offered_remote(service_t _service, instance_t _instance) const = 0; @@ -188,6 +197,10 @@ class configuration { virtual void set_configuration_path(const std::string &_path) = 0; + virtual std::map get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name) = 0; + //E2E virtual std::map> get_e2e_configuration() const = 0; virtual bool is_e2e_enabled() const = 0; @@ -199,17 +212,18 @@ class configuration { virtual uint32_t get_log_status_interval() const = 0; // TTL factor - typedef std::uint32_t ttl_factor_t; - typedef std::map> ttl_map_t; + using ttl_factor_t = std::uint32_t; + using ttl_map_t = std::map>; virtual ttl_map_t get_ttl_factor_offers() const = 0; virtual ttl_map_t get_ttl_factor_subscribes() const = 0; // Debouncing - virtual std::shared_ptr get_debounce( + virtual std::shared_ptr get_debounce( + const std::string &_name, service_t _service, instance_t _instance, event_t _event) const = 0; // Queue size limit endpoints - typedef std::uint32_t endpoint_queue_limit_t; + using endpoint_queue_limit_t = std::uint32_t; virtual endpoint_queue_limit_t get_endpoint_queue_limit( const std::string& _address, std::uint16_t _port) const = 0; virtual endpoint_queue_limit_t get_endpoint_queue_limit_local() const = 0; @@ -227,13 +241,13 @@ class configuration { const boost::asio::ip::address& _address, std::uint16_t _port, bool _reliable) const = 0; - typedef std::pair port_range_t; + using port_range_t = std::pair; virtual void set_sd_acceptance_rule( const boost::asio::ip::address &_address, port_range_t _port_range, port_type_e _type, const std::string &_path, bool _reliable, bool _enable, bool _default) = 0; - typedef std::map< + using sd_acceptance_rules_t = std::map< boost::asio::ip::address, // other device std::pair< std::string, // path to file that determines whether or not IPsec is active @@ -245,9 +259,7 @@ class configuration { > > > - > sd_acceptance_rules_t; - virtual void set_sd_acceptance_rules(const sd_acceptance_rules_t& _rules, - bool _enable) = 0; + >; virtual sd_acceptance_rules_t get_sd_acceptance_rules() = 0; virtual void set_sd_acceptance_rules_active( const boost::asio::ip::address& _address, bool _enable) = 0; @@ -256,15 +268,19 @@ class configuration { virtual int get_udp_receive_buffer_size() const = 0; - virtual bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const = 0; + virtual bool check_routing_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) const = 0; // SOME/IP-TP - virtual bool tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, - std::uint16_t _port_target, method_t _method) const = 0; - virtual bool tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, - std::uint16_t _port_service, method_t _method) const = 0; + virtual bool is_tp_client( + service_t _service, const std::string &_address, std::uint16_t _port, + method_t _method) const = 0; + virtual bool is_tp_service( + service_t _service, const std::string &_address, std::uint16_t _port, + method_t _method) const = 0; + virtual void get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const = 0; // routing shutdown timeout virtual std::uint32_t get_shutdown_timeout() const = 0; @@ -278,6 +294,17 @@ class configuration { virtual partition_id_t get_partition_id( service_t _service, instance_t _instance) const = 0; + + virtual reliability_type_e get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const = 0; + + // security + virtual bool is_security_enabled() const = 0; + virtual bool is_security_audit() const = 0; + virtual bool is_remote_access_allowed() const = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_element.hpp b/implementation/configuration/include/configuration_element.hpp index 7daf9d7a6..2b650e32a 100644 --- a/implementation/configuration/include/configuration_element.hpp +++ b/implementation/configuration/include/configuration_element.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,6 +16,16 @@ struct configuration_element { std::string name_; boost::property_tree::ptree tree_; + configuration_element(const std::string &_name, const boost::property_tree::ptree &_tree) noexcept + : name_(_name), + tree_(_tree) { + } + + configuration_element(configuration_element &&_source) noexcept + : name_(std::move(_source.name_)), + tree_(std::move(_source.tree_)) { + } + bool operator<(const configuration_element &_other) const { return (name_ < _other.name_); } diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index cb6c2846a..9ae1c793e 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,26 +6,30 @@ #ifndef VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP #define VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP +#include #include #include #include -#include #include -#include +#include #include -#include "trace.hpp" +#include "application_configuration.hpp" #include "configuration.hpp" #include "configuration_element.hpp" +#include "e2e.hpp" +#include "routing.hpp" #include "watchdog.hpp" #include "service_instance_range.hpp" +#include "trace.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" -#include "e2e.hpp" -#include "debounce.hpp" #include "../../security/include/policy.hpp" namespace vsomeip_v3 { + +struct debounce_filter_t; + namespace cfg { struct client; @@ -39,11 +43,14 @@ class configuration_impl: public configuration, public std::enable_shared_from_this { public: - VSOMEIP_EXPORT configuration_impl(); + VSOMEIP_EXPORT configuration_impl(const std::string &_path); VSOMEIP_EXPORT configuration_impl(const configuration_impl &_other); VSOMEIP_EXPORT virtual ~configuration_impl(); VSOMEIP_EXPORT bool load(const std::string &_name); +#ifndef VSOMEIP_DISABLE_SECURITY + VSOMEIP_EXPORT bool lazy_load_security(const std::string &_client_host); +#endif // !VSOMEIP_DISABLE_SECURITY VSOMEIP_EXPORT bool remote_offer_info_add(service_t _service, instance_t _instance, std::uint16_t _port, @@ -62,6 +69,7 @@ class configuration_impl: VSOMEIP_EXPORT const boost::asio::ip::address & get_unicast_address() const; VSOMEIP_EXPORT const boost::asio::ip::address& get_netmask() const; + VSOMEIP_EXPORT unsigned short get_prefix() const; VSOMEIP_EXPORT const std::string &get_device() const; VSOMEIP_EXPORT unsigned short get_diagnosis_address() const; VSOMEIP_EXPORT std::uint16_t get_diagnosis_mask() const; @@ -77,24 +85,17 @@ class configuration_impl: VSOMEIP_EXPORT std::string get_unicast_address(service_t _service, instance_t _instance) const; VSOMEIP_EXPORT uint16_t get_reliable_port(service_t _service, instance_t _instance) const; - VSOMEIP_EXPORT bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const; + VSOMEIP_EXPORT bool has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const; VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; - VSOMEIP_EXPORT major_version_t get_major_version(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT minor_version_t get_minor_version(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT ttl_t get_ttl(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT void get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const; VSOMEIP_EXPORT void get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const; @@ -105,7 +106,15 @@ class configuration_impl: uint16_t _remote_port, bool _reliable, std::map > &_used_client_ports, uint16_t &_client_port) const; - VSOMEIP_EXPORT const std::string & get_routing_host() const; + VSOMEIP_EXPORT bool is_routing_enabled() const; + VSOMEIP_EXPORT bool is_local_routing() const; + + VSOMEIP_EXPORT const std::string &get_routing_host_name() const; + VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_host_address() const; + VSOMEIP_EXPORT port_t get_routing_host_port() const; + + VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_guest_address() const; + VSOMEIP_EXPORT std::set > get_routing_guest_ports() const; VSOMEIP_EXPORT client_t get_id(const std::string &_name) const; VSOMEIP_EXPORT bool is_configured_client_id(client_t _id) const; @@ -125,13 +134,18 @@ class configuration_impl: VSOMEIP_EXPORT uint8_t get_threshold(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; + VSOMEIP_EXPORT void get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change_) const; + VSOMEIP_EXPORT std::uint32_t get_max_message_size_local() const; VSOMEIP_EXPORT std::uint32_t get_max_message_size_reliable(const std::string& _address, std::uint16_t _port) const; VSOMEIP_EXPORT std::uint32_t get_max_message_size_unreliable() const; VSOMEIP_EXPORT std::uint32_t get_buffer_shrink_threshold() const; - VSOMEIP_EXPORT bool supports_selective_broadcasts(boost::asio::ip::address _address) const; + VSOMEIP_EXPORT bool supports_selective_broadcasts(const boost::asio::ip::address &_address) const; VSOMEIP_EXPORT bool is_offered_remote(service_t _service, instance_t _instance) const; @@ -172,7 +186,8 @@ class configuration_impl: VSOMEIP_EXPORT std::uint32_t get_permissions_uds() const; VSOMEIP_EXPORT std::uint32_t get_permissions_shm() const; - VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; + VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) const; VSOMEIP_EXPORT std::map> get_plugins( const std::string &_name) const; @@ -189,7 +204,8 @@ class configuration_impl: VSOMEIP_EXPORT ttl_map_t get_ttl_factor_offers() const; VSOMEIP_EXPORT ttl_map_t get_ttl_factor_subscribes() const; - VSOMEIP_EXPORT std::shared_ptr get_debounce( + VSOMEIP_EXPORT std::shared_ptr get_debounce( + const std::string &_name, service_t _service, instance_t _instance, event_t _event) const; VSOMEIP_EXPORT endpoint_queue_limit_t get_endpoint_queue_limit( @@ -222,15 +238,16 @@ class configuration_impl: VSOMEIP_EXPORT int get_udp_receive_buffer_size() const; - VSOMEIP_EXPORT bool has_overlay(const std::string &_name) const; - VSOMEIP_EXPORT void load_overlay(const std::string &_name); - - VSOMEIP_EXPORT bool tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, - std::uint16_t _port_target, method_t _method) const; - VSOMEIP_EXPORT bool tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, + VSOMEIP_EXPORT bool is_tp_client( + service_t _service, + const std::string &_address, std::uint16_t _port, + method_t _method) const; + VSOMEIP_EXPORT bool is_tp_service( + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method) const; + VSOMEIP_EXPORT void get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const; VSOMEIP_EXPORT std::uint32_t get_shutdown_timeout() const; @@ -244,19 +261,36 @@ class configuration_impl: VSOMEIP_EXPORT partition_id_t get_partition_id( service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT std::map get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name); + + VSOMEIP_EXPORT reliability_type_e get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const; + + VSOMEIP_EXPORT bool is_security_enabled() const; + VSOMEIP_EXPORT bool is_security_audit() const; + VSOMEIP_EXPORT bool is_remote_access_allowed() const; + private: void read_data(const std::set &_input, + std::vector &_elements, + std::set &_failed, + bool _mandatory_only, bool _read_second_level = false); +#ifndef VSOMEIP_DISABLE_POLICY + void load_policy_data(const std::string &_input, std::vector &_elements, std::set &_failed, bool _mandatory_only); - +#endif // !VSOMEIP_DISABLE_POLICY bool load_data(const std::vector &_elements, bool _load_mandatory, bool _load_optional); bool load_logging(const configuration_element &_element, std::set &_warnings); - bool load_routing(const configuration_element &_element); - bool load_routing_credentials(const configuration_element &_element); bool load_applications(const configuration_element &_element); void load_application_data(const boost::property_tree::ptree &_tree, @@ -264,7 +298,7 @@ class configuration_impl: std::map> load_plugins( const boost::property_tree::ptree &_tree, - const std::string& _application_name); + const std::string &_application_name); struct plugin_config_data_t { std::string name_; @@ -275,6 +309,15 @@ class configuration_impl: const plugin_config_data_t &_plugin_data, const std::string& _application_name); + bool load_routing(const configuration_element &_element); + bool load_routing_host(const boost::property_tree::ptree &_tree, + const std::string &_name); + bool load_routing_guests(const boost::property_tree::ptree &_tree); + void load_routing_guest_ports(const boost::property_tree::ptree &_tree); + + bool load_routing_credentials(const configuration_element &_element); // compatibility + void load_routing_client_ports(const configuration_element &_element); // compatibility + void load_tracing(const configuration_element &_element); void load_trace_channels(const boost::property_tree::ptree &_tree); void load_trace_channel(const boost::property_tree::ptree &_tree); @@ -327,11 +370,12 @@ class configuration_impl: void load_selective_broadcasts_support(const configuration_element &_element); void load_debounce(const configuration_element &_element); - void load_service_debounce(const boost::property_tree::ptree &_tree); + void load_service_debounce(const boost::property_tree::ptree &_tree, + debounce_configuration_t &_debounces); void load_events_debounce(const boost::property_tree::ptree &_tree, - std::map> &_debounces); + std::map > &_debounces); void load_event_debounce(const boost::property_tree::ptree &_tree, - std::map> &_debounces); + std::map > &_debounces); void load_event_debounce_ignore(const boost::property_tree::ptree &_tree, std::map &_ignore); void load_acceptances(const configuration_element &_element); @@ -354,8 +398,8 @@ class configuration_impl: instance_t _instance) const; std::shared_ptr find_service(service_t _service, instance_t _instance) const; std::shared_ptr find_service_unlocked(service_t _service, instance_t _instance) const; - service * find_service_by_ip_port(service_t _service, const std::string& _ip, - std::uint16_t _port) const; + std::shared_ptr find_service(service_t _service, + const std::string &_address, std::uint16_t _port) const; std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; bool find_port(uint16_t &_port, uint16_t _remote, bool _reliable, @@ -396,7 +440,6 @@ class configuration_impl: const std::string default_unicast_; bool is_loaded_; bool is_logging_loaded_; - bool is_overlay_; std::set mandatory_; @@ -404,6 +447,7 @@ class configuration_impl: // Configuration data boost::asio::ip::address unicast_; boost::asio::ip::address netmask_; + unsigned short prefix_; std::string device_; diagnosis_t diagnosis_; diagnosis_t diagnosis_mask_; @@ -414,23 +458,9 @@ class configuration_impl: std::string logfile_; vsomeip_v3::logger::level_e loglevel_; - std::map - >, // plugins - int, // nice level - std::string // overlay -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , bool // has session handling? -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - > + std::map< + std::string, + application_configuration > applications_; std::set client_identifiers_; @@ -446,7 +476,7 @@ class configuration_impl: std::list< std::shared_ptr > clients_; - std::string routing_host_; + routing_t routing_; bool is_sd_enabled_; std::string sd_protocol_; @@ -523,11 +553,12 @@ class configuration_impl: ET_NPDU_DEFAULT_TIMINGS, ET_PLUGIN_NAME, ET_PLUGIN_TYPE, - ET_ROUTING_CREDENTIALS, ET_SHUTDOWN_TIMEOUT, ET_MAX_REMOTE_SUBSCRIBERS, ET_PARTITIONS, - ET_MAX = 44 + ET_SECURITY_AUDIT_MODE, + ET_SECURITY_REMOTE_ACCESS, + ET_MAX = 45 }; bool is_configured_[ET_MAX]; @@ -549,7 +580,7 @@ class configuration_impl: ttl_map_t ttl_factors_offers_; ttl_map_t ttl_factors_subscriptions_; - std::map>>> debounces_; + debounce_configuration_t debounces_; std::map> endpoint_queue_limits_; endpoint_queue_limit_t endpoint_queue_limit_external_; @@ -581,6 +612,7 @@ class configuration_impl: uint32_t statistics_interval_; uint32_t statistics_min_freq_; uint32_t statistics_max_messages_; + uint8_t max_remote_subscribers_; mutable std::mutex partitions_mutex_; @@ -589,6 +621,20 @@ class configuration_impl: partition_id_t > > partitions_; + + std::string path_; + + std::map + > + > plugins_additional_; + + bool is_security_enabled_; + bool is_security_audit_; + bool is_remote_access_allowed_; }; } // namespace cfg diff --git a/implementation/configuration/include/configuration_plugin.hpp b/implementation/configuration/include/configuration_plugin.hpp index 583c3d8e0..3ffc9683b 100644 --- a/implementation/configuration/include/configuration_plugin.hpp +++ b/implementation/configuration/include/configuration_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,13 +17,9 @@ class configuration; class configuration_plugin { public: - virtual ~configuration_plugin() -#ifndef ANDROID - {} -#else - ; -#endif - virtual std::shared_ptr get_configuration(const std::string &_name) = 0; + virtual ~configuration_plugin() = default; + virtual std::shared_ptr get_configuration( + const std::string &_name, const std::string &_path) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_plugin_impl.hpp b/implementation/configuration/include/configuration_plugin_impl.hpp index fd956282b..3fcfbefcd 100644 --- a/implementation/configuration/include/configuration_plugin_impl.hpp +++ b/implementation/configuration/include/configuration_plugin_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -27,14 +27,15 @@ class configuration_plugin_impl configuration_plugin_impl(); virtual ~configuration_plugin_impl(); - std::shared_ptr get_configuration(const std::string &_name); + std::shared_ptr get_configuration(const std::string &_name, + const std::string &_path); private: std::mutex mutex_; std::shared_ptr default_; -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +#if 0 std::map > configurations_; -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/debounce.hpp b/implementation/configuration/include/debounce.hpp index dc6151460..30ad9848e 100644 --- a/implementation/configuration/include/debounce.hpp +++ b/implementation/configuration/include/debounce.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,7 +21,7 @@ namespace cfg { struct debounce { debounce() : on_change_(false), on_change_resets_interval_(false), - interval_(0), + interval_(-1), // aka "never" last_forwarded_((std::chrono::steady_clock::time_point::max)()) { } diff --git a/implementation/configuration/include/e2e.hpp b/implementation/configuration/include/e2e.hpp index 705c92da6..8345c2a94 100644 --- a/implementation/configuration/include/e2e.hpp +++ b/implementation/configuration/include/e2e.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,7 +16,7 @@ namespace vsomeip_v3 { namespace cfg { struct e2e { - typedef std::map custom_parameters_t; + using custom_parameters_t = std::map>; e2e() : variant(""), @@ -25,7 +25,7 @@ struct e2e { event_id(0) { } - e2e(std::string _variant, std::string _profile, service_t _service_id, + e2e(const std::string &_variant, const std::string &_profile, service_t _service_id, event_t _event_id, custom_parameters_t&& _custom_parameters) : variant(_variant), profile(_profile), diff --git a/implementation/configuration/include/event.hpp b/implementation/configuration/include/event.hpp index 84dc5a083..1e35a85f0 100644 --- a/implementation/configuration/include/event.hpp +++ b/implementation/configuration/include/event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,18 +17,25 @@ namespace cfg { struct eventgroup; struct event { - event(event_t _id) + event(event_t _id, bool _is_field, reliability_type_e _reliability, + std::chrono::milliseconds _cycle, bool _change_resets_cycle, + bool _update_on_change) : id_(_id), - is_placeholder_(true), - is_field_(false), - reliability_(reliability_type_e::RT_UNRELIABLE) { + is_field_(_is_field), + reliability_(_reliability), + cycle_(_cycle), + change_resets_cycle_(_change_resets_cycle), + update_on_change_(_update_on_change) { } event_t id_; - bool is_placeholder_; bool is_field_; reliability_type_e reliability_; std::vector > groups_; + + std::chrono::milliseconds cycle_; + bool change_resets_cycle_; + bool update_on_change_; }; } // namespace cfg diff --git a/implementation/configuration/include/eventgroup.hpp b/implementation/configuration/include/eventgroup.hpp index 1402b514f..328a02db7 100644 --- a/implementation/configuration/include/eventgroup.hpp +++ b/implementation/configuration/include/eventgroup.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index efd9ba0e5..91cd1ee73 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,10 @@ #include #include +#include + #include +#include #define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" @@ -20,7 +23,7 @@ #define VSOMEIP_DEFAULT_CONFIGURATION_FILE "@DEFAULT_CONFIGURATION_FILE@" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_events.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json" #define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "@DEFAULT_CONFIGURATION_FOLDER@" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" @@ -28,6 +31,8 @@ #define VSOMEIP_BASE_PATH "@VSOMEIP_BASE_PATH@/" +#define VSOMEIP_ROUTING_HOST_PORT_DEFAULT 31490 + #ifdef _WIN32 #define VSOMEIP_CFG_LIBRARY "vsomeip3-cfg.dll" #else @@ -46,6 +51,12 @@ #define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so.@VSOMEIP_MAJOR_VERSION@" #endif +#ifdef _WIN32 +#define VSOMEIP_SEC_LIBRARY "vsomeip3-sec.dll" +#else +#define VSOMEIP_SEC_LIBRARY "libvsomeip3-sec.so" +#endif + #define VSOMEIP_ROUTING_CLIENT 0 #define VSOMEIP_CLIENT_UNSET 0xFFFF @@ -57,9 +68,11 @@ #define VSOMEIP_UNICAST_ADDRESS "@VSOMEIP_UNICAST_ADDRESS@" #define VSOMEIP_NETMASK "255.255.255.0" +#define VSOMEIP_PREFIX 24 #define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 #define VSOMEIP_MAX_CONNECT_TIMEOUT 1600 +#define VSOMEIP_DEFAULT_CONNECTING_TIMEOUT 100 #define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 #define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 @@ -70,6 +83,8 @@ #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 #define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 +#define VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT 1392 + #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 #define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000 @@ -92,93 +107,12 @@ #define VSOMEIP_MAX_WAIT_SENT 5 -#define VSOMEIP_COMMAND_HEADER_SIZE 7 - -#define VSOMEIP_COMMAND_TYPE_POS 0 -#define VSOMEIP_COMMAND_CLIENT_POS 1 -#define VSOMEIP_COMMAND_SIZE_POS_MIN 3 -#define VSOMEIP_COMMAND_SIZE_POS_MAX 6 -#define VSOMEIP_COMMAND_PAYLOAD_POS 7 - -#define VSOMEIP_ASSIGN_CLIENT 0x00 -#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 -#define VSOMEIP_REGISTER_APPLICATION 0x02 -#define VSOMEIP_DEREGISTER_APPLICATION 0x03 -#define VSOMEIP_APPLICATION_LOST 0x04 -#define VSOMEIP_ROUTING_INFO 0x05 -#define VSOMEIP_REGISTERED_ACK 0x06 - -#define VSOMEIP_PING 0x0E -#define VSOMEIP_PONG 0x0F - -#define VSOMEIP_OFFER_SERVICE 0x10 -#define VSOMEIP_STOP_OFFER_SERVICE 0x11 -#define VSOMEIP_SUBSCRIBE 0x12 -#define VSOMEIP_UNSUBSCRIBE 0x13 -#define VSOMEIP_REQUEST_SERVICE 0x14 -#define VSOMEIP_RELEASE_SERVICE 0x15 -#define VSOMEIP_SUBSCRIBE_NACK 0x16 -#define VSOMEIP_SUBSCRIBE_ACK 0x17 - -#define VSOMEIP_SEND 0x18 -#define VSOMEIP_NOTIFY 0x19 -#define VSOMEIP_NOTIFY_ONE 0x1A - -#define VSOMEIP_REGISTER_EVENT 0x1B -#define VSOMEIP_UNREGISTER_EVENT 0x1C -#define VSOMEIP_ID_RESPONSE 0x1D -#define VSOMEIP_ID_REQUEST 0x1E -#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F -#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 -#define VSOMEIP_UNSUBSCRIBE_ACK 0x21 -#define VSOMEIP_RESEND_PROVIDED_EVENTS 0x22 - -#define VSOMEIP_UPDATE_SECURITY_POLICY 0x23 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE 0x24 -#define VSOMEIP_REMOVE_SECURITY_POLICY 0x25 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE 0x26 -#define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 -#define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 -#define VSOMEIP_UPDATE_SECURITY_POLICY_INT 0x29 -#define VSOMEIP_EXPIRED_SUBSCRIPTION 0x2A - -#define VSOMEIP_SUSPEND 0x30 - -#define VSOMEIP_SEND_COMMAND_SIZE 13 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 -#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 -#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 -#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 - -#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 -#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 -#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 -#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 -#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 -#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 -#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 -#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 -#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 -#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 -#define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_PING_COMMAND_SIZE 7 -#define VSOMEIP_PONG_COMMAND_SIZE 7 -#define VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_REGISTERED_ACK_COMMAND_SIZE 7 -#define VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE 17 - - -#ifndef _WIN32 +#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE 19 + +#define VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT 100 +#define VSOMEIP_SETSOCKOPT_TIMEOUT_US 500000 // microseconds + +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -192,31 +126,11 @@ namespace vsomeip_v3 { -typedef enum { - RIE_ADD_CLIENT = 0x0, - RIE_ADD_SERVICE_INSTANCE = 0x1, - RIE_DEL_SERVICE_INSTANCE = 0x2, - RIE_DEL_CLIENT = 0x3, -} routing_info_entry_e; - -struct service_data_t { - service_t service_; - instance_t instance_; - major_version_t major_; - minor_version_t minor_; - - bool operator<(const service_data_t &_other) const { - return (service_ < _other.service_ - || (service_ == _other.service_ - && instance_ < _other.instance_)); - } -}; - -typedef enum { +enum class subscription_state_e { SUBSCRIPTION_ACKNOWLEDGED, SUBSCRIPTION_NOT_ACKNOWLEDGED, IS_SUBSCRIBING -} subscription_state_e; +}; const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits::max)(); @@ -230,8 +144,6 @@ const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits credentials_t; - enum class port_type_e { PT_OPTIONAL, PT_SECURE, @@ -239,7 +151,11 @@ enum class port_type_e { PT_UNKNOWN }; -typedef uint8_t partition_id_t; +using debounce_configuration_t = + std::map>>>; + +using partition_id_t = std::uint8_t; const partition_id_t VSOMEIP_DEFAULT_PARTITION_ID = 0; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp index 8ecd2b595..1efa0faea 100644 --- a/implementation/configuration/include/internal_android.hpp +++ b/implementation/configuration/include/internal_android.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,10 @@ #include #include +#include + #include +#include #define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" @@ -17,33 +20,41 @@ #define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES" #define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS" #define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING" -#define VSOMEIP_ENV_BASE_PATH "VSOMEIP_BASE_PATH" -#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/vendor/etc/vsomeip.json" +#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/vendor/run/etc/vsomeip.json" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json" -#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/vendor/etc/vsomeip" +#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/vendor/run/etc/vsomeip" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" #define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip" -#define VSOMEIP_BASE_PATH "/storage/" +// VSOMEIP_BASE_PATH should be specified in Android.bp or/and Android.mk file via c/c++ compiler flags. +// #define VSOMEIP_BASE_PATH "/storage/" + +#define VSOMEIP_ROUTING_HOST_PORT_DEFAULT 31490 + +#define VSOMEIP_CFG_LIBRARY "libvsomeip_cfg.so" -#define VSOMEIP_CFG_LIBRARY "libvsomeip3-cfg.so" +#define VSOMEIP_SD_LIBRARY "libvsomeip_sd.so" -#define VSOMEIP_SD_LIBRARY "libvsomeip3-sd.so" +#define VSOMEIP_E2E_LIBRARY "libvsomeip_e2e.so" -#define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so" +#define VSOMEIP_SEC_LIBRARY "libvsomeip_sec.so" +#define VSOMEIP_ROUTING "vsomeipd" #define VSOMEIP_ROUTING_CLIENT 0 +#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256 #define VSOMEIP_CLIENT_UNSET 0xFFFF #define VSOMEIP_UNICAST_ADDRESS "127.0.0.1" #define VSOMEIP_NETMASK "255.255.255.0" +#define VSOMEIP_PREFIX 24 #define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 #define VSOMEIP_MAX_CONNECT_TIMEOUT 1600 +#define VSOMEIP_DEFAULT_CONNECTING_TIMEOUT 100 #define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 #define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 @@ -54,6 +65,8 @@ #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 #define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 +#define VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT 1392 + #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 #define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000 @@ -76,90 +89,10 @@ #define VSOMEIP_MAX_WAIT_SENT 5 -#define VSOMEIP_COMMAND_HEADER_SIZE 7 - -#define VSOMEIP_COMMAND_TYPE_POS 0 -#define VSOMEIP_COMMAND_CLIENT_POS 1 -#define VSOMEIP_COMMAND_SIZE_POS_MIN 3 -#define VSOMEIP_COMMAND_SIZE_POS_MAX 6 -#define VSOMEIP_COMMAND_PAYLOAD_POS 7 - -#define VSOMEIP_ASSIGN_CLIENT 0x00 -#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 -#define VSOMEIP_REGISTER_APPLICATION 0x02 -#define VSOMEIP_DEREGISTER_APPLICATION 0x03 -#define VSOMEIP_APPLICATION_LOST 0x04 -#define VSOMEIP_ROUTING_INFO 0x05 -#define VSOMEIP_REGISTERED_ACK 0x06 - -#define VSOMEIP_PING 0x0E -#define VSOMEIP_PONG 0x0F - -#define VSOMEIP_OFFER_SERVICE 0x10 -#define VSOMEIP_STOP_OFFER_SERVICE 0x11 -#define VSOMEIP_SUBSCRIBE 0x12 -#define VSOMEIP_UNSUBSCRIBE 0x13 -#define VSOMEIP_REQUEST_SERVICE 0x14 -#define VSOMEIP_RELEASE_SERVICE 0x15 -#define VSOMEIP_SUBSCRIBE_NACK 0x16 -#define VSOMEIP_SUBSCRIBE_ACK 0x17 - -#define VSOMEIP_SEND 0x18 -#define VSOMEIP_NOTIFY 0x19 -#define VSOMEIP_NOTIFY_ONE 0x1A - -#define VSOMEIP_REGISTER_EVENT 0x1B -#define VSOMEIP_UNREGISTER_EVENT 0x1C -#define VSOMEIP_ID_RESPONSE 0x1D -#define VSOMEIP_ID_REQUEST 0x1E -#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F -#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 -#define VSOMEIP_UNSUBSCRIBE_ACK 0x21 -#define VSOMEIP_RESEND_PROVIDED_EVENTS 0x22 - -#define VSOMEIP_UPDATE_SECURITY_POLICY 0x23 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE 0x24 -#define VSOMEIP_REMOVE_SECURITY_POLICY 0x25 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE 0x26 -#define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 -#define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 -#define VSOMEIP_UPDATE_SECURITY_POLICY_INT 0x29 -#define VSOMEIP_EXPIRED_SUBSCRIPTION 0x2A - -#define VSOMEIP_SUSPEND 0x30 - -#define VSOMEIP_SEND_COMMAND_SIZE 13 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 -#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 -#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 -#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 - -#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 -#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 -#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 -#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 -#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 -#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 -#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 -#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 -#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 -#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 -#define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_PING_COMMAND_SIZE 7 -#define VSOMEIP_PONG_COMMAND_SIZE 7 -#define VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_REGISTERED_ACK_COMMAND_SIZE 7 -#define VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE 17 +#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE 19 + +#define VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT 100 +#define VSOMEIP_SETSOCKOPT_TIMEOUT_US 500000 // microseconds #include @@ -180,19 +113,6 @@ typedef enum { RIE_DEL_CLIENT = 0x3, } routing_info_entry_e; -struct service_data_t { - service_t service_; - instance_t instance_; - major_version_t major_; - minor_version_t minor_; - - bool operator<(const service_data_t &_other) const { - return (service_ < _other.service_ - || (service_ == _other.service_ - && instance_ < _other.instance_)); - } -}; - typedef enum { SUBSCRIPTION_ACKNOWLEDGED, SUBSCRIPTION_NOT_ACKNOWLEDGED, @@ -211,8 +131,6 @@ const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits credentials_t; - enum class port_type_e { PT_OPTIONAL, PT_SECURE, @@ -220,6 +138,14 @@ enum class port_type_e { PT_UNKNOWN }; +typedef std::map + > + > +> debounce_configuration_t; + typedef uint8_t partition_id_t; const partition_id_t VSOMEIP_DEFAULT_PARTITION_ID = 0; diff --git a/implementation/configuration/include/routing.hpp b/implementation/configuration/include/routing.hpp new file mode 100644 index 000000000..4ffc3b9b5 --- /dev/null +++ b/implementation/configuration/include/routing.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_CFG_ROUTING_HPP_ +#define VSOMEIP_V3_CFG_ROUTING_HPP_ + +#include + +#include +#include + +#ifdef ANDROID +#include "internal_android.hpp" +#else +#include "internal.hpp" +#endif + +namespace vsomeip_v3 { +namespace cfg { + +struct routing_host_t { + std::string name_; + boost::asio::ip::address unicast_; + port_t port_; + + routing_host_t() : port_(VSOMEIP_ROUTING_HOST_PORT_DEFAULT) {} + + routing_host_t &operator=(const routing_host_t &_other) { + name_ = _other.name_; + unicast_ = _other.unicast_; + port_ = _other.port_; + + return (*this); + } +}; + +struct routing_guests_t { + boost::asio::ip::address unicast_; + std::set > ports_; + + routing_guests_t &operator=(const routing_guests_t &_other) { + unicast_ = _other.unicast_; + ports_ = _other.ports_; + + return (*this); + } +}; + +struct routing_t { + bool is_enabled_; + + routing_host_t host_; + routing_guests_t guests_; + + routing_t() : is_enabled_(true) {} + + routing_t &operator=(const routing_t &_other) { + is_enabled_ = _other.is_enabled_; + host_ = _other.host_; + guests_ = _other.guests_; + + return (*this); + } +}; + +} // namespace cfg +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CFG_ROUTING_HPP_ diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp index 8077f8e1b..af84880f8 100644 --- a/implementation/configuration/include/service.hpp +++ b/implementation/configuration/include/service.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,10 +25,6 @@ struct service { uint16_t reliable_; uint16_t unreliable_; - major_version_t major_; - minor_version_t minor_; - ttl_t ttl_; - std::string multicast_address_; uint16_t multicast_port_; @@ -36,17 +32,16 @@ struct service { // [0] = debounce_time // [1] = retention_time - typedef std::map> npdu_time_configuration_t; + using npdu_time_configuration_t = std::map>; npdu_time_configuration_t debounce_times_requests_; npdu_time_configuration_t debounce_times_responses_; - std::shared_ptr group_; std::map > events_; std::map > eventgroups_; // SOME/IP-TP - std::set tp_segment_messages_client_to_service_; - std::set tp_segment_messages_service_to_client_; + std::map > tp_client_config_; + std::map > tp_service_config_; }; } // namespace cfg diff --git a/implementation/configuration/include/service_instance_range.hpp b/implementation/configuration/include/service_instance_range.hpp index a585d7a5d..9ae162f77 100644 --- a/implementation/configuration/include/service_instance_range.hpp +++ b/implementation/configuration/include/service_instance_range.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/trace.hpp b/implementation/configuration/include/trace.hpp index c9eb8cb29..a83aa81ca 100644 --- a/implementation/configuration/include/trace.hpp +++ b/implementation/configuration/include/trace.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,6 +11,7 @@ #include #include +#include "../../tracing/include/enumeration_types.hpp" namespace vsomeip_v3 { namespace cfg { @@ -22,12 +23,12 @@ struct trace_channel { struct trace_filter { trace_filter() - : is_positive_(true), + : ftype_(vsomeip_v3::trace::filter_type_e::POSITIVE), is_range_(false) { } std::vector channels_; - bool is_positive_; + vsomeip_v3::trace::filter_type_e ftype_; bool is_range_; std::vector matches_; }; diff --git a/implementation/configuration/include/watchdog.hpp b/implementation/configuration/include/watchdog.hpp index 9fe81ff04..5c9de1c1f 100644 --- a/implementation/configuration/include/watchdog.hpp +++ b/implementation/configuration/include/watchdog.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 6fdbb678e..2a8f632cc 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,22 +6,25 @@ #include #include #include +#include #include #include -#include #include #define WIN32_LEAN_AND_MEAN +#define BOOST_BIND_GLOBAL_PLACEHOLDERS #include #include #include +#include #include #include #include #include #include +#include #include "../include/client.hpp" #include "../include/configuration_impl.hpp" @@ -29,20 +32,22 @@ #include "../include/eventgroup.hpp" #include "../include/service.hpp" #include "../../logger/include/logger_impl.hpp" +#include "../../protocol/include/protocol.hpp" #include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../utility/include/utility.hpp" #include "../../plugin/include/plugin_manager.hpp" +#include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" namespace vsomeip_v3 { namespace cfg { -configuration_impl::configuration_impl() +configuration_impl::configuration_impl(const std::string &_path) : default_unicast_("local"), is_loaded_(false), is_logging_loaded_(false), - is_overlay_(false), + prefix_(VSOMEIP_PREFIX), diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), diagnosis_mask_(0xFF00), has_console_log_(true), @@ -95,7 +100,12 @@ configuration_impl::configuration_impl() statistics_interval_(VSOMEIP_DEFAULT_STATISTICS_INTERVAL), statistics_min_freq_(VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ), statistics_max_messages_(VSOMEIP_DEFAULT_STATISTICS_MAX_MSG), - max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS) { + max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS), + path_(_path), + is_security_enabled_(false), + is_security_audit_(false), + is_remote_access_allowed_(true) { + unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS); netmask_ = netmask_.from_string(VSOMEIP_NETMASK); for (auto i = 0; i < ET_MAX; i++) @@ -107,7 +117,6 @@ configuration_impl::configuration_impl(const configuration_impl &_other) default_unicast_(_other.default_unicast_), is_loaded_(_other.is_loaded_), is_logging_loaded_(_other.is_logging_loaded_), - is_overlay_(_other.is_overlay_), mandatory_(_other.mandatory_), max_configured_message_size_(_other.max_configured_message_size_), max_local_message_size_(_other.max_local_message_size_), @@ -125,7 +134,8 @@ configuration_impl::configuration_impl(const configuration_impl &_other) npdu_default_debounce_resp_(_other.npdu_default_debounce_resp_), npdu_default_max_retention_requ_(_other.npdu_default_max_retention_requ_), npdu_default_max_retention_resp_(_other.npdu_default_max_retention_resp_), - shutdown_timeout_(_other.shutdown_timeout_) { + shutdown_timeout_(_other.shutdown_timeout_), + path_(_other.path_) { applications_.insert(_other.applications_.begin(), _other.applications_.end()); client_identifiers_ = _other.client_identifiers_; @@ -145,7 +155,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) loglevel_ = _other.loglevel_; - routing_host_ = _other.routing_host_; + routing_ = _other.routing_; is_sd_enabled_ = _other.is_sd_enabled_; sd_multicast_ = _other.sd_multicast_; @@ -201,6 +211,10 @@ configuration_impl::configuration_impl(const configuration_impl &_other) statistics_min_freq_ = _other.statistics_min_freq_; statistics_max_messages_ = _other.statistics_max_messages_; max_remote_subscribers_ = _other.max_remote_subscribers_; + + is_security_enabled_ = _other.is_security_enabled_; + is_security_audit_ = _other.is_security_audit_; + is_remote_access_allowed_ = _other.is_remote_access_allowed_; } configuration_impl::~configuration_impl() { @@ -211,10 +225,23 @@ bool configuration_impl::load(const std::string &_name) { if (is_loaded_) return true; + // Environment + char *its_env; + // Predefine file / folder std::string its_file(VSOMEIP_DEFAULT_CONFIGURATION_FILE); // configuration file std::string its_folder(VSOMEIP_DEFAULT_CONFIGURATION_FOLDER); // configuration folder + if (!path_.empty()) { + if (utility::is_file(path_)) { + its_file = path_; + its_folder = ""; + } else { + its_file = ""; + its_folder = path_; + } + } + // Override with local file / folder (if existing) std::string its_local_file(VSOMEIP_LOCAL_CONFIGURATION_FILE); if (utility::is_file(its_local_file)) { @@ -227,7 +254,12 @@ bool configuration_impl::load(const std::string &_name) { } // Override with path from environment (if existing) - const char *its_env = getenv(VSOMEIP_ENV_CONFIGURATION); + std::string its_named_configuration(VSOMEIP_ENV_CONFIGURATION); + its_named_configuration += "_" + _name; + + its_env = getenv(its_named_configuration.c_str()); + if (nullptr == its_env) + its_env = getenv(VSOMEIP_ENV_CONFIGURATION); if (nullptr != its_env) { if (utility::is_file(its_env)) { its_file = its_env; @@ -244,7 +276,7 @@ bool configuration_impl::load(const std::string &_name) { } if (its_folder != "") { its_input.insert(its_folder); -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // load security configuration files from UID_GID sub folder if existing std::stringstream its_security_config_folder; its_security_config_folder << its_folder << "/" << getuid() << "_" << getgid(); @@ -280,8 +312,8 @@ bool configuration_impl::load(const std::string &_name) { // If the configuration is incomplete, this is the routing manager configuration or // the routing is yet unknown, read the full set of configuration files if (its_mandatory_elements.empty() || - _name == get_routing_host() || - "" == get_routing_host()) { + _name == get_routing_host_name() || + "" == get_routing_host_name()) { read_data(its_input, its_optional_elements, its_failed, false); load_data(its_mandatory_elements, false, true); load_data(its_optional_elements, true, true); @@ -297,9 +329,6 @@ bool configuration_impl::load(const std::string &_name) { set_magic_cookies_unicast_address(); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); - VSOMEIP_INFO << "Parsed vsomeip configuration in " - << std::chrono::duration_cast(end - begin).count() - << "ms"; for (auto i : its_input) { if (utility::is_file(i)) @@ -309,16 +338,56 @@ bool configuration_impl::load(const std::string &_name) { VSOMEIP_INFO << "Using configuration folder: \"" << i << "\"."; } - is_loaded_ = true; + VSOMEIP_INFO << "Parsed vsomeip configuration in " + << std::chrono::duration_cast(end - begin).count() + << "ms"; + is_loaded_ = true; return is_loaded_; } +#ifndef VSOMEIP_DISABLE_SECURITY +bool configuration_impl::lazy_load_security(const std::string &_client_host) { + bool result(false); + + std::string its_folder = policy_manager_impl::get()->get_policy_extension_path(_client_host); + if (!its_folder.empty()) { + std::set its_input; + std::set its_failed; + std::vector its_mandatory_elements; + + its_input.insert(its_folder); + // load security configuration files from UID_GID sub folder if existing + std::string its_security_config_folder = policy_manager_impl::get()->get_security_config_folder(its_folder); + + if (!its_security_config_folder.empty()) + its_input.insert(its_security_config_folder); + + read_data(its_input, its_mandatory_elements, its_failed, true, true); + + for (const auto& e : its_mandatory_elements) { + policy_manager_impl::get()->load(e, true); + } + + for (auto f : its_failed) + VSOMEIP_WARNING << __func__ << ": Reading of configuration file \"" + << f << "\" failed. Configuration may be incomplete."; + + result = (its_failed.empty() && !its_mandatory_elements.empty()); + if (result) + policy_manager_impl::get()->set_is_policy_extension_loaded(_client_host, true); + } + + return result; +} +#endif // !VSOMEIP_DISABLE_SECURITY + bool configuration_impl::check_routing_credentials( - client_t _client, uint32_t _uid, uint32_t _gid) const { - return (_client != get_id(routing_host_)) || - security::get()->check_routing_credentials(_client, _uid, _gid); + client_t _client, const vsomeip_sec_client_t *_sec_client) const { + + return (_client != get_id(routing_.host_.name_) || + VSOMEIP_SEC_OK == security::authenticate_router(_sec_client)); } bool configuration_impl::remote_offer_info_add(service_t _service, @@ -418,46 +487,56 @@ bool configuration_impl::remote_offer_info_remove(service_t _service, void configuration_impl::read_data(const std::set &_input, std::vector &_elements, std::set &_failed, - bool _mandatory_only) { + bool _mandatory_only, bool _read_second_level) { for (auto i : _input) { if (utility::is_file(i)) { - if (is_mandatory(i) == _mandatory_only) { - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(i, its_tree); - _elements.push_back({ i, its_tree }); - } - catch (boost::property_tree::json_parser_error &e) { - #ifdef _WIN32 - e; // silence MSVC warning C4101 - #endif - _failed.insert(i); - } - } + load_policy_data(i, _elements, _failed, _mandatory_only); } else if (utility::is_folder(i)) { + // Use the map to ensure the configuration files are read in + // the ascending order of their names. This allows to use + // specific configuration file names to overwrite generic + // (or generated) parts of the configuration. + std::map its_names; boost::filesystem::path its_path(i); for (auto j = boost::filesystem::directory_iterator(its_path); j != boost::filesystem::directory_iterator(); j++) { - auto its_file_path = j->path(); - if (!boost::filesystem::is_directory(its_file_path)) { - const std::string& its_name = its_file_path.string(); - if (is_mandatory(its_name) == _mandatory_only) { - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(its_name, its_tree); - _elements.push_back({its_name, its_tree}); - } - catch (...) { - _failed.insert(its_name); - } - } + if (!boost::filesystem::is_directory(j->path())) { + its_names[j->path().string()] = _mandatory_only; + } else if(_read_second_level) { + //_read_second_level to read the second level folders only after + // the start, without this the ECU block + std::string name = j->path().string() + "/vsomeip_security.json"; + if (utility::is_file(name)) + its_names[name] = true; } } + + for (const auto &n : its_names) + load_policy_data(n.first, _elements, _failed, n.second); } } } +void configuration_impl::load_policy_data(const std::string &_input, + std::vector &_elements, std::set &_failed, + bool _mandatory_only) { + if (is_mandatory(_input) == _mandatory_only) { +#ifndef VSOMEIP_DISABLE_SECURITY + if (policy_manager_impl::get()->is_policy_extension(_input)) { + policy_manager_impl::get()->set_policy_extension_base_path(_input); + } +#endif + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(_input, its_tree); + _elements.push_back({ _input, its_tree }); + } + catch (boost::property_tree::json_parser_error&) { + _failed.insert(_input); + } + } +} bool configuration_impl::load_data(const std::vector &_elements, bool _load_mandatory, bool _load_optional) { @@ -513,6 +592,7 @@ bool configuration_impl::load_data(const std::vector &_el load_acceptances(e); load_secure_services(e); load_partitions(e); + load_routing_client_ports(e); } } @@ -531,7 +611,11 @@ bool configuration_impl::load_logging( " Ignoring definition from " + _element.name_); } else { std::string its_value(i->second.data()); - has_console_log_ = (its_value == "true"); + #ifndef ANDROID + has_console_log_ = (its_value == "true"); + #else + has_console_log_ = true; + #endif is_configured_[ET_LOGGING_CONSOLE] = true; } } else if (its_key == "file") { @@ -642,7 +726,55 @@ configuration_impl::load_routing(const configuration_element &_element) { VSOMEIP_WARNING << "Multiple definitions of routing." << " Ignoring definition from " << _element.name_; } else { - routing_host_ = its_routing.data(); + routing_.is_enabled_ = + its_routing.get_optional("enabled").get_value_or(routing_.is_enabled_); + + bool is_loaded = load_routing_host(its_routing, _element.name_) + && load_routing_guests(its_routing); + + if (!is_loaded) { + routing_.host_.name_ = its_routing.data(); + } else { + if (routing_.guests_.unicast_.is_unspecified()) + routing_.guests_.unicast_ = routing_.host_.unicast_; + if (routing_.guests_.ports_.empty()) + routing_.guests_.ports_.insert(std::make_pair(31492, 31999)); + } + + // Try to validate the port configuration. Check whether a range + // contains an even number of ports and whether its starting port + // number fits to the configured routing host port. Correct both + // cases by reducing the range, if necessary. + std::set > its_invalid_ranges; + std::set > its_corrected_ranges; + for (auto &r : routing_.guests_.ports_) { + auto its_pair = std::make_pair(r.first, r.second); + + bool is_even(((r.second - r.first + 1) % 2) == 0); + + // If the routing host port is [un]even, the start number of the + // range shall also be [un]even. + bool is_matching((r.first % 2) == (routing_.host_.port_ % 2)); + if (!is_matching) { + its_pair.first++; + if (is_even) + its_pair.second--; + } else if (!is_even) { + its_pair.second--; + } + + if (!is_even || !is_matching) { + its_invalid_ranges.insert(r); + its_corrected_ranges.insert(its_pair); + } + } + + for (const auto &r : its_invalid_ranges) + routing_.guests_.ports_.erase(r); + + for (const auto &r : its_corrected_ranges) + routing_.guests_.ports_.insert(r); + is_configured_[ET_ROUTING] = true; } } catch (...) { @@ -651,6 +783,140 @@ configuration_impl::load_routing(const configuration_element &_element) { return true; } +bool +configuration_impl::load_routing_host(const boost::property_tree::ptree &_tree, + const std::string &_name) { + + try { + bool has_uid(false), has_gid(false); + uid_t its_uid; + gid_t its_gid; + auto its_host = _tree.get_child("host"); + for (auto i = its_host.begin(); i != its_host.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if (its_key == "name") { + routing_.host_.name_ = its_value; + } else if (its_key == "uid" || its_key == "gid") { + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + if (its_key == "uid") { + its_converter >> its_uid; + has_uid = true; + } else { + its_converter >> its_gid; + has_gid = true; + } + } else if (its_key == "unicast") { +#if VSOMEIP_BOOST_VERSION < 106600 + routing_.host_.unicast_ + = boost::asio::ip::address::from_string(its_value); +#else + routing_.host_.unicast_ + = boost::asio::ip::make_address(its_value); +#endif + } else if (its_key == "port") { + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> routing_.host_.port_; + } + } + + if (has_uid && has_gid) { + policy_manager_impl::get()->set_routing_credentials(its_uid, its_gid, _name); + } + + } catch (...) { + return (false); + } + return (true); +} + +bool +configuration_impl::load_routing_guests(const boost::property_tree::ptree &_tree) { + + try { + auto its_guests = _tree.get_child("guests"); + for (auto i = its_guests.begin(); i != its_guests.end(); ++i) { + std::string its_key(i->first); + if (its_key == "unicast") { + std::string its_value(i->second.data()); +#if VSOMEIP_BOOST_VERSION < 106600 + routing_.guests_.unicast_ + = boost::asio::ip::address::from_string(its_value); +#else + routing_.guests_.unicast_ + = boost::asio::ip::make_address(its_value); +#endif + } else if (its_key == "ports") { + load_routing_guest_ports(i->second); + } + } + } catch (...) { + // intentionally left empty + } + return (true); +} + +void +configuration_impl::load_routing_guest_ports( + const boost::property_tree::ptree &_tree) { + + try { + for (auto its_range = _tree.begin(); + its_range != _tree.end(); ++its_range) { + + port_t its_first_port(0), its_last_port(0); + for (auto its_element = its_range->second.begin(); + its_element != its_range->second.end(); ++its_element) { + + std::string its_key(its_element->first); + std::string its_value(its_element->second.data()); + + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + + if (its_key == "first") { + its_converter >> its_first_port; + } else if (its_key == "last") { + its_converter >> its_last_port; + } + } + + if (its_first_port != 0 && its_last_port != 0) { + routing_.guests_.ports_.insert(std::make_pair( + std::min(its_first_port, its_last_port), + std::max(its_first_port, its_last_port))); + } + } + } catch (...) { + } +} + + +void +configuration_impl::load_routing_client_ports(const configuration_element &_element) { + + try { + auto its_ports = _element.tree_.get_child("routing-client-ports"); + load_routing_guest_ports(its_ports); + } + catch (...) { + } +} + bool configuration_impl::load_applications(const configuration_element &_element) { try { @@ -676,10 +942,8 @@ void configuration_impl::load_application_data( std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME); std::map> plugins; int its_io_thread_nice_level(VSOMEIP_IO_THREAD_NICE_LEVEL); - std::string its_overlay; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG + debounce_configuration_t its_debounces; bool has_session_handling(true); -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); std::string its_value(i->second.data()); @@ -721,14 +985,18 @@ void configuration_impl::load_application_data( } } else if (its_key == "plugins") { plugins = load_plugins(i->second, its_name); - } else if (its_key == "overlay") { - its_overlay = its_value; + } else if (its_key == "debounce") { + try { + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + load_service_debounce(j->second, its_debounces); + } + } catch (...) { + // intentionally empty + } } -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG else if (its_key == "has_session_handling") { has_session_handling = (its_value != "false"); } -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG } if (its_name != "") { if (applications_.find(its_name) == applications_.end()) { @@ -743,15 +1011,18 @@ void configuration_impl::load_application_data( its_id = VSOMEIP_CLIENT_UNSET; } } - applications_[its_name] - = std::make_tuple(its_id, its_max_dispatchers, - its_max_dispatch_time, its_io_thread_count, - its_request_debounce_time, plugins, its_io_thread_nice_level, - its_overlay -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , has_session_handling -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - ); + + applications_[its_name] = { + its_id, + its_max_dispatchers, + its_max_dispatch_time, + its_io_thread_count, + its_request_debounce_time, + plugins, + its_io_thread_nice_level, + its_debounces + , has_session_handling + }; } else { VSOMEIP_WARNING << "Multiple configurations for application " << its_name << ". Ignoring a configuration from " @@ -762,7 +1033,7 @@ void configuration_impl::load_application_data( std::map> configuration_impl::load_plugins( const boost::property_tree::ptree &_tree, - const std::string& _application_name) { + const std::string &_application_name) { std::map> its_plugins; std::string its_name(""); std::string its_type; @@ -788,6 +1059,19 @@ std::map> configuration_impl::load_plugins( its_type = its_inner_value; its_configured[ET_PLUGIN_TYPE] = true; } + } else if (its_inner_key == "additional") { + if (its_configured[ET_PLUGIN_NAME]) { + const boost::property_tree::ptree &its_additional_tree(l->second); + for (auto m = its_additional_tree.begin(); m!= its_additional_tree.end(); ++m) { + for (auto n = m->second.begin(); n != m->second.end(); ++n) { + std::string its_additional_inner_key(n->first); + std::string its_additional_inner_value(n->second.data()); + plugins_additional_[_application_name][its_name] + [its_additional_inner_key] = + its_additional_inner_value; + } + } + } } else { //support old config format (type : name) plugin_config_data_t its_plugin_data = { @@ -820,13 +1104,13 @@ void configuration_impl::add_plugin(std::mapsecond.data(); - its_filter->is_positive_ = (its_value == "positive"); + if (its_value == "negative") + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::NEGATIVE; + else if (its_value == "header-only") + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::HEADER_ONLY; + else + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::POSITIVE; } else { load_trace_filter_expressions(i->second, its_key, its_filter); } @@ -941,7 +1230,7 @@ void configuration_impl::load_trace_filter( its_filter->channels_.push_back("TC"); // default } - if (!its_filter->is_range_ || its_filter->matches_.size() == 2) { + if (!its_filter->is_range_ || its_filter->matches_.size() > 0) { trace_->filters_.push_back(its_filter); } } @@ -1052,7 +1341,7 @@ void configuration_impl::load_trace_filter_match( void configuration_impl::load_unicast_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("unicast"); - if (!is_overlay_ && is_configured_[ET_UNICAST]) { + if (is_configured_[ET_UNICAST]) { VSOMEIP_WARNING << "Multiple definitions for unicast." "Ignoring definition from " << _element.name_; } else { @@ -1066,13 +1355,35 @@ void configuration_impl::load_unicast_address(const configuration_element &_elem void configuration_impl::load_netmask(const configuration_element &_element) { try { - std::string its_value = _element.tree_.get("netmask"); - if (!is_overlay_ && is_configured_[ET_NETMASK]) { - VSOMEIP_WARNING << "Multiple definitions for netmask." - "Ignoring definition from " << _element.name_; - } else { - netmask_ = netmask_.from_string(its_value); - is_configured_[ET_NETMASK] = true; + auto its_value = _element.tree_.get_optional("netmask"); + if (its_value) { + if (is_configured_[ET_NETMASK]) { + VSOMEIP_WARNING << "Multiple definitions for netmask/prefix." + "Ignoring netmask definition from " << _element.name_; + } else { + netmask_ = netmask_.from_string(*its_value); + is_configured_[ET_NETMASK] = true; + } + } + + its_value = _element.tree_.get_optional("prefix"); + if (its_value) { + if (is_configured_[ET_NETMASK]) { + VSOMEIP_WARNING << "Multiple definitions for prefix/netmask." + "Ignoring prefix definition from " << _element.name_; + } else { + std::stringstream its_converter; + its_converter << *its_value; + its_converter >> std::dec >> prefix_; + + // Convert to netmask as this is used for IPv4. + uint32_t its_netmask = (std::numeric_limits::max() + << (std::numeric_limits::digits - prefix_)) + & std::numeric_limits::max(); + netmask_ = boost::asio::ip::address_v4(its_netmask); + + is_configured_[ET_NETMASK] = true; + } } } catch (...) { // intentionally left empty! @@ -1082,7 +1393,7 @@ void configuration_impl::load_netmask(const configuration_element &_element) { void configuration_impl::load_device(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("device"); - if (!is_overlay_ && is_configured_[ET_DEVICE]) { + if (is_configured_[ET_DEVICE]) { VSOMEIP_WARNING << "Multiple definitions for device." "Ignoring definition from " << _element.name_; } else { @@ -1097,7 +1408,7 @@ void configuration_impl::load_device(const configuration_element &_element) { void configuration_impl::load_network(const configuration_element &_element) { try { std::string its_value(_element.tree_.get("network")); - if (!is_overlay_ && is_configured_[ET_NETWORK]) { + if (is_configured_[ET_NETWORK]) { VSOMEIP_WARNING << "Multiple definitions for network." "Ignoring definition from " << _element.name_; } else { @@ -1112,7 +1423,7 @@ void configuration_impl::load_network(const configuration_element &_element) { void configuration_impl::load_diagnosis_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("diagnosis"); - if (!is_overlay_ && is_configured_[ET_DIAGNOSIS]) { + if (is_configured_[ET_DIAGNOSIS]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis." "Ignoring definition from " << _element.name_; } else { @@ -1127,7 +1438,7 @@ void configuration_impl::load_diagnosis_address(const configuration_element &_el is_configured_[ET_DIAGNOSIS] = true; } std::string its_mask = _element.tree_.get("diagnosis_mask"); - if (!is_overlay_ && is_configured_[ET_DIAGNOSIS_MASK]) { + if (is_configured_[ET_DIAGNOSIS_MASK]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis_mask." "Ignoring definition from " << _element.name_; } else { @@ -1189,7 +1500,7 @@ void configuration_impl::load_service_discovery( std::string its_value(i->second.data()); std::stringstream its_converter; if (its_key == "enable") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { + if (is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.enabled." " Ignoring definition from " << _element.name_; } else { @@ -1197,7 +1508,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_ENABLE] = true; } } else if (its_key == "multicast") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { + if (is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.multicast." " Ignoring definition from " << _element.name_; } else { @@ -1205,7 +1516,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_MULTICAST] = true; } } else if (its_key == "port") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PORT]) { + if (is_configured_[ET_SERVICE_DISCOVERY_PORT]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.port." " Ignoring definition from " << _element.name_; } else { @@ -1218,7 +1529,7 @@ void configuration_impl::load_service_discovery( } } } else if (its_key == "protocol") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { + if (is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.protocol." " Ignoring definition from " << _element.name_; } else { @@ -1226,7 +1537,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL] = true; } } else if (its_key == "initial_delay_min") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_min." " Ignoring definition from " << _element.name_; } else { @@ -1235,7 +1546,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN] = true; } } else if (its_key == "initial_delay_max") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_max." " Ignoring definition from " << _element.name_; } else { @@ -1244,7 +1555,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX] = true; } } else if (its_key == "repetitions_base_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_base_delay." " Ignoring definition from " << _element.name_; } else { @@ -1253,7 +1564,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY] = true; } } else if (its_key == "repetitions_max") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_max." " Ignoring definition from " << _element.name_; } else { @@ -1266,7 +1577,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX] = true; } } else if (its_key == "ttl") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl." " Ignoring definition from " << _element.name_; } else { @@ -1281,7 +1592,7 @@ void configuration_impl::load_service_discovery( else is_configured_[ET_SERVICE_DISCOVERY_TTL] = true; } } else if (its_key == "cyclic_offer_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.cyclic_offer_delay." " Ignoring definition from " << _element.name_; } else { @@ -1290,7 +1601,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY] = true; } } else if (its_key == "request_response_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.request_response_delay." " Ignoring definition from " << _element.name_; } else { @@ -1299,7 +1610,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY] = true; } } else if (its_key == "offer_debounce_time") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { + if (is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.offer_debounce." " Ignoring definition from " << _element.name_; } else { @@ -1308,7 +1619,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME] = true; } } else if (its_key == "ttl_factor_offers") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_offers." " Ignoring definition from " << _element.name_; } else { @@ -1316,7 +1627,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS] = true; } } else if (its_key == "ttl_factor_subscriptions") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_subscriptions." " Ignoring definition from " << _element.name_; } else { @@ -1324,7 +1635,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS] = true; } } else if (its_key == "max_remote_subscribers") { - if (!is_overlay_ && is_configured_[ET_MAX_REMOTE_SUBSCRIBERS]) { + if (is_configured_[ET_MAX_REMOTE_SUBSCRIBERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.max_remote_subscribers." " Ignoring definition from " << _element.name_; } else { @@ -1393,7 +1704,7 @@ void configuration_impl::load_npdu_default_timings(const configuration_element & const std::string rresp("max-retention-time-response"); try { if (_element.tree_.get_child_optional(ndt)) { - if (!is_overlay_ && is_configured_[ET_NPDU_DEFAULT_TIMINGS]) { + if (is_configured_[ET_NPDU_DEFAULT_TIMINGS]) { VSOMEIP_WARNING << "Multiple definitions of " << ndt << " Ignoring definition from " << _element.name_; } else { @@ -1403,7 +1714,7 @@ void configuration_impl::load_npdu_default_timings(const configuration_element & its_time = std::chrono::nanoseconds( std::strtoull(e.second.data().c_str(), NULL, 10) * 1000000); - } catch (const std::exception& e) { + } catch (const std::exception&) { continue; } if (e.first.data() == dreq) { @@ -1481,9 +1792,6 @@ void configuration_impl::load_service( its_service->multicast_address_ = ""; its_service->multicast_port_ = ILLEGAL_PORT; its_service->protocol_ = "someip"; - its_service->major_ = DEFAULT_MAJOR; - its_service->minor_ = DEFAULT_MINOR; - its_service->ttl_ = DEFAULT_TTL; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -1548,14 +1856,6 @@ void configuration_impl::load_service( its_converter >> its_service->service_; } else if (its_key == "instance") { its_converter >> its_service->instance_; - } else if (its_key == "major") { - unsigned int temp; - its_converter >> temp; - its_service->major_ = static_cast(temp); - } else if (its_key == "minor") { - its_converter >> its_service->minor_; - } else if (its_key == "ttl") { - its_converter >> its_service->ttl_; } } } @@ -1625,6 +1925,10 @@ void configuration_impl::load_event( event_t its_event_id(0); bool its_is_field(false); reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); + uint32_t its_cycle_value; + std::chrono::milliseconds its_cycle(std::chrono::milliseconds::zero()); + bool its_change_resets_cycle(false); + bool its_update_on_change(true); for (auto j = i->second.begin(); j != i->second.end(); ++j) { std::string its_key(j->first); @@ -1644,28 +1948,26 @@ void configuration_impl::load_event( its_reliability = reliability_type_e::RT_RELIABLE; else its_reliability = reliability_type_e::RT_UNRELIABLE; + } else if (its_key == "cycle") { + std::stringstream its_converter; + its_converter << std::dec << its_value; + its_converter >> its_cycle_value; + its_cycle = std::chrono::milliseconds(its_cycle_value); + } else if (its_key == "change_resets_cycle") { + its_change_resets_cycle = (its_value == "true"); + } else if (its_key == "update_on_change") { + its_update_on_change = (its_value == "true"); } } if (its_event_id > 0) { - std::shared_ptr its_event; - auto found_event = _service->events_.find(its_event_id); if (found_event != _service->events_.end()) { - if (found_event->second->is_placeholder_) { - its_event = found_event->second; - } else { - VSOMEIP_ERROR << "Multiple configurations for event [" - << std::hex << _service->service_ << "." - << _service->instance_ << "." - << its_event_id << "]"; - } + VSOMEIP_INFO << "Multiple configurations for event [" + << std::hex << _service->service_ << "." + << _service->instance_ << "." + << its_event_id << "]."; } else { - its_event = std::make_shared(its_event_id); - _service->events_[its_event_id] = its_event; - } - - if (its_event) { // If event reliability type was not configured, if (its_reliability == reliability_type_e::RT_UNKNOWN) { if (_service->unreliable_ != ILLEGAL_PORT) { @@ -1681,9 +1983,11 @@ void configuration_impl::load_event( ? "RT_RELIABLE" : "RT_UNRELIABLE"); } - its_event->is_placeholder_ = false; - its_event->reliability_ = its_reliability; - its_event->is_field_ = its_is_field; + std::shared_ptr its_event = std::make_shared( + its_event_id, its_is_field, its_reliability, + its_cycle, its_change_resets_cycle, + its_update_on_change); + _service->events_[its_event_id] = its_event; } } } @@ -1747,7 +2051,10 @@ void configuration_impl::load_eventgroup( if (find_event != _service->events_.end()) { its_event = find_event->second; } else { - its_event = std::make_shared(its_event_id); + its_event = std::make_shared(its_event_id, + false, reliability_type_e::RT_UNRELIABLE, + std::chrono::milliseconds::zero(), + false, true); } if (its_event) { its_event->groups_.push_back(its_eventgroup); @@ -2138,9 +2445,46 @@ void configuration_impl::load_permissions(const configuration_element &_element) } void configuration_impl::load_security(const configuration_element &_element) { - security::get()->load(_element); + + try { + auto its_security = _element.tree_.get_child_optional("security"); + if (its_security) { + is_security_enabled_ = true; + + auto its_audit_mode = its_security->get_child_optional("check_credentials"); + if (its_audit_mode) { + if (is_configured_[ET_SECURITY_AUDIT_MODE]) { + VSOMEIP_WARNING << "Multiple definitions for security audit mode (" + << "(check_credentials). Ignoring definition from " + << _element.name_; + } else { + is_security_audit_ = (its_audit_mode->data() != "true"); + is_configured_[ET_SECURITY_AUDIT_MODE] = true; + } + } + + auto its_remote_access = its_security->get_child_optional("allow_remote_clients"); + if (its_remote_access) { + if (is_configured_[ET_SECURITY_REMOTE_ACCESS]) { + VSOMEIP_WARNING << "Multiple definitions for security audit mode (" + << "(check_credentials). Ignoring definition from " + << _element.name_; + } else { + is_remote_access_allowed_ = (its_remote_access->data() == "true"); + is_configured_[ET_SECURITY_REMOTE_ACCESS] = true; + } + } + } + + } catch (...) { + } + +#ifndef VSOMEIP_DISABLE_SECURITY + policy_manager_impl::get()->load(_element); +#endif // !VSOMEIP_DISABLE_SECURITY } + void configuration_impl::load_selective_broadcasts_support(const configuration_element &_element) { try { auto its_service_discovery = _element.tree_.get_child("supports_selective_broadcasts"); @@ -2220,14 +2564,14 @@ configuration_impl::load_partition(const boost::property_tree::ptree &_tree) { << std::dec << static_cast(its_partition_id) << " ["; - for (const auto &i : its_partition_members) { - for (const auto j : i.second) { - partitions_[i.first][j] = its_partition_id; + for (const auto &p : its_partition_members) { + for (const auto &m : p.second) { + partitions_[p.first][m] = its_partition_id; its_log << "<" << std::setw(4) << std::setfill('0') << std::hex - << i.first << "." + << p.first << "." << std::setw(4) << std::setfill('0') << std::hex - << j + << m << ">"; } } @@ -2294,6 +2638,10 @@ const boost::asio::ip::address& configuration_impl::get_netmask() const { return netmask_; } +unsigned short configuration_impl::get_prefix() const { + return prefix_; +} + const std::string &configuration_impl::get_device() const { return device_; } @@ -2371,15 +2719,16 @@ uint16_t configuration_impl::get_unreliable_port(service_t _service, } void configuration_impl::get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const { + if (_debounce_time == nullptr || _max_retention_time == nullptr) { return; } - service *its_service = find_service_by_ip_port(_service, _ip_target, - _port_target); + + auto its_service = find_service(_service, _ip_target, _port_target); if (its_service) { auto find_method = its_service->debounce_times_requests_.find(_method); if (find_method != its_service->debounce_times_requests_.end()) { @@ -2388,20 +2737,21 @@ void configuration_impl::get_configured_timing_requests( return; } } + *_debounce_time = npdu_default_debounce_requ_; *_max_retention_time = npdu_default_max_retention_requ_; } void configuration_impl::get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const { if (_debounce_time == nullptr || _max_retention_time == nullptr) { return; } - service *its_service = find_service_by_ip_port(_service, _ip_service, - _port_service); + + auto its_service = find_service(_service, _ip_service, _port_service); if (its_service) { auto find_method = its_service->debounce_times_responses_.find(_method); if (find_method != its_service->debounce_times_responses_.end()) { @@ -2410,43 +2760,11 @@ void configuration_impl::get_configured_timing_responses( return; } } + *_debounce_time = npdu_default_debounce_resp_; *_max_retention_time = npdu_default_max_retention_resp_; } -major_version_t configuration_impl::get_major_version(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - major_version_t its_major = DEFAULT_MAJOR; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_major = its_service->major_; - - return its_major; -} - -minor_version_t configuration_impl::get_minor_version(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - minor_version_t its_minor = DEFAULT_MINOR; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_minor = its_service->minor_; - - return its_minor; -} - -ttl_t configuration_impl::get_ttl(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - ttl_t its_ttl = DEFAULT_TTL; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_ttl = its_service->ttl_; - - return its_ttl; -} - bool configuration_impl::is_someip(service_t _service, instance_t _instance) const { auto its_service = find_service(_service, _instance); @@ -2499,7 +2817,7 @@ bool configuration_impl::get_client_port( return false; } -bool configuration_impl::has_enabled_magic_cookies(std::string _address, +bool configuration_impl::has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const { bool has_enabled(false); auto find_address = magic_cookies_.find(_address); @@ -2512,9 +2830,51 @@ bool configuration_impl::has_enabled_magic_cookies(std::string _address, return has_enabled; } +bool configuration_impl::is_routing_enabled() const { + return (routing_.is_enabled_); +} + +const std::string & +configuration_impl::get_routing_host_name() const { + + return (routing_.host_.name_); +} + +const boost::asio::ip::address & +configuration_impl::get_routing_host_address() const { + + return (routing_.host_.unicast_); +} + +port_t +configuration_impl::get_routing_host_port() const { + + return (routing_.host_.port_); +} + +const boost::asio::ip::address & +configuration_impl::get_routing_guest_address() const { + + return (routing_.guests_.unicast_); +} + +std::set > +configuration_impl::get_routing_guest_ports() const { -const std::string & configuration_impl::get_routing_host() const { - return routing_host_; + return (routing_.guests_.ports_); +} + +bool +configuration_impl::is_local_routing() const { + + bool is_local(true); + try { + is_local = routing_.host_.unicast_.is_unspecified() || + routing_.host_.unicast_.is_multicast(); + } catch (...) { + } + + return (is_local); } client_t configuration_impl::get_id(const std::string &_name) const { @@ -2522,7 +2882,7 @@ client_t configuration_impl::get_id(const std::string &_name) const { auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_client = std::get<0>(found_application->second); + its_client = found_application->second.client_; } return its_client; @@ -2533,13 +2893,13 @@ bool configuration_impl::is_configured_client_id(client_t _id) const { } std::size_t configuration_impl::get_request_debouncing(const std::string &_name) const { - size_t debounce_time = VSOMEIP_REQUEST_DEBOUNCE_TIME; + size_t its_request_debouncing(VSOMEIP_REQUEST_DEBOUNCE_TIME); auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - debounce_time = std::get<4>(found_application->second); + its_request_debouncing = found_application->second.request_debouncing_; } - return debounce_time; + return its_request_debouncing; } std::size_t configuration_impl::get_io_thread_count(const std::string &_name) const { @@ -2547,7 +2907,7 @@ std::size_t configuration_impl::get_io_thread_count(const std::string &_name) co auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_io_thread_count = std::get<3>(found_application->second); + its_io_thread_count = found_application->second.thread_count_; } return its_io_thread_count; @@ -2558,7 +2918,7 @@ int configuration_impl::get_io_thread_nice_level(const std::string &_name) const auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_io_thread_nice_level = std::get<6>(found_application->second); + its_io_thread_nice_level = found_application->second.nice_level_; } return its_io_thread_nice_level; @@ -2566,11 +2926,12 @@ int configuration_impl::get_io_thread_nice_level(const std::string &_name) const std::size_t configuration_impl::get_max_dispatchers( const std::string &_name) const { - std::size_t its_max_dispatchers = VSOMEIP_MAX_DISPATCHERS; + + std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_max_dispatchers = std::get<1>(found_application->second); + its_max_dispatchers = found_application->second.max_dispatchers_; } return its_max_dispatchers; @@ -2582,23 +2943,22 @@ std::size_t configuration_impl::get_max_dispatch_time( auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_max_dispatch_time = std::get<2>(found_application->second); + its_max_dispatch_time = found_application->second.max_dispatch_time_; } return its_max_dispatch_time; } -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG + bool configuration_impl::has_session_handling(const std::string &_name) const { bool its_value(true); auto found_application = applications_.find(_name); if (found_application != applications_.end()) - its_value = std::get<8>(found_application->second); + its_value = found_application->second.has_session_handling_; return (its_value); } -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG std::set > configuration_impl::get_remote_services() const { @@ -2657,7 +3017,7 @@ void configuration_impl::trim(std::string &_s) { std::find_if( _s.begin(), _s.end(), - std::not1(std::ptr_fun(isspace)) + [](unsigned char ch) { return !std::isspace(ch); } ) ); @@ -2665,7 +3025,7 @@ void configuration_impl::trim(std::string &_s) { std::find_if( _s.rbegin(), _s.rend(), - std::not1(std::ptr_fun(isspace))).base(), + [](unsigned char ch) { return !std::isspace(ch); }).base(), _s.end() ); } @@ -2715,6 +3075,32 @@ std::shared_ptr configuration_impl::find_client(service_t _service, return nullptr; } +void configuration_impl::get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change) const { + + auto find_service = services_.find(_service); + if (find_service != services_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + auto its_service = find_instance->second; + auto find_event = its_service->events_.find(_event); + if (find_event != its_service->events_.end()) { + _cycle = find_event->second->cycle_; + _change_resets_cycle = find_event->second->change_resets_cycle_; + _update_on_change = find_event->second->update_on_change_; + return; + } + } + } + + _cycle = std::chrono::milliseconds::zero(); + _change_resets_cycle = false; + _update_on_change = true; +} + + bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reliable, std::map > &_used_client_ports) const { bool is_configured(false); @@ -2726,10 +3112,12 @@ bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reli is_configured = true; uint16_t its_port(ILLEGAL_PORT); if ((*it)->last_used_client_port_[_reliable] != ILLEGAL_PORT && - is_in_port_range(((*it)->last_used_client_port_[_reliable])++, + is_in_port_range(((*it)->last_used_client_port_[_reliable]), (*it)->client_ports_[_reliable])) { - its_port = ((*it)->last_used_client_port_[_reliable])++; + its_port = ++((*it)->last_used_client_port_[_reliable]); + ((*it)->last_used_client_port_[_reliable])++; } else { + ((*it)->last_used_client_port_[_reliable])++; // on initial start of port search if ((*it)->last_used_client_port_[_reliable] == ILLEGAL_PORT) { its_port = (*it)->client_ports_[_reliable].first; @@ -2892,19 +3280,23 @@ std::shared_ptr configuration_impl::find_service_unlocked(service_t _se return its_service; } -service* configuration_impl::find_service_by_ip_port( - service_t _service, const std::string& _ip, std::uint16_t _port) const { - service *its_service(0); - auto find_ip = services_by_ip_port_.find(_ip); - if(find_ip != services_by_ip_port_.end()) { - auto find_port = find_ip->second.find(_port); - if(find_port != find_ip->second.end()) { +std::shared_ptr +configuration_impl::find_service(service_t _service, + const std::string &_address, std::uint16_t _port) const { + + std::shared_ptr its_service; + + auto find_address = services_by_ip_port_.find(_address); + if (find_address != services_by_ip_port_.end()) { + auto find_port = find_address->second.find(_port); + if(find_port != find_address->second.end()) { auto find_service = find_port->second.find(_service); if(find_service != find_port->second.end()) { - its_service = find_service->second.get(); + its_service = find_service->second; } } } + return its_service; } @@ -2944,7 +3336,7 @@ std::uint32_t configuration_impl::get_max_message_size_local() const { // add sizes of the the routing_manager_proxy's messages // to the routing_manager stub - return std::uint32_t(its_max_message_size + VSOMEIP_SEND_COMMAND_SIZE); + return std::uint32_t(its_max_message_size + protocol::SEND_COMMAND_HEADER_SIZE); } std::uint32_t configuration_impl::get_max_message_size_reliable( @@ -2970,7 +3362,7 @@ std::uint32_t configuration_impl::get_buffer_shrink_threshold() const { return buffer_shrink_threshold_; } -bool configuration_impl::supports_selective_broadcasts(boost::asio::ip::address _address) const { +bool configuration_impl::supports_selective_broadcasts(const boost::asio::ip::address &_address) const { return supported_selective_addresses.find(_address.to_string()) != supported_selective_addresses.end(); } @@ -3076,20 +3468,28 @@ std::uint32_t configuration_impl::get_permissions_shm() const { std::map> configuration_impl::get_plugins( const std::string &_name) const { - std::map> result; + + std::map> its_plugins; auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - result = std::get<5>(found_application->second); + its_plugins = found_application->second.plugins_; } - return result; + return its_plugins; } void configuration_impl::set_configuration_path(const std::string &_path) { configuration_path_ = _path; } +std::map configuration_impl::get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name) { + + return plugins_additional_[_application_name][_plugin_name]; +} + bool configuration_impl::is_e2e_enabled() const { return e2e_enabled_; } @@ -3361,17 +3761,20 @@ configuration_impl::load_debounce(const configuration_element &_element) { try { auto its_debounce = _element.tree_.get_child("debounce"); for (auto i = its_debounce.begin(); i != its_debounce.end(); ++i) { - load_service_debounce(i->second); + load_service_debounce(i->second, debounces_); } } catch (...) { } } void -configuration_impl::load_service_debounce(const boost::property_tree::ptree &_tree) { +configuration_impl::load_service_debounce( + const boost::property_tree::ptree &_tree, + debounce_configuration_t &_debounces) { + service_t its_service(0); instance_t its_instance(0); - std::map> its_debounces; + std::map> its_debounces; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -3410,23 +3813,27 @@ configuration_impl::load_service_debounce(const boost::property_tree::ptree &_tr return; } } - debounces_[its_service][its_instance] = its_debounces; + _debounces[its_service][its_instance] = its_debounces; } } -void configuration_impl::load_events_debounce( +void +configuration_impl::load_events_debounce( const boost::property_tree::ptree &_tree, - std::map> &_debounces) { + std::map > &_debounces) { + for (auto i = _tree.begin(); i != _tree.end(); ++i) { load_event_debounce(i->second, _debounces); } } -void configuration_impl::load_event_debounce( +void +configuration_impl::load_event_debounce( const boost::property_tree::ptree &_tree, - std::map> &_debounces) { + std::map > &_debounces) { + event_t its_event(0); - std::shared_ptr its_debounce = std::make_shared(); + auto its_debounce = std::make_shared(); for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -3518,20 +3925,21 @@ configuration_impl::load_acceptances( const configuration_element &_element) { std::string its_acceptances_key("acceptances"); + try { + auto its_acceptances = _element.tree_.get_child_optional(its_acceptances_key); + if (its_acceptances) { + if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { + VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key + << " Ignoring definition from " << _element.name_; + return; + } - if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { - VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key - << " Ignoring definition from " << _element.name_; - return; - } + for (auto i = its_acceptances->begin(); i != its_acceptances->end(); ++i) { + load_acceptance_data(i->second); + } - try { - auto its_acceptances = _element.tree_.get_child(its_acceptances_key); - for (auto i = its_acceptances.begin(); i != its_acceptances.end(); ++i) { - load_acceptance_data(i->second); + is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; } - - is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; } catch (...) { // Intentionally left empty } @@ -3560,7 +3968,6 @@ configuration_impl::load_acceptance_data( std::string its_value(i->second.data()); if (its_key == "address") { - boost::system::error_code ec; its_address = boost::asio::ip::address::from_string(its_value); } else if (its_key == "path") { its_path = its_value; @@ -3643,37 +4050,8 @@ configuration_impl::load_acceptance_data( } } - // If no ports are specified, use default! - if (its_ports.empty()) { - const auto its_optional_client = boost::icl::interval::closed(30491, 30499); - const auto its_optional_client_spare = boost::icl::interval::closed(30898, 30998); - const auto its_optional_server = boost::icl::interval::closed(30501, 30599); - - // optional - its_ports.operator [](false).first.insert(its_optional_client); - its_ports.operator [](false).first.insert(its_optional_client_spare); - its_ports.operator [](false).first.insert(its_optional_server); - its_ports.operator [](true).first.insert(its_optional_client); - its_ports.operator [](true).first.insert(its_optional_client_spare); - its_ports.operator [](true).first.insert(its_optional_server); - - // secure - const auto its_secure_client = boost::icl::interval::closed(32491, 32499); - const auto its_secure_client_spare = boost::icl::interval::closed(32898, 32998); - const auto its_secure_server = boost::icl::interval::closed(32501, 32599); - - its_ports.operator [](false).second.insert(its_secure_client); - its_ports.operator [](false).second.insert(its_secure_client_spare); - its_ports.operator [](false).second.insert(its_secure_server); - its_ports.operator [](true).second.insert(its_secure_client); - its_ports.operator [](true).second.insert(its_secure_client_spare); - its_ports.operator [](true).second.insert(its_secure_server); - } - if (!its_address.is_unspecified()) { - sd_acceptance_rules_.insert( - std::make_pair(its_address, - std::make_pair(its_path, its_ports))); + sd_acceptance_rules_[its_address] = std::make_pair(its_path, its_ports); } } catch (...) { // intentionally left empty @@ -3779,20 +4157,88 @@ void configuration_impl::load_someip_tp_for_service( try { std::stringstream its_converter; for (const auto& method : _tree) { - method_t its_method = 0xFFFF; + method_t its_method(0); + uint16_t its_max_segment_length(VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT); + uint32_t its_separation_time(0); + const std::string its_value(method.second.data()); - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; + if (its_value.empty()) { + for (const auto &its_data : method.second) { + const std::string its_value(its_data.second.data()); + if (!its_value.empty()) { + if (its_data.first == "method") { + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_method; + } else if (its_data.first == "max-segment-length") { + its_converter << std::dec << its_value; + its_converter >> its_max_segment_length; + + // Segment length must be multiple of 16 + // Ensure this by subtracting the rest + std::uint16_t its_rest = std::uint16_t(its_max_segment_length % 16); + if (its_rest != 0) { + VSOMEIP_WARNING << "SOMEIP/TP: max-segment-length must be multiple of 16. Corrected " + << std::dec << its_max_segment_length << " to " + << std::dec << its_max_segment_length-its_rest; + + its_max_segment_length = std::uint16_t(its_max_segment_length - its_rest); + } + } else if (its_data.first == "separation-time") { + its_converter << std::dec << its_value; + its_converter >> its_separation_time; + its_separation_time *= std::uint32_t(1000); + } + } + its_converter.str(""); + its_converter.clear(); + } } else { - its_converter << std::dec << its_value; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_method; + its_converter.str(""); + its_converter.clear(); } - its_converter >> its_method; - its_converter.str(""); - its_converter.clear(); - if (_is_request) { - _service->tp_segment_messages_client_to_service_.insert(its_method); + + if (its_method != 0) { + if (_is_request) { + const auto its_entry = _service->tp_client_config_.find(its_method); + if (its_entry == _service->tp_client_config_.end()) { + _service->tp_client_config_[its_method] + = std::make_pair(its_max_segment_length, its_separation_time); + } else { + VSOMEIP_WARNING << "SOME/IP-TP: Multiple client configurations for method [" + << std::hex << std::setw(4) << std::setfill('0') << _service->service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << _service->instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]:" + << " using (" + << std::dec << its_entry->second.first << ", " + << std::dec << its_entry->second.second << ")"; + } + } else { + const auto its_entry = _service->tp_service_config_.find(its_method); + if (its_entry == _service->tp_service_config_.end()) { + _service->tp_service_config_[its_method] + = std::make_pair(its_max_segment_length, its_separation_time); + } else { + VSOMEIP_WARNING << "SOME/IP-TP: Multiple service configurations for method [" + << std::hex << std::setw(4) << std::setfill('0') << _service->service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << _service->instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]:" + << " using (" + << std::dec << its_entry->second.first << ", " + << std::dec << its_entry->second.second << ")"; + } + } } else { - _service->tp_segment_messages_service_to_client_.insert(its_method); + VSOMEIP_ERROR << "SOME/IP-TP configuration contains invalid entry. No valid method specified!"; } } } catch (...) { @@ -3802,18 +4248,18 @@ void configuration_impl::load_someip_tp_for_service( void configuration_impl::load_udp_receive_buffer_size(const configuration_element &_element) { - const std::string urbs("udp-receive-buffer-size"); + const std::string its_buffer_size("udp-receive-buffer-size"); try { - if (_element.tree_.get_child_optional(urbs)) { + if (_element.tree_.get_child_optional(its_buffer_size)) { if (is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE]) { - VSOMEIP_WARNING << "Multiple definitions of " << urbs + VSOMEIP_WARNING << "Multiple definitions of " << its_buffer_size << " Ignoring definition from " << _element.name_; } else { - const std::string s(_element.tree_.get_child(urbs).data()); + const std::string its_data(_element.tree_.get_child(its_buffer_size).data()); try { - udp_receive_buffer_size_ = std::stoi(s.c_str(), NULL, 10); + udp_receive_buffer_size_ = std::stoi(its_data.c_str(), nullptr, 10); } catch (const std::exception &e) { - VSOMEIP_ERROR<< __func__ << ": " << urbs << " " << e.what(); + VSOMEIP_ERROR<< __func__ << ": " << its_buffer_size << " " << e.what(); } is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE] = true; } @@ -3872,19 +4318,38 @@ void configuration_impl::load_secure_service(const boost::property_tree::ptree & } } -std::shared_ptr configuration_impl::get_debounce( +std::shared_ptr +configuration_impl::get_debounce(const std::string &_name, service_t _service, instance_t _instance, event_t _event) const { + + // Try to find application (client) specific debounce configuration + auto found_application = applications_.find(_name); + if (found_application != applications_.end()) { + auto found_service = found_application->second.debounces_.find(_service); + if (found_service != found_application->second.debounces_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_event = found_instance->second.find(_event); + if (found_event != found_instance->second.end()) { + return (found_event->second); + } + } + } + } + + // If no application specific configuration was found, search for a + // generic auto found_service = debounces_.find(_service); if (found_service != debounces_.end()) { auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { auto found_event = found_instance->second.find(_event); if (found_event != found_instance->second.end()) { - return found_event->second; + return (found_event->second); } } } - return nullptr; + return (nullptr); } void @@ -4141,13 +4606,6 @@ void configuration_impl::set_sd_acceptance_rule( } } -void configuration_impl::set_sd_acceptance_rules( - const sd_acceptance_rules_t& _rules, bool _enable) { - // Unused, only still available to preserve compatibility - (void)_rules; - (void)_enable; -} - configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules() { std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); return sd_acceptance_rules_; @@ -4155,6 +4613,7 @@ configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules void configuration_impl::set_sd_acceptance_rules_active( const boost::asio::ip::address& _address, bool _enable) { + std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); if (_enable) { sd_acceptance_rules_active_.insert(_address); } else { @@ -4171,64 +4630,84 @@ bool configuration_impl::is_secure_service(service_t _service, instance_t _insta } int configuration_impl::get_udp_receive_buffer_size() const { - return udp_receive_buffer_size_; + + return (udp_receive_buffer_size_); } -bool configuration_impl::tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, std::uint16_t _port_target, +bool configuration_impl::is_tp_client( + service_t _service, + const std::string &_address, std::uint16_t _port, method_t _method) const { + bool ret(false); - const service* const its_service = find_service_by_ip_port(_service, - _ip_target, _port_target); + + const auto its_service + = find_service(_service, _address, _port); + if (its_service) { - ret = (its_service->tp_segment_messages_client_to_service_.find(_method) - != its_service->tp_segment_messages_client_to_service_.end()); + ret = (its_service->tp_client_config_.find(_method) + != its_service->tp_client_config_.end()); } + return ret; } -bool configuration_impl::tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, - std::uint16_t _port_service, method_t _method) const { +bool configuration_impl::is_tp_service( + service_t _service, + const std::string &_address, std::uint16_t _port, + method_t _method) const { + bool ret(false); - const service* const its_service = find_service_by_ip_port(_service, - _ip_service, _port_service); + const auto its_service + = find_service(_service, _address, _port); if (its_service) { - ret = (its_service->tp_segment_messages_service_to_client_.find(_method) - != its_service->tp_segment_messages_service_to_client_.end()); + ret = (its_service->tp_service_config_.find(_method) + != its_service->tp_service_config_.end()); } + return ret; } -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS -bool -configuration_impl::has_overlay(const std::string &_name) const { - auto its_application = applications_.find(_name); - return (its_application != applications_.end() - && !std::get<7>(its_application->second).empty()); -} +void configuration_impl::get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, + bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const { -void -configuration_impl::load_overlay(const std::string &_name) { - std::set its_input; - std::vector its_elements; - std::set its_failed; + const auto its_info = find_service(_service, _instance); + if (its_info) { + if (_is_client) { + auto its_method = its_info->tp_client_config_.find(_method); - auto its_application = applications_.find(_name); - if (its_application != applications_.end()) { - std::string its_overlay(std::get<7>(its_application->second)); + // Note: The following two lines do not make sense now, + // but they will when TP configuration is reworked + if (its_method == its_info->tp_client_config_.end()) + its_method = its_info->tp_client_config_.find(ANY_METHOD); - its_input.insert(its_overlay); - read_data(its_input, its_elements, its_failed, false); + if (its_method != its_info->tp_client_config_.end()) { + _max_segment_length = its_method->second.first; + _separation_time = its_method->second.second; + return; + } + } else { + auto its_method = its_info->tp_service_config_.find(_method); - for (const auto& f : its_failed) - VSOMEIP_ERROR << "Reading configuration data from " << f << " failed!"; + // Note: The following two lines do not make sense now, + // but they will when TP configuration is reworked + if (its_method == its_info->tp_service_config_.end()) + its_method = its_info->tp_service_config_.find(ANY_METHOD); - is_overlay_ = true; - load_data(its_elements, true, true); + if (its_method != its_info->tp_service_config_.end()) { + _max_segment_length = its_method->second.first; + _separation_time = its_method->second.second; + return; + } + } } + + // No configuration defined --> set default values + _max_segment_length = VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT; + _separation_time = 0; } -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS std::uint32_t configuration_impl::get_shutdown_timeout() const { return shutdown_timeout_; @@ -4272,5 +4751,45 @@ configuration_impl::get_partition_id( return (its_id); } +reliability_type_e +configuration_impl::get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const { + + if (_reliable_port != ILLEGAL_PORT + && _unreliable_port != ILLEGAL_PORT + && !_reliable_address.is_unspecified() + && !_unreliable_address.is_unspecified()) { + return reliability_type_e::RT_BOTH; + } else if (_unreliable_port != ILLEGAL_PORT + && !_unreliable_address.is_unspecified()) { + return reliability_type_e::RT_UNRELIABLE; + } else if (_reliable_port != ILLEGAL_PORT + && !_reliable_address.is_unspecified()) { + return reliability_type_e::RT_RELIABLE; + } + return reliability_type_e::RT_UNKNOWN; +} + +bool +configuration_impl::is_security_enabled() const { + + return (is_security_enabled_); +} + +bool +configuration_impl::is_security_audit() const { + + return (is_security_audit_); +} + +bool +configuration_impl::is_remote_access_allowed() const { + + return (is_remote_access_allowed_); +} + } // namespace cfg } // namespace vsomeip_v3 diff --git a/implementation/configuration/src/configuration_plugin_impl.cpp b/implementation/configuration/src/configuration_plugin_impl.cpp index df175f337..2293c0902 100644 --- a/implementation/configuration/src/configuration_plugin_impl.cpp +++ b/implementation/configuration/src/configuration_plugin_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -22,31 +22,29 @@ configuration_plugin_impl::~configuration_plugin_impl() { } std::shared_ptr -configuration_plugin_impl::get_configuration(const std::string &_name) { +configuration_plugin_impl::get_configuration(const std::string &_name, + const std::string &_path) { + std::lock_guard its_lock(mutex_); if (!default_) { - default_ = std::make_shared(); + default_ = std::make_shared(_path); default_->load(_name); } + return default_; -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - auto its_configuration(default_); - if (its_configuration->has_overlay(_name)) { - VSOMEIP_INFO << "Loading configuration overlay for \"" << _name << "\""; - auto its_iterator = configurations_.find(_name); - if (its_iterator != configurations_.end()) { - its_configuration = its_iterator->second; - } else { - its_configuration = std::make_shared( - *(its_configuration.get())); - its_configuration->load_overlay(_name); - configurations_[_name] = its_configuration; - } +#if 0 + std::shared_ptr its_configuration; + auto its_iterator = configurations_.find(_name); + if (its_iterator != configurations_.end()) { + its_configuration = its_iterator->second; + } else { + its_configuration = std::make_shared(_path); + its_configuration->load(_name); + configurations_[_name] = its_configuration; } - return its_configuration; -#else - return default_; -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS + + return (its_configuration); +#endif } } // namespace vsomeip_v3 diff --git a/implementation/e2e_protection/include/buffer/buffer.hpp b/implementation/e2e_protection/include/buffer/buffer.hpp index 8583ede97..95205f8db 100644 --- a/implementation/e2e_protection/include/buffer/buffer.hpp +++ b/implementation/e2e_protection/include/buffer/buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/crc/crc.hpp b/implementation/e2e_protection/include/crc/crc.hpp index b8d5688d6..de0ccec1b 100644 --- a/implementation/e2e_protection/include/crc/crc.hpp +++ b/implementation/e2e_protection/include/crc/crc.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp index 41d7487bf..51e42e17f 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -37,4 +37,3 @@ class e2e_provider { } // namespace vsomeip_v3 #endif // VSOMEIP_V3_E2E_PROVIDER_HPP - diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp index 62db2e277..631f87f29 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -71,4 +71,3 @@ class e2e_provider_impl : } // namespace vsomeip_v3 #endif // VSOMEIP_V3_E2E_PROVIDER_IMPL_HPP - diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp index 418499603..8f97113e0 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp index 54b2d5c46..097d9f569 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp index 13bd524ac..7e3799309 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp index c16eb1087..2ed3ebdc9 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,8 @@ #ifndef VSOMEIP_V3_E2E_PROFILE04_CHECKER_HPP #define VSOMEIP_V3_E2E_PROFILE04_CHECKER_HPP +#include + #include "../profile04/profile_04.hpp" #include "../profile_interface/checker.hpp" @@ -20,14 +22,14 @@ class profile_04_checker final : public e2e::profile_interface::checker { // [SWS_E2E_00389] initialize state explicit profile_04_checker(const profile_config &_config) : - config_(_config), counter_(0xffff) {} + config_(_config) {} void check(const e2e_buffer &_buffer, instance_t _instance, e2e::profile_interface::check_status_t &_generic_check_status) override final; private: bool verify_input(const e2e_buffer &_buffer) const; - bool verify_counter(uint16_t _received_counter) const; + bool verify_counter(instance_t _instance, uint16_t _received_counter); bool read_16(const e2e_buffer &_buffer, uint16_t &_data, size_t _index) const; bool read_32(const e2e_buffer &_buffer, uint32_t &_data, size_t _index) const; @@ -35,7 +37,7 @@ class profile_04_checker final : public e2e::profile_interface::checker { std::mutex check_mutex_; profile_config config_; - uint16_t counter_; + std::map counter_; }; } // namespace profile_04 diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp index 88be05c9f..11a7ee7e1 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp index fd4a6e73a..eab0a9a7a 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,9 @@ #ifndef VSOMEIP_V3_E2E_PROFILE04_PROTECTOR_HPP #define VSOMEIP_V3_E2E_PROFILE04_PROTECTOR_HPP +#include #include + #include "../profile04/profile_04.hpp" #include "../profile_interface/protector.hpp" @@ -19,20 +21,21 @@ class protector final : public e2e::profile_interface::protector { protector(void) = delete; explicit protector(const profile_config &_config) - : config_(_config), counter_(0) {}; + : config_(_config) {} void protect(e2e_buffer &_buffer, instance_t _instance) override final; private: bool verify_inputs(e2e_buffer &_buffer); - void increment_counter(); + uint16_t get_counter(instance_t _instance) const; + void increment_counter(instance_t _instance); void write_16(e2e_buffer &_buffer, uint16_t _data, size_t _index); void write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index); private: profile_config config_; - uint16_t counter_; + std::map counter_; std::mutex protect_mutex_; }; diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp index e23320524..94d54564e 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp index 244989d17..0a97ff1b1 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp index a2ec5d158..2396b5ad0 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp index 12cb6b77a..1bdf44744 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp index 5fa018cf9..5079e7e37 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,7 @@ namespace vsomeip_v3 { namespace e2e { namespace profile_interface { -typedef uint8_t check_status_t; +using check_status_t = std::uint8_t; enum generic_check_status : check_status_t { E2E_OK, E2E_WRONG_CRC, E2E_ERROR}; diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp index 4b02971db..20c63d527 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2exf/config.hpp b/implementation/e2e_protection/include/e2exf/config.hpp index a022d8c87..9c10504f8 100644 --- a/implementation/e2e_protection/include/e2exf/config.hpp +++ b/implementation/e2e_protection/include/e2exf/config.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/buffer/buffer.cpp b/implementation/e2e_protection/src/buffer/buffer.cpp index d50310bbc..6d82622bf 100644 --- a/implementation/e2e_protection/src/buffer/buffer.cpp +++ b/implementation/e2e_protection/src/buffer/buffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/crc/crc.cpp b/implementation/e2e_protection/src/crc/crc.cpp index 60ddb6cf7..18c7ec739 100644 --- a/implementation/e2e_protection/src/crc/crc.cpp +++ b/implementation/e2e_protection/src/crc/crc.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -30,7 +30,11 @@ namespace vsomeip_v3 { uint8_t e2e_crc::calculate_profile_01(buffer_view _buffer_view, const uint8_t _start_value) { uint8_t crc = _start_value ^ 0xFFU; for (uint8_t byte : _buffer_view) { - crc = static_cast(lookup_table_profile_01_[static_cast((byte) ^ crc)] ^ (crc >> 8U)); + /* + * XXX Right-shifting 8 bits on uint8_t results in 0 every time. + * It is, quintessentially, shifting all bits into the void. + */ + crc = static_cast(lookup_table_profile_01_[static_cast((byte) ^ crc)]/* ^ (crc >> 8U)*/); } crc = crc ^ 0xFFU; return crc; @@ -181,4 +185,3 @@ const uint32_t e2e_crc::lookup_table_profile_custom_[256] = { }; } // namespace vsomeip_v3 - diff --git a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp index 111e126e6..0d05fcabc 100644 --- a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp +++ b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp index a5d75d874..d70dac6da 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/checker.hpp" -#include -#include -#include -#include #include #include +#include +#include "../../../../include/e2e/profile/profile01/checker.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile01 { diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp index 358dd4eb6..032bac033 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp @@ -1,14 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/profile_01.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" -#include -#include -#include -#include +#include "../../../../include/e2e/profile/profile01/profile_01.hpp" +#include "../../../../include/crc/crc.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp index e5cb4baa7..0f514a029 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/protector.hpp" -#include -#include -#include -#include #include +#include +#include "../../../../include/e2e/profile/profile01/protector.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile01 { diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp index c9761ca7d..88c019247 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,10 +6,9 @@ #include #include -#include "../../utility/include/byteorder.hpp" - -#include "../../../../../e2e_protection/include/e2e/profile/profile04/checker.hpp" +#include "../../../../include/e2e/profile/profile04/checker.hpp" +#include "../../../../../utility/include/byteorder.hpp" namespace vsomeip_v3 { namespace e2e { @@ -51,10 +50,9 @@ void profile_04_checker::check(const e2e_buffer &_buffer, instance_t _instance, uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); if (its_received_data_id == its_data_id && static_cast(its_received_length) == _buffer.size() - && verify_counter(its_received_counter)) { - _generic_check_status = e2e::profile_interface::generic_check_status::E2E_OK; + && verify_counter(_instance, its_received_counter)) { + _generic_check_status = e2e::profile_interface::generic_check_status::E2E_OK; } - counter_ = its_received_counter; } } } @@ -72,18 +70,19 @@ profile_04_checker::verify_input(const e2e_buffer &_buffer) const { } bool -profile_04_checker::verify_counter(uint16_t _received_counter) const { +profile_04_checker::verify_counter(instance_t _instance, uint16_t _received_counter) { - static bool has_counter(false); uint16_t its_delta(0); - if (has_counter) { - if (counter_ < _received_counter) - its_delta = uint16_t(_received_counter - counter_); + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) { + uint16_t its_counter = find_counter->second; + if (its_counter < _received_counter) + its_delta = uint16_t(_received_counter - its_counter); else - its_delta = uint16_t(uint16_t(0xffff) - counter_ + _received_counter); + its_delta = uint16_t(uint16_t(0xffff) - its_counter + _received_counter); } else { - has_counter = true; + counter_[_instance] = _received_counter; } return (its_delta <= config_.max_delta_counter_); diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp index 05ab5e975..43a938045 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp @@ -1,15 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include -#include -#include -#include - -#include "../../../../../e2e_protection/include/e2e/profile/profile04/profile_04.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" +#include "../../../../include/crc/crc.hpp" +#include "../../../../include/e2e/profile/profile04/profile_04.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp index a9287f2cb..bc7d0db8f 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp @@ -1,14 +1,13 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include -#include "../../../../../e2e_protection/include/e2e/profile/profile04/protector.hpp" - #include -#include "../../utility/include/byteorder.hpp" +#include "../../../../include/e2e/profile/profile04/protector.hpp" +#include "../../../../../utility/include/byteorder.hpp" namespace vsomeip_v3 { namespace e2e { @@ -31,7 +30,7 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { write_16(_buffer, static_cast(_buffer.size()), 0); /** @req [SWS_E2E_00365] */ - write_16(_buffer, counter_, 2); + write_16(_buffer, get_counter(_instance), 2); /** @req [SWS_E2E_00366] */ uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); @@ -44,7 +43,7 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { write_32(_buffer, its_crc, 8); /** @req [SWS_E2E_00369] */ - increment_counter(); + increment_counter(_instance); } } @@ -71,9 +70,26 @@ protector::write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index) { _buffer[config_.offset_ + _index + 3] = VSOMEIP_LONG_BYTE0(_data); } +uint16_t +protector::get_counter(instance_t _instance) const { + + uint16_t its_counter(0); + + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) + its_counter = find_counter->second; + + return (its_counter); +} + void -protector::increment_counter() { - counter_++; +protector::increment_counter(instance_t _instance) { + + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) + find_counter->second++; + else + counter_[_instance] = 1; } } // namespace profile04 diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp index 9916a2fb7..bce5af95f 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/checker.hpp" -#include -#include -#include -#include #include #include +#include +#include "../../../../include/e2e/profile/profile_custom/checker.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile_custom { diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp index 5ab53caff..4e2936ede 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp @@ -1,14 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" -#include -#include -#include -#include +#include "../../../../include/crc/crc.hpp" +#include "../../../../include/e2e/profile/profile_custom/profile_custom.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp index c71f91f27..1fd0ccb71 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp @@ -1,16 +1,9 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/protector.hpp" - -#include -#include -#include -#include -#include -#include +#include "../../../../include/e2e/profile/profile_custom/protector.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2exf/config.cpp b/implementation/e2e_protection/src/e2exf/config.cpp index 20a3b71e7..6f124d3db 100644 --- a/implementation/e2e_protection/src/e2exf/config.cpp +++ b/implementation/e2e_protection/src/e2exf/config.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp index af0582d2e..089a5263d 100644 --- a/implementation/endpoints/include/buffer.hpp +++ b/implementation/endpoints/include/buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,13 +11,18 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +#define io_context io_service +#else +# include +#endif #include #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_MSVC_LANG) #define DEFAULT_NANOSECONDS_MAX 1000000000 #else #define DEFAULT_NANOSECONDS_MAX std::chrono::nanoseconds::max() @@ -25,37 +30,41 @@ namespace vsomeip_v3 { -typedef std::vector message_buffer_t; -typedef std::shared_ptr message_buffer_ptr_t; +using message_buffer_t = std::vector; +using message_buffer_ptr_t = std::shared_ptr; +#if 0 struct timing { timing() : debouncing_(0), maximum_retention_(DEFAULT_NANOSECONDS_MAX) {}; std::chrono::nanoseconds debouncing_; std::chrono::nanoseconds maximum_retention_; }; +#endif struct train { - train(boost::asio::io_service& _io) : buffer_(std::make_shared()), - departure_(DEFAULT_NANOSECONDS_MAX), - minimal_debounce_time_(DEFAULT_NANOSECONDS_MAX), - minimal_max_retention_time_(DEFAULT_NANOSECONDS_MAX), - last_departure_(std::chrono::steady_clock::now() - std::chrono::hours(1)), - departure_timer_(std::make_shared(_io)) {}; + train() + : buffer_(std::make_shared()), + minimal_debounce_time_(DEFAULT_NANOSECONDS_MAX), + minimal_max_retention_time_(DEFAULT_NANOSECONDS_MAX), + departure_(std::chrono::steady_clock::now() + std::chrono::hours(6)) { + }; + + void reset() { + buffer_ = std::make_shared(); + passengers_.clear(); + minimal_debounce_time_ = DEFAULT_NANOSECONDS_MAX; + minimal_max_retention_time_ = DEFAULT_NANOSECONDS_MAX; + departure_ = std::chrono::steady_clock::now() + std::chrono::hours(6); + } message_buffer_ptr_t buffer_; - std::chrono::nanoseconds departure_; + std::set > passengers_; + std::chrono::nanoseconds minimal_debounce_time_; std::chrono::nanoseconds minimal_max_retention_time_; - std::chrono::steady_clock::time_point last_departure_; - std::shared_ptr departure_timer_; - std::set > passengers_; - void update_departure_time_and_stop_departure() { - departure_ = departure_timer_->expires_from_now(); - boost::system::error_code ec; - departure_timer_->cancel(ec); - } + std::chrono::steady_clock::time_point departure_; }; diff --git a/implementation/endpoints/include/client_endpoint.hpp b/implementation/endpoints/include/client_endpoint.hpp index 3429a9255..372a12258 100644 --- a/implementation/endpoints/include/client_endpoint.hpp +++ b/implementation/endpoints/include/client_endpoint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,12 +12,7 @@ namespace vsomeip_v3 { class client_endpoint : public virtual endpoint { public: - virtual ~client_endpoint() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~client_endpoint() {} virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0; virtual std::uint16_t get_remote_port() const = 0; diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index 518e696e1..f7e7567fd 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,15 +6,15 @@ #ifndef VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ +#include #include #include #include #include -#include #include +#include #include -#include #include #include #include @@ -35,13 +35,13 @@ template class client_endpoint_impl: public endpoint_impl, public client_endpoint, public std::enable_shared_from_this > { public: - typedef typename Protocol::endpoint endpoint_type; - typedef typename Protocol::socket socket_type; + using endpoint_type = typename Protocol::endpoint; + using socket_type = typename Protocol::socket; client_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -56,7 +56,7 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi const byte_t *_data, uint32_t _size); bool flush(); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, service_t _service); + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); virtual void stop(); virtual void restart(bool _force = false) = 0; @@ -78,6 +78,7 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi public: void connect_cbk(boost::system::error_code const &_error); void wait_connect_cbk(boost::system::error_code const &_error); + void wait_connecting_cbk(boost::system::error_code const &_error); virtual void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); void flush_cbk(boost::system::error_code const &_error); @@ -94,8 +95,8 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi CONNECTED, ESTABLISHED }; - message_buffer_ptr_t get_front(); - virtual void send_queued(message_buffer_ptr_t _buffer) = 0; + std::pair get_front(); + virtual void send_queued(std::pair &_entry) = 0; virtual void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -103,10 +104,13 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi void shutdown_and_close_socket(bool _recreate_socket); void shutdown_and_close_socket_unlocked(bool _recreate_socket); void start_connect_timer(); + void start_connecting_timer(); typename endpoint_impl::cms_ret_e check_message_size( const std::uint8_t * const _data, std::uint32_t _size); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size) const; - void queue_train(bool _queue_size_zero_on_entry); + void queue_train(const std::shared_ptr &_train, + bool _queue_size_zero_on_entry); + void update_last_departure(); protected: mutable std::mutex socket_mutex_; @@ -121,10 +125,20 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi std::atomic state_; std::atomic reconnect_counter_; - // send data - train train_; + std::mutex connecting_timer_mutex_; + boost::asio::steady_timer connecting_timer_; + std::atomic connecting_timeout_; + - std::deque queue_; + // send data + std::shared_ptr train_; + std::map > > dispatched_trains_; + boost::asio::steady_timer dispatch_timer_; + std::chrono::steady_clock::time_point last_departure_; + std::atomic has_last_departure_; + + std::deque > queue_; std::size_t queue_size_; mutable std::mutex mutex_; @@ -133,7 +147,7 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi std::atomic local_port_; - boost::asio::io_service::strand strand_; + boost::asio::io_context::strand strand_; private: virtual void set_local_port() = 0; @@ -142,8 +156,13 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi method_t _method) const = 0; virtual std::uint32_t get_max_allowed_reconnects() const = 0; virtual void max_allowed_reconnects_reached() = 0; - void send_segments(const tp::tp_split_messages_t &_segments); - void wait_until_debounce_time_reached() const; + void send_segments(const tp::tp_split_messages_t &_segments, + std::uint32_t _separation_time); + + void schedule_train(); + + void start_dispatch_timer(const std::chrono::steady_clock::time_point &_now); + void cancel_dispatch_timer(); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/credentials.hpp b/implementation/endpoints/include/credentials.hpp index 2fe906098..bb4ee448f 100644 --- a/implementation/endpoints/include/credentials.hpp +++ b/implementation/endpoints/include/credentials.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,10 @@ #ifndef VSOMEIP_V3_ENDPOINTS_INCLUDE_CREDENTIALS_HPP_ #define VSOMEIP_V3_ENDPOINTS_INCLUDE_CREDENTIALS_HPP_ +#include + +#include + #include namespace vsomeip_v3 { @@ -16,9 +20,10 @@ class credentials { static void deactivate_credentials(const int _fd); - static client_t receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid); + using received_t = std::tuple; + static boost::optional receive_credentials(const int _fd); - static void send_credentials(const int _fd, client_t _client); + static void send_credentials(const int _fd, client_t _client, std::string _client_host); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index 3eafc3ae4..f3a76b77e 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,18 +19,13 @@ class endpoint_definition; class endpoint { public: - typedef std::function error_handler_t; - typedef std::function&, service_t)> prepare_stop_handler_t; + using error_handler_t = std::function; + using prepare_stop_handler_t = std::function&, service_t)>; - virtual ~endpoint() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~endpoint() {} virtual void start() = 0; - virtual void prepare_stop(prepare_stop_handler_t _handler, + virtual void prepare_stop(const prepare_stop_handler_t &_handler, service_t _service = ANY_SERVICE) = 0; virtual void stop() = 0; @@ -38,8 +33,6 @@ class endpoint { virtual bool is_established_or_connected() const = 0; virtual bool send(const byte_t *_data, uint32_t _size) = 0; - virtual bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size) = 0; virtual bool send_to(const std::shared_ptr _target, const byte_t *_data, uint32_t _size) = 0; virtual bool send_error(const std::shared_ptr _target, @@ -62,7 +55,7 @@ class endpoint { virtual void restart(bool _force = false) = 0; - virtual void register_error_handler(error_handler_t _error) = 0; + virtual void register_error_handler(const error_handler_t &_error) = 0; virtual void print_status() = 0; virtual size_t get_queue_size() const = 0; diff --git a/implementation/endpoints/include/endpoint_definition.hpp b/implementation/endpoints/include/endpoint_definition.hpp index 5a7e9eb8e..2dca226ea 100644 --- a/implementation/endpoints/include/endpoint_definition.hpp +++ b/implementation/endpoints/include/endpoint_definition.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/endpoint_host.hpp b/implementation/endpoints/include/endpoint_host.hpp index 2af1697cd..e5ca6d131 100644 --- a/implementation/endpoints/include/endpoint_host.hpp +++ b/implementation/endpoints/include/endpoint_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,19 +23,31 @@ namespace vsomeip_v3 { class configuration; class endpoint; +struct multicast_option_t { + std::shared_ptr endpoint_; + bool is_join_; + boost::asio::ip::address address_; +}; + class endpoint_host { public: virtual ~endpoint_host() = default; virtual void on_connect(std::shared_ptr _endpoint) = 0; virtual void on_disconnect(std::shared_ptr _endpoint) = 0; - virtual bool on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port) = 0; + virtual bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port) = 0; virtual void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port) = 0; + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port) = 0; virtual void release_port(uint16_t _port, bool _reliable) = 0; virtual client_t get_client() const = 0; + virtual std::string get_client_host() const = 0; + virtual instance_t find_instance(service_t _service, + endpoint * const _endpoint) const = 0; + virtual void add_multicast_option(const multicast_option_t &_option) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 76f469899..730c29093 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,6 @@ #include #include -#include #include #include "buffer.hpp" @@ -26,12 +25,12 @@ class routing_host; template class endpoint_impl: public virtual endpoint { public: - typedef typename Protocol::endpoint endpoint_type; + using endpoint_type = typename Protocol::endpoint; endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -50,7 +49,7 @@ class endpoint_impl: public virtual endpoint { void decrement_use_count(); uint32_t get_use_count(); - void register_error_handler(error_handler_t _error_handler); + void register_error_handler(const error_handler_t &_error_handler); virtual void print_status() = 0; virtual size_t get_queue_size() const = 0; @@ -63,6 +62,7 @@ class endpoint_impl: public virtual endpoint { protected: uint32_t find_magic_cookie(byte_t *_buffer, size_t _size); + instance_t get_instance(service_t _service); protected: enum class cms_ret_e : uint8_t { @@ -72,7 +72,7 @@ class endpoint_impl: public virtual endpoint { }; // Reference to service context - boost::asio::io_service &service_; + boost::asio::io_context &io_; // References to hosts std::weak_ptr endpoint_host_; diff --git a/implementation/endpoints/include/endpoint_manager_base.hpp b/implementation/endpoints/include/endpoint_manager_base.hpp index aa21269d1..fec39cce0 100644 --- a/implementation/endpoints/include/endpoint_manager_base.hpp +++ b/implementation/endpoints/include/endpoint_manager_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,12 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include @@ -23,7 +28,6 @@ namespace vsomeip_v3 { class routing_manager_base; class configuration; -class local_server_endpoint_impl; class routing_host; class endpoint_manager_base @@ -31,7 +35,7 @@ class endpoint_manager_base public endpoint_host { public: endpoint_manager_base(routing_manager_base* const _rm, - boost::asio::io_service& _io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~endpoint_manager_base() = default; @@ -44,23 +48,31 @@ class endpoint_manager_base std::unordered_set get_connected_clients() const; - std::shared_ptr create_local_server( + std::shared_ptr create_local_server( const std::shared_ptr &_routing_host); // endpoint_host interface virtual void on_connect(std::shared_ptr _endpoint); virtual void on_disconnect(std::shared_ptr _endpoint); - virtual bool on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port); + virtual bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port); virtual void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); virtual void release_port(uint16_t _port, bool _reliable); client_t get_client() const; + std::string get_client_host() const; + instance_t find_instance(service_t _service, + endpoint* const _endpoint) const; // Statistics void log_client_states() const; + // Multicast options + void add_multicast_option(const multicast_option_t &_option); + protected: std::map> get_local_endpoints() const; @@ -68,14 +80,23 @@ class endpoint_manager_base std::shared_ptr create_local_unlocked(client_t _client); std::shared_ptr find_local_unlocked(client_t _client); + bool get_local_server_port(port_t &_port, const std::set &_used_ports) const; + protected: routing_manager_base* const rm_; - boost::asio::io_service& io_; + boost::asio::io_context &io_; std::shared_ptr configuration_; + bool is_local_routing_; + port_t local_port_; // local (client) port when connecting to other + // vsomeip application via TCP + private: mutable std::mutex local_endpoint_mutex_; std::map > local_endpoints_; + + mutable std::mutex create_local_server_endpoint_mutex_; + }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint_manager_impl.hpp b/implementation/endpoints/include/endpoint_manager_impl.hpp index 335494711..a354fb58c 100644 --- a/implementation/endpoints/include/endpoint_manager_impl.hpp +++ b/implementation/endpoints/include/endpoint_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,10 @@ #ifndef VSOMEIP_V3_ENDPOINT_MANAGER_IMPL_HPP_ #define VSOMEIP_V3_ENDPOINT_MANAGER_IMPL_HPP_ +#include +#include +#include + #include "../include/endpoint_manager_base.hpp" namespace vsomeip_v3 { @@ -15,9 +19,9 @@ class routing_host; class endpoint_manager_impl : public endpoint_manager_base { public: endpoint_manager_impl(routing_manager_base* const _rm, - boost::asio::io_service& _io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); - ~endpoint_manager_impl() = default; + ~endpoint_manager_impl(); std::shared_ptr find_or_create_remote_client(service_t _service, instance_t _instance, @@ -66,9 +70,10 @@ class endpoint_manager_impl : public endpoint_manager_base { void print_status() const; - std::shared_ptr create_local_server( - bool* _is_socket_activated, - const std::shared_ptr& _routing_host); + bool create_routing_root( + std::shared_ptr &_root, + bool &_is_socket_activated, + const std::shared_ptr &_host); instance_t find_instance(service_t _service, endpoint* const _endpoint) const; @@ -83,17 +88,30 @@ class endpoint_manager_impl : public endpoint_manager_base { void on_connect(std::shared_ptr _endpoint); void on_disconnect(std::shared_ptr _endpoint); bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); - void release_port(uint16_t _port, bool _reliable); + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); + + void get_used_client_ports( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + std::map > &_used_ports); + void request_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port); + void release_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port); // Statistics void log_client_states() const; void log_server_states() const; + // add join/leave options + void add_multicast_option(const multicast_option_t &_option); + private: std::shared_ptr find_remote_client(service_t _service, instance_t _instance, @@ -105,40 +123,49 @@ class endpoint_manager_impl : public endpoint_manager_base { const boost::asio::ip::address &_address, uint16_t _local_port, uint16_t _remote_port, bool _reliable); + // process join/leave options + void process_multicast_options(); + private: mutable std::recursive_mutex endpoint_mutex_; // Client endpoints for remote services std::map>>> remote_service_info_; - typedef std::map>>> remote_services_t; + using remote_services_t = + std::map>>>; remote_services_t remote_services_; - typedef std::map - > - > - > - > client_endpoints_by_ip_t; + using client_endpoints_by_ip_t = + std::map>>>>; client_endpoints_by_ip_t client_endpoints_by_ip_; std::map > service_instances_; std::map > service_instances_multicast_; - std::map> used_client_ports_; + std::map > + > + > used_client_ports_; std::mutex used_client_ports_mutex_; // Server endpoints for local services - typedef std::map>> server_endpoints_t; + using server_endpoints_t = std::map>>; server_endpoints_t server_endpoints_; // Multicast endpoint info (notifications) std::map>> multicast_info; + + // Socket option processing (join, leave) + std::mutex options_mutex_; + bool is_processing_options_; + std::condition_variable options_condition_; + std::queue options_queue_; + std::thread options_thread_; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp new file mode 100644 index 000000000..38e166236 --- /dev/null +++ b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp @@ -0,0 +1,118 @@ +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ +#define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ + +#if VSOMEIP_BOOST_VERSION >= 106600 +#if defined(__linux__) || defined(ANDROID) + +#include + +namespace vsomeip_v3 { + +using socket_type_t = boost::asio::local::stream_protocol::socket; +using receive_handler_t = std::function< + void (boost::system::error_code const &_error, size_t _size, + const std::uint32_t &, const std::uint32_t &)>; + +struct local_server_endpoint_impl_receive_op { + + socket_type_t &socket_; + receive_handler_t handler_; + byte_t *buffer_; + size_t length_; + uid_t uid_; + gid_t gid_; + size_t bytes_; + + void operator()(boost::system::error_code _error) { + + if (!_error) { + if (!socket_.native_non_blocking()) + socket_.native_non_blocking(true, _error); + + for (;;) { + ssize_t its_result; + int its_flags(0); + + // Set buffer + struct iovec its_vec[1]; + its_vec[0].iov_base = buffer_; + its_vec[0].iov_len = length_; + + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(struct ucred))]; + } control_un; + + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; + + // Build header with all informations to call ::recvmsg + msghdr its_header = msghdr(); + its_header.msg_iov = its_vec; + its_header.msg_iovlen = 1; + its_header.msg_control = control_un.control; + its_header.msg_controllen = sizeof(control_un.control); + + // Call recvmsg and handle its result + errno = 0; + its_result = ::recvmsg(socket_.native_handle(), &its_header, its_flags); + _error = boost::system::error_code(its_result < 0 ? errno : 0, + boost::asio::error::get_system_category()); + bytes_ += _error ? 0 : static_cast(its_result); + + if (_error == boost::asio::error::interrupted) + continue; + + if (_error == boost::asio::error::would_block + || _error == boost::asio::error::try_again) { + socket_.async_wait(socket_type_t::wait_read, *this); + return; + } + + if (_error) + break; + + if (bytes_ == 0) + _error = boost::asio::error::eof; + + // Extract credentials (UID/GID) + struct ucred *its_credentials; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) + { + if (cmsg->cmsg_level == SOL_SOCKET + && cmsg->cmsg_type == SCM_CREDENTIALS + && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { + + its_credentials = (struct ucred *) CMSG_DATA(cmsg); + if (its_credentials) { + uid_ = its_credentials->uid; + gid_ = its_credentials->gid; + break; + } + } + } + + break; + } + } + + // Call the handler + handler_(_error, bytes_, uid_, gid_); + } +}; + +} // namespace vsomeip + +#endif // __linux__ || ANDROID +#endif // VSOMEIP_BOOST_VERSION >= 106600 + +#endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp new file mode 100644 index 000000000..45b6e727f --- /dev/null +++ b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ + +#include + +#include + +#include "client_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_tcp_client_endpoint_base_impl = client_endpoint_impl; + +class local_tcp_client_endpoint_impl: public local_tcp_client_endpoint_base_impl { +public: + local_tcp_client_endpoint_impl(const std::shared_ptr &_endpoint_host, + const std::shared_ptr &_routing_host, + const endpoint_type &_local, + const endpoint_type &_remote, + boost::asio::io_context &_io, + const std::shared_ptr &_configuration); + + virtual ~local_tcp_client_endpoint_impl(); + + void start(); + void stop(); + + bool is_local() const; + + bool get_remote_address(boost::asio::ip::address &_address) const; + std::uint16_t get_remote_port() const; + + void restart(bool _force); + void print_status(); + + bool is_reliable() const; + + // this overrides client_endpoint_impl::send to disable the pull method + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; +private: + void send_queued(std::pair &_entry); + + void send_magic_cookie(); + + void connect(); + void receive(); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes); + void set_local_port(); + std::string get_remote_information() const; + bool check_packetizer_space(std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + std::uint32_t get_max_allowed_reconnects() const; + void max_allowed_reconnects_reached(); + + message_buffer_t recv_buffer_; + + // send data + message_buffer_ptr_t send_data_buffer_; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp new file mode 100644 index 000000000..d4b27c392 --- /dev/null +++ b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp @@ -0,0 +1,166 @@ +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ + +#include +#include +#include +#include + +#include + +#include + +#include "buffer.hpp" +#include "server_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_tcp_server_endpoint_base_impl = server_endpoint_impl; + +class local_tcp_server_endpoint_impl + : public local_tcp_server_endpoint_base_impl { + +public: + local_tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + virtual ~local_tcp_server_endpoint_impl(); + + void start(); + void stop(); + + void receive(); + + // this overrides server_endpoint_impl::send to disable the nPDU feature + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + bool send_to(const std::shared_ptr, + const byte_t *_data, uint32_t _size); + bool send_error(const std::shared_ptr _target, + const byte_t *_data, uint32_t _size); + bool send_queued(const target_data_iterator_type _queue_iterator); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; + + bool get_default_target(service_t, endpoint_type &) const; + + bool is_local() const; + + void accept_client_func(); + void print_status(); + + bool is_reliable() const; + std::uint16_t get_local_port() const; + void set_local_port(std::uint16_t _port); + + client_t assign_client(const byte_t *_data, uint32_t _size); + +private: + class connection: public std::enable_shared_from_this { + + public: + using ptr = std::shared_ptr; + + static ptr create(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + socket_type & get_socket(); + std::unique_lock get_socket_lock(); + + void start(); + void stop(); + + + void send_queued(const message_buffer_ptr_t& _buffer); + + void set_bound_client(client_t _client); + client_t get_bound_client() const; + + void set_bound_client_host(const std::string &_bound_client_host); + std::string get_bound_client_host() const; + + std::size_t get_recv_buffer_capacity() const; + + private: + connection(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + + void send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes); + void calculate_shrink_count(); + std::string get_path_local() const; + std::string get_path_remote() const; + void handle_recv_buffer_exception(const std::exception &_e); + + std::mutex socket_mutex_; + local_tcp_server_endpoint_impl::socket_type socket_; + std::weak_ptr server_; + + const std::uint32_t recv_buffer_size_initial_; + const std::uint32_t max_message_size_; + + message_buffer_t recv_buffer_; + size_t recv_buffer_size_; + std::uint32_t missing_capacity_; + std::uint32_t shrink_count_; + const std::uint32_t buffer_shrink_threshold_; + + client_t bound_client_; + std::string bound_client_host_; + + vsomeip_sec_client_t sec_client_; + + bool assigned_client_; + }; + + std::mutex acceptor_mutex_; + boost::asio::ip::tcp::acceptor acceptor_; + + using connections_t = std::map; + std::mutex connections_mutex_; + connections_t connections_; + + const std::uint32_t buffer_shrink_threshold_; + + port_t local_port_; + + const bool is_routing_endpoint_; + +private: + bool add_connection(const client_t &_client, + const std::shared_ptr &_connection); + void remove_connection(const client_t &_client); + void accept_cbk(const connection::ptr& _connection, + boost::system::error_code const &_error); + std::string get_remote_information( + const target_data_iterator_type _queue_iterator) const; + std::string get_remote_information( + const endpoint_type& _remote) const; + + bool check_packetizer_space(target_data_iterator_type _queue_iterator, + message_buffer_ptr_t* _packetizer, + std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + void send_client_identifier(const client_t &_client); +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp similarity index 57% rename from implementation/endpoints/include/local_client_endpoint_impl.hpp rename to implementation/endpoints/include/local_uds_client_endpoint_impl.hpp index 3eae19137..74ba316c9 100644 --- a/implementation/endpoints/include/local_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp @@ -1,43 +1,30 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ -#define VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ +#ifndef VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ -#include #include -#ifdef _WIN32 -#include -#endif - #include #include "client_endpoint_impl.hpp" namespace vsomeip_v3 { -#ifdef _WIN32 -typedef client_endpoint_impl< - boost::asio::ip::tcp - > local_client_endpoint_base_impl; -#else -typedef client_endpoint_impl< - boost::asio::local::stream_protocol - > local_client_endpoint_base_impl; -#endif - -class local_client_endpoint_impl: public local_client_endpoint_base_impl { -public: - local_client_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _remote, - boost::asio::io_service &_io, - const std::shared_ptr& _configuration); +using local_uds_client_endpoint_base_impl = + client_endpoint_impl; - virtual ~local_client_endpoint_impl(); +class local_uds_client_endpoint_impl: public local_uds_client_endpoint_base_impl { +public: + local_uds_client_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _remote, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration); + virtual ~local_uds_client_endpoint_impl(); void start(); void stop(); @@ -55,14 +42,12 @@ class local_client_endpoint_impl: public local_client_endpoint_base_impl { // this overrides client_endpoint_impl::send to disable the pull method // for local communication bool send(const uint8_t *_data, uint32_t _size); - bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const; private: - void send_queued(message_buffer_ptr_t _buffer); + void send_queued(std::pair &_entry); void send_magic_cookie(); @@ -85,4 +70,4 @@ class local_client_endpoint_impl: public local_client_endpoint_base_impl { } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ +#endif // VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp similarity index 59% rename from implementation/endpoints/include/local_server_endpoint_impl.hpp rename to implementation/endpoints/include/local_uds_server_endpoint_impl.hpp index 8fbb619ba..256d86618 100644 --- a/implementation/endpoints/include/local_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp @@ -1,60 +1,56 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ -#define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ +#ifndef VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ #include #include #include #include -#include -#include - - -#ifdef _WIN32 -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +#else +# include #endif #include +#include #include "buffer.hpp" #include "server_endpoint_impl.hpp" namespace vsomeip_v3 { -#ifdef _WIN32 -typedef server_endpoint_impl< - boost::asio::ip::tcp - > local_server_endpoint_base_impl; +using local_uds_server_endpoint_base_impl = server_endpoint_impl< +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext #else -typedef server_endpoint_impl< - boost::asio::local::stream_protocol_ext - > local_server_endpoint_base_impl; + boost::asio::local::stream_protocol #endif + >; -class local_server_endpoint_impl: public local_server_endpoint_base_impl { - +class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl { public: - local_server_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_service &_io, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint); - - local_server_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_service &_io, - int native_socket, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint); - - virtual ~local_server_endpoint_impl(); + local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + int native_socket, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + virtual ~local_uds_server_endpoint_impl(); void start(); void stop(); @@ -68,7 +64,7 @@ class local_server_endpoint_impl: public local_server_endpoint_base_impl { const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); + bool send_queued(const target_data_iterator_type _queue_iterator); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -91,52 +87,55 @@ class local_server_endpoint_impl: public local_server_endpoint_base_impl { class connection: public std::enable_shared_from_this { public: - typedef std::shared_ptr ptr; + using ptr = std::shared_ptr; - static ptr create(const std::shared_ptr& _server, + static ptr create(const std::shared_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service); + boost::asio::io_context &_io); socket_type & get_socket(); std::unique_lock get_socket_lock(); void start(); void stop(); - void send_queued(const message_buffer_ptr_t& _buffer); void set_bound_client(client_t _client); client_t get_bound_client() const; -#ifndef _WIN32 - void set_bound_uid_gid(uid_t _uid, gid_t _gid); + + void set_bound_client_host(const std::string &_bound_client_host); + std::string get_bound_client_host() const; + +#if defined(__linux__) || defined(ANDROID) + void set_bound_sec_client(const vsomeip_sec_client_t &_sec_client); #endif std::size_t get_recv_buffer_capacity() const; private: - connection(const std::shared_ptr& _server, + connection(const std::shared_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _initial_recv_buffer_size, std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service); + boost::asio::io_context &_io); void send_cbk(const message_buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes); void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) , std::uint32_t const &_uid, std::uint32_t const &_gid #endif ); void calculate_shrink_count(); - const std::string get_path_local() const; - const std::string get_path_remote() const; + std::string get_path_local() const; + std::string get_path_remote() const; void handle_recv_buffer_exception(const std::exception &_e); std::mutex socket_mutex_; - local_server_endpoint_impl::socket_type socket_; - std::weak_ptr server_; + local_uds_server_endpoint_impl::socket_type socket_; + std::weak_ptr server_; const std::uint32_t recv_buffer_size_initial_; const std::uint32_t max_message_size_; @@ -148,21 +147,20 @@ class local_server_endpoint_impl: public local_server_endpoint_base_impl { const std::uint32_t buffer_shrink_threshold_; client_t bound_client_; -#ifndef _WIN32 - uid_t bound_uid_; - gid_t bound_gid_; -#endif + std::string bound_client_host_; + + vsomeip_sec_client_t sec_client_; + bool assigned_client_; }; std::mutex acceptor_mutex_; -#ifdef _WIN32 - boost::asio::ip::tcp::acceptor acceptor_; -#else +#if VSOMEIP_BOOST_VERSION < 106600 boost::asio::local::stream_protocol_ext::acceptor acceptor_; +#else + boost::asio::local::stream_protocol::acceptor acceptor_; #endif - - typedef std::map connections_t; + using connections_t = std::map; std::mutex connections_mutex_; connections_t connections_; @@ -177,11 +175,11 @@ class local_server_endpoint_impl: public local_server_endpoint_base_impl { void accept_cbk(const connection::ptr& _connection, boost::system::error_code const &_error); std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; + const target_data_iterator_type _queue_iterator) const; std::string get_remote_information( const endpoint_type& _remote) const; - bool check_packetizer_space(queue_iterator_type _queue_iterator, + bool check_packetizer_space(target_data_iterator_type _queue_iterator, message_buffer_ptr_t* _packetizer, std::uint32_t _size); bool tp_segmentation_enabled(service_t _service, method_t _method) const; @@ -190,4 +188,4 @@ class local_server_endpoint_impl: public local_server_endpoint_base_impl { } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ +#endif // VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/netlink_connector.hpp b/implementation/endpoints/include/netlink_connector.hpp index bb484b885..0a7c94eff 100644 --- a/implementation/endpoints/include/netlink_connector.hpp +++ b/implementation/endpoints/include/netlink_connector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,7 @@ #ifndef VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ #define VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -27,23 +26,23 @@ template class nl_endpoint { public: /// The protocol type associated with the endpoint. - typedef Protocol protocol_type; - typedef boost::asio::detail::socket_addr_type data_type; + using protocol_type = Protocol; + using data_type = boost::asio::detail::socket_addr_type; /// Default constructor. nl_endpoint() { sockaddr.nl_family = PF_NETLINK; sockaddr.nl_groups = 0; - sockaddr.nl_pid = static_cast(getpid()); + sockaddr.nl_pid = 0; // Let the kernel do the assignment } /// Construct an endpoint using the specified path name. - nl_endpoint(int group, int pid=getpid()) + nl_endpoint(int group) { sockaddr.nl_family = PF_NETLINK; sockaddr.nl_groups = static_cast(group); - sockaddr.nl_pid = static_cast(pid); + sockaddr.nl_pid = 0; } /// Copy constructor. @@ -124,25 +123,31 @@ class nl_protocol { return PF_NETLINK; } - typedef nl_endpoint endpoint; - typedef boost::asio::basic_raw_socket socket; + using endpoint = nl_endpoint; + using socket = boost::asio::basic_raw_socket; private: int proto; }; -typedef std::function< void (bool, std::string, bool) > net_if_changed_handler_t; +using net_if_changed_handler_t = std::function< void ( + bool, // true = is interface, false = is route + std::string, // interface name + bool) // available? +>; class netlink_connector : public std::enable_shared_from_this { public: - netlink_connector(boost::asio::io_service& _io, boost::asio::ip::address _address, - boost::asio::ip::address _multicast_address): + netlink_connector(boost::asio::io_context &_io, const boost::asio::ip::address &_address, + const boost::asio::ip::address &_multicast_address, + bool _is_requiring_link = true): net_if_index_for_address_(0), handler_(nullptr), socket_(_io), recv_buffer_(recv_buffer_size, 0), address_(_address), - multicast_address_(_multicast_address) { + multicast_address_(_multicast_address), + is_requiring_link_(_is_requiring_link) { } ~netlink_connector() {} @@ -180,10 +185,11 @@ class netlink_connector : public std::enable_shared_from_this boost::asio::ip::address address_; boost::asio::ip::address multicast_address_; + bool is_requiring_link_; }; } // namespace vsomeip_v3 -#endif // NOT _WIN32 +#endif // __linux__ || ANDROID #endif // VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp index dfa22e634..b7ee74d67 100644 --- a/implementation/endpoints/include/server_endpoint_impl.hpp +++ b/implementation/endpoints/include/server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -14,7 +14,6 @@ #include #include -#include #include "buffer.hpp" #include "endpoint_impl.hpp" @@ -26,14 +25,33 @@ template class server_endpoint_impl: public endpoint_impl, public std::enable_shared_from_this > { public: - typedef typename Protocol::socket socket_type; - typedef typename Protocol::endpoint endpoint_type; - typedef typename std::map>> queue_type; - typedef typename queue_type::iterator queue_iterator_type; + using socket_type = typename Protocol::socket; + using endpoint_type = typename Protocol::endpoint; + struct endpoint_data_type { + endpoint_data_type(boost::asio::io_context &_io) + : train_(std::make_shared()), + dispatch_timer_(std::make_shared(_io)), + has_last_departure_(false), + queue_size_(0) { + } + + std::shared_ptr train_; + std::map > > dispatched_trains_; + std::shared_ptr dispatch_timer_; + std::chrono::steady_clock::time_point last_departure_; + bool has_last_departure_; + + std::deque > queue_; + std::size_t queue_size_; + }; + + using target_data_type = typename std::map; + using target_data_iterator_type = typename target_data_type::iterator; server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - endpoint_type _local, boost::asio::io_service &_io, + endpoint_type _local, boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -49,11 +67,10 @@ class server_endpoint_impl: public endpoint_impl, bool send(const std::vector& _cmd_header, const byte_t *_data, uint32_t _size); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); virtual void stop(); - bool flush(endpoint_type _target, - const std::shared_ptr& _train); + bool flush(target_data_iterator_type _it); size_t get_queue_size() const; @@ -63,16 +80,15 @@ class server_endpoint_impl: public endpoint_impl, public: void connect_cbk(boost::system::error_code const &_error); - void send_cbk(const queue_iterator_type _queue_iterator, + void send_cbk(const target_data_iterator_type _it, boost::system::error_code const &_error, std::size_t _bytes); - void flush_cbk(endpoint_type _target, - const std::shared_ptr& _train, - const boost::system::error_code &_error_code); + void flush_cbk(target_data_iterator_type _it, + const boost::system::error_code &_error_code); protected: virtual bool send_intern(endpoint_type _target, const byte_t *_data, uint32_t _port); - virtual void send_queued(const queue_iterator_type _queue_iterator) = 0; + virtual bool send_queued(const target_data_iterator_type _it) = 0; virtual void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -85,26 +101,23 @@ class server_endpoint_impl: public endpoint_impl, typename endpoint_impl::cms_ret_e check_message_size( const std::uint8_t * const _data, std::uint32_t _size, - const endpoint_type& _target); + const endpoint_type &_target); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size, std::size_t _current_queue_size) const; - void queue_train(const queue_iterator_type _queue_iterator, - const std::shared_ptr& _train, - bool _queue_size_zero_on_entry); - queue_iterator_type find_or_create_queue_unlocked(const endpoint_type& _target); - std::shared_ptr find_or_create_train_unlocked(const endpoint_type& _target); + bool queue_train(const target_data_iterator_type _it, + const std::shared_ptr &_train, + bool _queue_size_zero_on_entry); - void send_segments(const tp::tp_split_messages_t &_segments, const endpoint_type &_target); + void send_segments(const tp::tp_split_messages_t &_segments, + std::uint32_t _separation_time, const endpoint_type &_target); -protected: - queue_type queues_; + target_data_iterator_type find_or_create_target_unlocked(endpoint_type _target); - std::mutex requests_mutex_; - std::map, endpoint_type> - > requests_; +protected: + std::mutex clients_mutex_; + std::map > clients_; - std::map> trains_; + target_data_type targets_; std::map prepare_stop_handlers_; @@ -116,12 +129,18 @@ class server_endpoint_impl: public endpoint_impl, private: virtual std::string get_remote_information( - const queue_iterator_type _queue_iterator) const = 0; + const target_data_iterator_type _queue_iterator) const = 0; virtual std::string get_remote_information( const endpoint_type& _remote) const = 0; virtual bool tp_segmentation_enabled(service_t _service, method_t _method) const = 0; - void wait_until_debounce_time_reached(const std::shared_ptr& _train) const; + + void schedule_train(endpoint_data_type &_target); + void update_last_departure(endpoint_data_type &_data); + + void start_dispatch_timer(target_data_iterator_type _it, + const std::chrono::steady_clock::time_point &_now); + void cancel_dispatch_timer(target_data_iterator_type _it); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index 137571ce7..8a314bc61 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,9 +16,8 @@ namespace vsomeip_v3 { -typedef client_endpoint_impl< - boost::asio::ip::tcp - > tcp_client_endpoint_base_impl; +using tcp_client_endpoint_base_impl = + client_endpoint_impl; class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { public: @@ -26,7 +25,7 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~tcp_client_endpoint_impl(); @@ -42,7 +41,7 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); private: - void send_queued(message_buffer_ptr_t _buffer); + void send_queued(std::pair &_entry); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -63,8 +62,8 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { std::size_t _missing_capacity); void calculate_shrink_count(const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size); - const std::string get_address_port_remote() const; - const std::string get_address_port_local() const; + std::string get_address_port_remote() const; + std::string get_address_port_local() const; void handle_recv_buffer_exception(const std::exception &_e, const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size); diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index bf0e1b961..1a2cf4e59 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,9 +19,8 @@ namespace vsomeip_v3 { -typedef server_endpoint_impl< - boost::asio::ip::tcp - > tcp_server_endpoint_base_impl; +using tcp_server_endpoint_base_impl = + server_endpoint_impl; class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { @@ -29,7 +28,7 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~tcp_server_endpoint_impl(); @@ -40,14 +39,14 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); - void send_queued_sync(const queue_iterator_type _queue_iterator); + bool send_queued(const target_data_iterator_type _it); + void send_queued_sync(const target_data_iterator_type _it); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const; - VSOMEIP_EXPORT bool is_established(const std::shared_ptr& _endpoint); + VSOMEIP_EXPORT bool is_established_to(const std::shared_ptr& _endpoint); bool get_default_target(service_t, endpoint_type &) const; @@ -64,14 +63,17 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { class connection: public std::enable_shared_from_this { public: - typedef std::shared_ptr ptr; + using ptr = std::shared_ptr; static ptr create(const std::weak_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context & _io, std::chrono::milliseconds _send_timeout); + + ~connection(); + socket_type & get_socket(); std::unique_lock get_socket_lock(); @@ -79,11 +81,11 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { void stop(); void receive(); - void send_queued(const queue_iterator_type _queue_iterator); - void send_queued_sync(const queue_iterator_type _queue_iterator); + void send_queued(const target_data_iterator_type _it); + void send_queued_sync(const target_data_iterator_type _it); void set_remote_info(const endpoint_type &_remote); - const std::string get_address_port_remote() const; + std::string get_address_port_remote() const; std::size_t get_recv_buffer_capacity() const; private: @@ -92,14 +94,14 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { std::uint32_t _recv_buffer_size_initial, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout); bool send_magic_cookie(message_buffer_ptr_t &_buffer); bool is_magic_cookie(size_t _offset) const; void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes); void calculate_shrink_count(); - const std::string get_address_port_local() const; + std::string get_address_port_local() const; void handle_recv_buffer_exception(const std::exception &_e); std::size_t write_completion_condition( const boost::system::error_code& _error, @@ -134,7 +136,7 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { std::mutex acceptor_mutex_; boost::asio::ip::tcp::acceptor acceptor_; std::mutex connections_mutex_; - typedef std::map connections_t; + using connections_t = std::map; connections_t connections_; const std::uint32_t buffer_shrink_threshold_; const std::uint16_t local_port_; @@ -145,7 +147,7 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { void accept_cbk(const connection::ptr& _connection, boost::system::error_code const &_error); std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; + const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; }; diff --git a/implementation/endpoints/include/tp.hpp b/implementation/endpoints/include/tp.hpp index 0e3a9d028..ec185b286 100644 --- a/implementation/endpoints/include/tp.hpp +++ b/implementation/endpoints/include/tp.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,9 +24,9 @@ namespace tp { #define VSOMEIP_TP_PAYLOAD_POS 20 // 28 bit length + 3 bit reserved + 1 bit more segments -typedef std::uint32_t tp_header_t; -typedef std::uint8_t tp_message_type_t; -typedef std::vector tp_split_messages_t; +using tp_header_t = std::uint32_t; +using tp_message_type_t = std::uint8_t; +using tp_split_messages_t = std::vector; const std::uint8_t TP_FLAG = 0x20; @@ -49,9 +49,10 @@ class tp { } static tp_split_messages_t tp_split_message( - const std::uint8_t * const _data, std::uint32_t _size); + const std::uint8_t * const _data, std::uint32_t _size, + std::uint16_t _max_segment_length); - static const std::uint16_t tp_max_segment_length_; + static const std::uint16_t tp_max_segment_length_ = 1392; }; } // namespace tp diff --git a/implementation/endpoints/include/tp_message.hpp b/implementation/endpoints/include/tp_message.hpp index 269a1f108..13aef2d0f 100644 --- a/implementation/endpoints/include/tp_message.hpp +++ b/implementation/endpoints/include/tp_message.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/tp_reassembler.hpp b/implementation/endpoints/include/tp_reassembler.hpp index aaf61c5ef..5e50c8c12 100644 --- a/implementation/endpoints/include/tp_reassembler.hpp +++ b/implementation/endpoints/include/tp_reassembler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,8 +11,13 @@ #include #include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include -#include #include #include @@ -25,7 +30,7 @@ namespace tp { class tp_reassembler : public std::enable_shared_from_this { public: - tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_service &_io); + tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_context &_io); /** * @return Returns a pair consisting of a bool and a message_buffer_t. The * value of the bool is set to true if the pair contains a finished message diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 3a3fdcb03..56fcc2021 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,6 @@ #include -#include #include #include @@ -21,9 +20,8 @@ namespace vsomeip_v3 { class endpoint_adapter; -typedef client_endpoint_impl< - boost::asio::ip::udp - > udp_client_endpoint_base_impl; +using udp_client_endpoint_base_impl = + client_endpoint_impl; class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { @@ -32,7 +30,7 @@ class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~udp_client_endpoint_impl(); @@ -48,10 +46,10 @@ class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { void print_status(); bool is_reliable() const; - void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, - const message_buffer_ptr_t &_sent_msg); + void send_cbk(boost::system::error_code const &_error, + std::size_t _bytes, const message_buffer_ptr_t &_sent_msg); private: - void send_queued(message_buffer_ptr_t _buffer); + void send_queued(std::pair &_entry); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -59,8 +57,8 @@ class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { void connect(); void receive(); void set_local_port(); - const std::string get_address_port_remote() const; - const std::string get_address_port_local() const; + std::string get_address_port_remote() const; + std::string get_address_port_local() const; std::string get_remote_information() const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; @@ -69,7 +67,7 @@ class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { private: const boost::asio::ip::address remote_address_; const std::uint16_t remote_port_; - int udp_receive_buffer_size_; + const int udp_receive_buffer_size_; std::shared_ptr tp_reassembler_; }; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index fef09dc68..dd7e224e0 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,10 +6,11 @@ #ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 #include - -#include +#else +#include +#endif #include @@ -18,9 +19,13 @@ namespace vsomeip_v3 { -typedef server_endpoint_impl< - boost::asio::ip::udp_ext - > udp_server_endpoint_base_impl; +#if VSOMEIP_BOOST_VERSION < 106600 +using udp_server_endpoint_base_impl = + server_endpoint_impl; +#else +using udp_server_endpoint_base_impl = + server_endpoint_impl; +#endif class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { @@ -28,7 +33,7 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { udp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~udp_server_endpoint_impl(); @@ -41,7 +46,7 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); + bool send_queued(const target_data_iterator_type _it); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -49,7 +54,9 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { VSOMEIP_EXPORT void join(const std::string &_address); VSOMEIP_EXPORT void join_unlocked(const std::string &_address); - void leave(const std::string &_address); + VSOMEIP_EXPORT void leave(const std::string &_address); + VSOMEIP_EXPORT void set_multicast_option( + const boost::asio::ip::address &_address, bool _is_join); void add_default_target(service_t _service, const std::string &_address, uint16_t _port); @@ -71,33 +78,35 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { bool is_joined(const std::string &_address) const; bool is_joined(const std::string &_address, bool* _received) const; std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; + const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; - const std::string get_address_port_local() const; + std::string get_address_port_local() const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; void on_unicast_received(boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination); + std::size_t _bytes); void on_multicast_received(boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination, - uint8_t _multicast_id); + std::size_t _bytes, uint8_t _multicast_id, + const boost::asio::ip::address &_destination); void on_message_received(boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, + bool _is_multicast, endpoint_type const &_remote, message_buffer_t const &_buffer); + bool is_same_subnet(const boost::asio::ip::address &_address) const; + private: socket_type unicast_socket_; endpoint_type unicast_remote_; message_buffer_t unicast_recv_buffer_; mutable std::mutex unicast_mutex_; + bool is_v4_; + std::unique_ptr multicast_socket_; std::unique_ptr multicast_local_; endpoint_type multicast_remote_; @@ -110,6 +119,9 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { mutable std::mutex default_targets_mutex_; std::map default_targets_; + boost::asio::ip::address netmask_; + unsigned short prefix_; + const std::uint16_t local_port_; std::shared_ptr tp_reassembler_; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp new file mode 100644 index 000000000..71fad4d8f --- /dev/null +++ b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp @@ -0,0 +1,186 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ +#define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ + +#if VSOMEIP_BOOST_VERSION >= 106600 +#if defined(__linux__) || defined(ANDROID) + +#include + +#include + +#include + +namespace vsomeip_v3 { + +struct udp_server_endpoint_impl_receive_op { + + using socket_type_t = boost::asio::ip::udp::socket; + using endpoint_type_t = boost::asio::ip::udp::endpoint; + using receive_handler_t = + std::function; + + socket_type_t &socket_; + endpoint_type_t &sender_; + receive_handler_t handler_; + byte_t *buffer_; + size_t length_; + uint8_t multicast_id_; + bool is_v4_; + boost::asio::ip::address destination_; + size_t bytes_; + + void operator()(boost::system::error_code _error) { + + sender_ = endpoint_type_t(); // reset + + if (!_error) { + + if (!socket_.native_non_blocking()) + socket_.native_non_blocking(true, _error); + + for (;;) { + ssize_t its_result; + int its_flags(0); + + // Create control elements + msghdr its_header = msghdr(); + struct iovec its_vec[1]; + + // Prepare + its_vec[0].iov_base = buffer_; + its_vec[0].iov_len = length_; + + // Add io buffer + its_header.msg_iov = its_vec; + its_header.msg_iovlen = 1; + + // Sender & destination address info + union { + struct sockaddr_in v4; + struct sockaddr_in6 v6; + } addr; + + union { + struct cmsghdr cmh; + union { + char v4[CMSG_SPACE(sizeof(struct in_pktinfo))]; + char v6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + } control; + } control_un; + + // Prepare + if (is_v4_) { + its_header.msg_name = &addr; + its_header.msg_namelen = sizeof(sockaddr_in); + + its_header.msg_control = control_un.control.v4; + its_header.msg_controllen = sizeof(control_un.control.v4); + } else { + its_header.msg_name = &addr; + its_header.msg_namelen = sizeof(sockaddr_in6); + + its_header.msg_control = control_un.control.v6; + its_header.msg_controllen = sizeof(control_un.control.v6); + } + + // Call recvmsg and handle its result + errno = 0; + its_result = ::recvmsg(socket_.native_handle(), &its_header, its_flags); + + _error = boost::system::error_code(its_result < 0 ? errno : 0, + boost::asio::error::get_system_category()); + bytes_ += _error ? 0 : static_cast(its_result); + + if (_error == boost::asio::error::interrupted) + continue; + + if (_error == boost::asio::error::would_block + || _error == boost::asio::error::try_again) { + + socket_.async_wait(socket_type_t::wait_read, *this); + return; + } + + if (_error) + break; + + if (bytes_ == 0) + _error = boost::asio::error::eof; + + // Extract sender & destination addresses + if (is_v4_) { + // sender + boost::asio::ip::address_v4 its_sender_address( + ntohl(addr.v4.sin_addr.s_addr)); + in_port_t its_sender_port(ntohs(addr.v4.sin_port)); + sender_ = endpoint_type_t(its_sender_address, its_sender_port); + + // destination + struct in_pktinfo *its_pktinfo_v4; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_PKTINFO + && cmsg->cmsg_len == CMSG_LEN(sizeof(*its_pktinfo_v4))) { + + its_pktinfo_v4 = (struct in_pktinfo*) CMSG_DATA(cmsg); + if (its_pktinfo_v4) { + destination_ = boost::asio::ip::address_v4( + ntohl(its_pktinfo_v4->ipi_addr.s_addr)); + break; + } + } + } + } else { + boost::asio::ip::address_v6::bytes_type its_bytes; + + // sender + boost::asio::ip::address_v6 its_sender_address; + for (size_t i = 0; i < its_bytes.size(); i++) + its_bytes[i] = addr.v6.sin6_addr.s6_addr[i]; + in_port_t its_sender_port(ntohs(addr.v6.sin6_port)); + sender_ = endpoint_type_t(its_sender_address, its_sender_port); + + struct in6_pktinfo *its_pktinfo_v6; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IPV6 + && cmsg->cmsg_type == IPV6_PKTINFO + && cmsg->cmsg_len == CMSG_LEN(sizeof(*its_pktinfo_v6))) { + + its_pktinfo_v6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); + if (its_pktinfo_v6) { + for (size_t i = 0; i < its_bytes.size(); i++) + its_bytes[i] = its_pktinfo_v6->ipi6_addr.s6_addr[i]; + destination_ = boost::asio::ip::address_v6(its_bytes); + break; + } + } + } + } + + break; + } + } + + // Call the handler + handler_(_error, bytes_, multicast_id_, destination_); + } +}; + +} // namespace vsomeip + +#endif // __linux__ || ANDROID +#endif // VSOMEIP_BOOST_VERSION >= 106600 + +#endif // VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp index adf397218..98b3958e8 100644 --- a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,12 @@ #ifndef VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include @@ -20,12 +25,12 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ const std::string &_address, uint16_t _port, bool _reliable, - boost::asio::io_service& _service); + boost::asio::io_context &_io); virtual ~virtual_server_endpoint_impl(); void start(); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); void stop(); @@ -35,8 +40,6 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ void set_connected(bool _connected); bool send(const byte_t *_data, uint32_t _size); - bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size); bool send_to(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, @@ -61,7 +64,7 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ void restart(bool _force); - void register_error_handler(error_handler_t _handler); + void register_error_handler(const error_handler_t &_handler); void print_status(); size_t get_queue_size() const; @@ -72,7 +75,7 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ bool reliable_; uint32_t use_count_; - boost::asio::io_service& service_; + boost::asio::io_context &io_; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index 66b313809..6850f6610 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -30,7 +30,7 @@ client_endpoint_impl::client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) @@ -41,7 +41,10 @@ client_endpoint_impl::client_endpoint_impl( connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable state_(cei_state_e::CLOSED), reconnect_counter_(0), - train_(_io), + connecting_timer_(_io), connecting_timeout_(VSOMEIP_DEFAULT_CONNECTING_TIMEOUT), + train_(std::make_shared()), + dispatch_timer_(_io), + has_last_departure_(false), queue_size_(0), was_not_connected_(false), local_port_(0), @@ -50,26 +53,31 @@ client_endpoint_impl::client_endpoint_impl( template client_endpoint_impl::~client_endpoint_impl() { + } template bool client_endpoint_impl::is_client() const { + return true; } template bool client_endpoint_impl::is_established() const { + return state_ == cei_state_e::ESTABLISHED; } template bool client_endpoint_impl::is_established_or_connected() const { + return (state_ == cei_state_e::ESTABLISHED || state_ == cei_state_e::CONNECTED); } template void client_endpoint_impl::set_established(bool _established) { + if (_established) { if (state_ != cei_state_e::CONNECTING) { std::lock_guard its_lock(socket_mutex_); @@ -86,6 +94,7 @@ void client_endpoint_impl::set_established(bool _established) { template void client_endpoint_impl::set_connected(bool _connected) { + if (_connected) { std::lock_guard its_lock(socket_mutex_); if (socket_->is_open()) { @@ -100,7 +109,8 @@ void client_endpoint_impl::set_connected(bool _connected) { template void client_endpoint_impl::prepare_stop( - endpoint::prepare_stop_handler_t _handler, service_t _service) { + const endpoint::prepare_stop_handler_t &_handler, service_t _service) { + (void) _handler; (void) _service; } @@ -129,12 +139,14 @@ void client_endpoint_impl::stop() { } template -message_buffer_ptr_t client_endpoint_impl::get_front() { - message_buffer_ptr_t its_buffer; +std::pair +client_endpoint_impl::get_front() { + + std::pair its_entry; if (queue_.size()) - its_buffer = queue_.front(); + its_entry = queue_.front(); - return (its_buffer); + return (its_entry); } @@ -142,6 +154,7 @@ template bool client_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; @@ -154,6 +167,7 @@ template bool client_endpoint_impl::send_error( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; @@ -165,9 +179,11 @@ bool client_endpoint_impl::send_error( template bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); bool must_depart(false); - const bool queue_size_zero_on_entry(queue_.empty()); + auto its_now(std::chrono::steady_clock::now()); + #if 0 std::stringstream msg; msg << "cei::send: "; @@ -192,8 +208,8 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) break; } - // STEP 1: Determine elapsed time and update the departure time and cancel the departure timer - train_.update_departure_time_and_stop_departure(); + // STEP 1: Cancel dispatch timer + cancel_dispatch_timer(); // STEP 3: Get configured timings const service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -207,36 +223,36 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) // STEP 4: Check if the passenger enters an empty train const std::pair its_identifier = std::make_pair( its_service, its_method); - if (train_.passengers_.empty()) { - train_.departure_ = its_retention; + if (train_->passengers_.empty()) { + train_->departure_ = its_now + its_retention; // latest possible } else { // STEP 4.1: Check whether the current train already contains the message - if (train_.passengers_.end() != train_.passengers_.find(its_identifier)) { + if (train_->passengers_.end() != train_->passengers_.find(its_identifier)) { must_depart = true; } else { // STEP 5: Check whether the current message fits into the current train - if (train_.buffer_->size() + _size > endpoint_impl::max_message_size_) { + if (train_->buffer_->size() + _size > endpoint_impl::max_message_size_) { must_depart = true; } else { // STEP 6: Check debouncing time - if (its_debouncing > train_.minimal_max_retention_time_) { + if (its_debouncing > train_->minimal_max_retention_time_) { // train's latest departure would already undershot new // passenger's debounce time must_depart = true; } else { - if (its_debouncing > train_.departure_) { + if (its_now + its_debouncing > train_->departure_) { // train departs earlier as the new passenger's debounce // time allows must_depart = true; } else { // STEP 7: Check maximum retention time - if (its_retention < train_.minimal_debounce_time_) { + if (its_retention < train_->minimal_debounce_time_) { // train's earliest departure would already exceed // the new passenger's retention time. must_depart = true; } else { - if (its_retention < train_.departure_) { - train_.departure_ = its_retention; + if (its_now + its_retention < train_->departure_) { + train_->departure_ = its_now + its_retention; } } } @@ -248,50 +264,40 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) // STEP 8: if necessary, send current buffer and create a new one if (must_depart) { // STEP 8.1: check if debounce time would be undershot here if the train - // departs. Block sending until train is allowed to depart. - wait_until_debounce_time_reached(); - train_.passengers_.clear(); - queue_train(queue_size_zero_on_entry); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.departure_ = its_retention; - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + // departs. Schedule departure of current train and create a new one. + schedule_train(); + + train_ = std::make_shared(); + train_->departure_ = its_now + its_retention; } // STEP 9: insert current message buffer - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - train_.passengers_.insert(its_identifier); + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + train_->passengers_.insert(its_identifier); // STEP 9.1: update the trains minimal debounce time if necessary - if (its_debouncing < train_.minimal_debounce_time_) { - train_.minimal_debounce_time_ = its_debouncing; + if (its_debouncing < train_->minimal_debounce_time_) { + train_->minimal_debounce_time_ = its_debouncing; } // STEP 9.2: update the trains minimal maximum retention time if necessary - if (its_retention < train_.minimal_max_retention_time_) { - train_.minimal_max_retention_time_ = its_retention; + if (its_retention < train_->minimal_max_retention_time_) { + train_->minimal_max_retention_time_ = its_retention; } - // STEP 10: restart timer with current departure time -#ifndef _WIN32 - train_.departure_timer_->expires_from_now(train_.departure_); -#else - train_.departure_timer_->expires_from_now( - std::chrono::duration_cast< - std::chrono::steady_clock::duration>(train_.departure_)); -#endif - train_.departure_timer_->async_wait( - std::bind(&client_endpoint_impl::flush_cbk, - this->shared_from_this(), std::placeholders::_1)); + // STEP 10: restart dispatch timer with next departure time + start_dispatch_timer(its_now); return true; } template void client_endpoint_impl::send_segments( - const tp::tp_split_messages_t &_segments) { + const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time) { + + auto its_now(std::chrono::steady_clock::now()); + if (_segments.size() == 0) { return; } - const bool queue_size_zero_on_entry(queue_.empty()); const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], @@ -303,53 +309,49 @@ void client_endpoint_impl::send_segments( get_configured_times_from_endpoint(its_service, its_method, &its_debouncing, &its_retention); // update the trains minimal debounce time if necessary - if (its_debouncing < train_.minimal_debounce_time_) { - train_.minimal_debounce_time_ = its_debouncing; + if (its_debouncing < train_->minimal_debounce_time_) { + train_->minimal_debounce_time_ = its_debouncing; } // update the trains minimal maximum retention time if necessary - if (its_retention < train_.minimal_max_retention_time_) { - train_.minimal_max_retention_time_ = its_retention; + if (its_retention < train_->minimal_max_retention_time_) { + train_->minimal_max_retention_time_ = its_retention; } // We only need to respect the debouncing. There is no need to wait for further // messages as we will send several now anyway. - if (!train_.passengers_.empty()) { - wait_until_debounce_time_reached(); - train_.passengers_.clear(); - queue_train(queue_size_zero_on_entry); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.departure_ = its_retention; - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + if (!train_->passengers_.empty()) { + schedule_train(); + train_->departure_ = its_now + its_retention; } + const bool queue_size_still_zero(queue_.empty()); for (const auto& s : _segments) { - queue_.emplace_back(s); + queue_.emplace_back(std::make_pair(s, _separation_time)); queue_size_ += s->size(); } if (queue_size_still_zero && !queue_.empty()) { // no writing in progress // respect minimal debounce time - wait_until_debounce_time_reached(); + schedule_train(); // ignore retention time and send immediately as the train is full anyway - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); } } - train_.last_departure_ = std::chrono::steady_clock::now(); } template -void client_endpoint_impl::wait_until_debounce_time_reached() const { - const std::chrono::nanoseconds time_since_last_departure = - std::chrono::duration_cast( - std::chrono::steady_clock::now() - train_.last_departure_); - if (time_since_last_departure < train_.minimal_debounce_time_) { - std::this_thread::sleep_for( - train_.minimal_debounce_time_ - time_since_last_departure); +void client_endpoint_impl::schedule_train() { + + if (has_last_departure_) { + if (last_departure_ + train_->minimal_debounce_time_ > train_->departure_) { + train_->departure_ = last_departure_ + train_->minimal_debounce_time_; + } } + + dispatched_trains_[train_->departure_].push_back(train_); } template @@ -363,24 +365,58 @@ bool client_endpoint_impl::send(const std::vector& _cmd_header template bool client_endpoint_impl::flush() { - bool is_successful(true); + + bool has_queued(true); + bool is_current_train(true); + std::lock_guard its_lock(mutex_); - if (!train_.buffer_->empty()) { - queue_train(!queue_.size()); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.passengers_.clear(); - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + + std::shared_ptr its_train(train_); + if (!dispatched_trains_.empty()) { + + auto its_dispatched = dispatched_trains_.begin(); + if (its_dispatched->first <= its_train->departure_) { + + is_current_train = false; + its_train = its_dispatched->second.front(); + its_dispatched->second.pop_front(); + if (its_dispatched->second.empty()) { + + dispatched_trains_.erase(its_dispatched); + } + } + } + + if (!its_train->buffer_->empty()) { + + queue_train(its_train, !queue_.size()); + + // Reset current train if necessary + if (is_current_train) { + its_train->reset(); + } } else { - is_successful = false; + has_queued = false; } - return is_successful; + if (!is_current_train || !dispatched_trains_.empty()) { + + auto its_now(std::chrono::steady_clock::now()); + start_dispatch_timer(its_now); + } + + return (has_queued); } template void client_endpoint_impl::connect_cbk( boost::system::error_code const &_error) { + + if (_error != boost::asio::error::timed_out) { + std::lock_guard its_lock(connecting_timer_mutex_); + connecting_timer_.cancel(); + } + if (_error == boost::asio::error::operation_aborted || endpoint_impl::sending_blocked_) { // endpoint was stopped @@ -416,10 +452,10 @@ void client_endpoint_impl::connect_cbk( if (was_not_connected_) { was_not_connected_ = false; std::lock_guard its_lock(mutex_); - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); VSOMEIP_WARNING << __func__ << ": resume sending to: " << get_remote_information(); } @@ -435,6 +471,7 @@ void client_endpoint_impl::connect_cbk( template void client_endpoint_impl::wait_connect_cbk( boost::system::error_code const &_error) { + if (!_error && !client_endpoint_impl::sending_blocked_) { auto self = this->shared_from_this(); strand_.dispatch(std::bind(&client_endpoint_impl::connect, @@ -442,19 +479,33 @@ void client_endpoint_impl::wait_connect_cbk( } } +template +void client_endpoint_impl::wait_connecting_cbk( + boost::system::error_code const &_error) { + if (!_error && !client_endpoint_impl::sending_blocked_) { + connect_cbk(boost::asio::error::timed_out); + } +} + template void client_endpoint_impl::send_cbk( boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg) { + (void)_bytes; + if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) - send_queued(its_buffer); + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { + send_queued(its_entry); + } } } else if (_error == boost::asio::error::broken_pipe) { state_ = cei_state_e::CLOSED; @@ -563,6 +614,7 @@ void client_endpoint_impl::send_cbk( template void client_endpoint_impl::flush_cbk( boost::system::error_code const &_error) { + if (!_error) { (void) flush(); } @@ -570,15 +622,17 @@ void client_endpoint_impl::flush_cbk( template void client_endpoint_impl::shutdown_and_close_socket(bool _recreate_socket) { + std::lock_guard its_lock(socket_mutex_); shutdown_and_close_socket_unlocked(_recreate_socket); } template void client_endpoint_impl::shutdown_and_close_socket_unlocked(bool _recreate_socket) { + local_port_ = 0; if (socket_->is_open()) { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (-1 == fcntl(socket_->native_handle(), F_GETFD)) { VSOMEIP_ERROR << "cei::shutdown_and_close_socket_unlocked: socket/handle closed already '" << std::string(std::strerror(errno)) @@ -590,34 +644,39 @@ void client_endpoint_impl::shutdown_and_close_socket_unlocked(bool _re socket_->close(its_error); } if (_recreate_socket) { - socket_.reset(new socket_type(endpoint_impl::service_)); + socket_.reset(new socket_type(endpoint_impl::io_)); } } template bool client_endpoint_impl::get_remote_address( boost::asio::ip::address &_address) const { + (void)_address; return false; } template std::uint16_t client_endpoint_impl::get_remote_port() const { + return 0; } template std::uint16_t client_endpoint_impl::get_local_port() const { + return local_port_; } template void client_endpoint_impl::set_local_port(uint16_t _port) { + local_port_ = _port; } template void client_endpoint_impl::start_connect_timer() { + std::lock_guard its_lock(connect_timer_mutex_); connect_timer_.expires_from_now( std::chrono::milliseconds(connect_timeout_)); @@ -626,9 +685,21 @@ void client_endpoint_impl::start_connect_timer() { this->shared_from_this(), std::placeholders::_1)); } +template +void client_endpoint_impl::start_connecting_timer() { + + std::lock_guard its_lock(connecting_timer_mutex_); + connecting_timer_.expires_from_now( + std::chrono::milliseconds(connecting_timeout_)); + connecting_timer_.async_wait( + std::bind(&client_endpoint_impl::wait_connecting_cbk, + this->shared_from_this(), std::placeholders::_1)); +} + template typename endpoint_impl::cms_ret_e client_endpoint_impl::check_message_size( const std::uint8_t * const _data, std::uint32_t _size) { + typename endpoint_impl::cms_ret_e ret(endpoint_impl::cms_ret_e::MSG_OK); if (endpoint_impl::max_message_size_ != MESSAGE_SIZE_UNLIMITED && _size > endpoint_impl::max_message_size_) { @@ -640,11 +711,20 @@ typename endpoint_impl::cms_ret_e client_endpoint_impl::chec _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); if (tp_segmentation_enabled(its_service, its_method)) { - send_segments(tp::tp::tp_split_message(_data, _size)); - return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + instance_t its_instance = this->get_instance(its_service); + if (its_instance != 0xFFFF) { + std::uint16_t its_max_segment_length; + std::uint32_t its_separation_time; + this->configuration_->get_tp_configuration( + its_service, its_instance, its_method, true, + its_max_segment_length, its_separation_time); + send_segments(tp::tp::tp_split_message(_data, _size, + its_max_segment_length), its_separation_time); + return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + } } } - VSOMEIP_ERROR << "cei::check_message_size: Dropping too big message (" + VSOMEIP_ERROR << "cei::check_message_size: Dropping to big message (" << std::dec << _size << " Bytes). Maximum allowed message size is: " << endpoint_impl::max_message_size_ << " Bytes."; ret = endpoint_impl::cms_ret_e::MSG_TOO_BIG; @@ -654,6 +734,7 @@ typename endpoint_impl::cms_ret_e client_endpoint_impl::chec template bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std::uint32_t _size) const { + if (endpoint_impl::queue_limit_ != QUEUE_SIZE_UNLIMITED && queue_size_ + _size > endpoint_impl::queue_limit_) { service_t its_service(0); @@ -692,31 +773,84 @@ bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std } template -void client_endpoint_impl::queue_train(bool _queue_size_zero_on_entry) { - queue_.push_back(train_.buffer_); - queue_size_ += train_.buffer_->size(); - train_.buffer_ = std::make_shared(); +void client_endpoint_impl::queue_train( + const std::shared_ptr &_train, bool _queue_size_zero_on_entry) { + + queue_.push_back(std::make_pair(_train->buffer_, 0)); + queue_size_ += _train->buffer_->size(); + if (_queue_size_zero_on_entry && !queue_.empty()) { // no writing in progress - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); } } } template size_t client_endpoint_impl::get_queue_size() const { + std::lock_guard its_lock(mutex_); return queue_size_; } +template +void client_endpoint_impl::start_dispatch_timer( + const std::chrono::steady_clock::time_point &_now) { + + // Choose the next train + std::shared_ptr its_train(train_); + if (!dispatched_trains_.empty()) { + + auto its_dispatched = dispatched_trains_.begin(); + if (its_dispatched->first < its_train->departure_) { + + its_train = its_dispatched->second.front(); + } + } + + std::chrono::nanoseconds its_offset; + if (its_train->departure_ > _now) { + + its_offset = std::chrono::duration_cast( + its_train->departure_ - _now); + } else { // already departure time + + its_offset = std::chrono::nanoseconds::zero(); + } + +#if defined(__linux__) || defined(ANDROID) + dispatch_timer_.expires_from_now(its_offset); +#else + dispatch_timer_.expires_from_now( + std::chrono::duration_cast< + std::chrono::steady_clock::duration>(its_offset)); +#endif + dispatch_timer_.async_wait( + std::bind(&client_endpoint_impl::flush_cbk, + this->shared_from_this(), std::placeholders::_1)); +} + +template +void client_endpoint_impl::cancel_dispatch_timer() { + + boost::system::error_code ec; + dispatch_timer_.cancel(ec); +} + +template +void client_endpoint_impl::update_last_departure() { + + last_departure_ = std::chrono::steady_clock::now(); + has_last_departure_ = true; +} + // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) template class client_endpoint_impl; #endif template class client_endpoint_impl; template class client_endpoint_impl; } // namespace vsomeip_v3 - diff --git a/implementation/endpoints/src/credentials.cpp b/implementation/endpoints/src/credentials.cpp index 3b9762c8b..70d8dcc45 100644 --- a/implementation/endpoints/src/credentials.cpp +++ b/implementation/endpoints/src/credentials.cpp @@ -1,10 +1,12 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) +#include +#include #include #include "../include/credentials.hpp" @@ -21,7 +23,7 @@ namespace vsomeip_v3 { void credentials::activate_credentials(const int _fd) { int optval = 1; if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Activating socket option for receiving " + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Activating socket option for receiving " << "credentials failed."; } } @@ -29,70 +31,94 @@ void credentials::activate_credentials(const int _fd) { void credentials::deactivate_credentials(const int _fd) { int optval = 0; if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Deactivating socket option for receiving " + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Deactivating socket option for receiving " << "credentials failed."; } } -client_t credentials::receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid) { - struct ucred *ucredp; +boost::optional credentials::receive_credentials(const int _fd) { struct msghdr msgh; - struct iovec iov; + struct iovec iov[2]; union { struct cmsghdr cmh; char control[CMSG_SPACE(sizeof(struct ucred))]; } control_un; - struct cmsghdr *cmhp; - // Sender client_id will be received as data - client_t client = VSOMEIP_ROUTING_CLIENT; - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; + // We don't need address of peer as we using connect + msgh.msg_name = NULL; + msgh.msg_namelen = 0; + + // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg() + msgh.msg_iov = iov; + msgh.msg_iovlen = 2; // Set 'msgh' fields to describe 'control_un' msgh.msg_control = control_un.control; msgh.msg_controllen = sizeof(control_un.control); - // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg() - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - iov.iov_base = &client; - iov.iov_len = sizeof(client_t); + // Sender client_id and client_host_length will be received as data + client_t client = VSOMEIP_ROUTING_CLIENT; + uint8_t client_host_length(0); + iov[0].iov_base = &client; + iov[0].iov_len = sizeof(client_t); + iov[1].iov_base = &client_host_length; + iov[1].iov_len = sizeof(uint8_t); - // We don't need address of peer as we using connect - msgh.msg_name = NULL; - msgh.msg_namelen = 0; + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; - // Receive client_id plus ancillary data + // Receive client_id plus client_host_length plus ancillary data ssize_t nr = recvmsg(_fd, &msgh, 0); if (nr == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. No data."; + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. No data. errno: " << std::strerror(errno); + return boost::none; } - cmhp = CMSG_FIRSTHDR(&msgh); + struct cmsghdr* cmhp = CMSG_FIRSTHDR(&msgh); if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred)) || cmhp->cmsg_level != SOL_SOCKET || cmhp->cmsg_type != SCM_CREDENTIALS) { - VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. Invalid data."; - } else { - ucredp = (struct ucred *) CMSG_DATA(cmhp); - _uid = ucredp->uid; - _gid = ucredp->gid; + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. Invalid data."; + return boost::none; } - return client; + // Use the implicitly-defined copy constructor + struct ucred ucred = *reinterpret_cast(CMSG_DATA(cmhp)); + + msgh.msg_iov = iov; + msgh.msg_iovlen = 1; + msgh.msg_control = nullptr; + msgh.msg_controllen = 0; + + // Receive client_host as data + std::string client_host(client_host_length, '\0'); + iov[0].iov_base = &client_host.front(); + iov[0].iov_len = client_host.length(); + + nr = recvmsg(_fd, &msgh, 0); + if (nr == -1) { + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving client host failed. No data. errno: " << std::strerror(errno); + return boost::none; + } + + return received_t{client, ucred.uid, ucred.gid, client_host}; } -void credentials::send_credentials(const int _fd, client_t _client) { +void credentials::send_credentials(const int _fd, client_t _client, std::string _client_host) { struct msghdr msgh; - struct iovec iov; + struct iovec iov[3]; + uint8_t client_host_length = (uint8_t)_client_host.length(); // data to send - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - iov.iov_base = &_client; - iov.iov_len = sizeof(client_t); + msgh.msg_iov = &iov[0]; + msgh.msg_iovlen = 3; + iov[0].iov_base = &_client; + iov[0].iov_len = sizeof(client_t); + iov[1].iov_base = &client_host_length; + iov[1].iov_len = sizeof(uint8_t); + iov[2].iov_base = &_client_host[0]; + iov[2].iov_len = client_host_length; // destination not needed as we use connect msgh.msg_name = NULL; @@ -105,11 +131,10 @@ void credentials::send_credentials(const int _fd, client_t _client) { // send client id with credentials ssize_t ns = sendmsg(_fd, &msgh, 0); if (ns == -1) { - VSOMEIP_ERROR << "Sending credentials failed."; + VSOMEIP_ERROR << __func__ << ": Sending credentials failed. errno: " << std::strerror(errno); } } } // namespace vsomeip_v3 -#endif // #ifndef _WIN32 - +#endif // __linux__ || ANDROID diff --git a/implementation/endpoints/src/endpoint_definition.cpp b/implementation/endpoints/src/endpoint_definition.cpp index 954783694..ff6ff7bdc 100644 --- a/implementation/endpoints/src/endpoint_definition.cpp +++ b/implementation/endpoints/src/endpoint_definition.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index 4bb2fc0ec..983531584 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -1,13 +1,15 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include -#include #include +#if VSOMEIP_BOOST_VERSION < 106600 #include +#include +#endif #include #include @@ -24,11 +26,11 @@ endpoint_impl::endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) - : service_(_io), + : io_(_io), endpoint_host_(_endpoint_host), routing_host_(_routing_host), is_supporting_magic_cookies_(false), @@ -125,18 +127,32 @@ uint32_t endpoint_impl::get_use_count() { } template -void endpoint_impl::register_error_handler(error_handler_t _error_handler) { +void endpoint_impl::register_error_handler(const error_handler_t &_error_handler) { std::lock_guard its_lock(error_handler_mutex_); this->error_handler_ = _error_handler; } +template +instance_t endpoint_impl::get_instance(service_t _service) { + + instance_t its_instance(0xFFFF); + + auto its_host = endpoint_host_.lock(); + if (its_host) + its_instance = its_host->find_instance(_service, this); + + return (its_instance); +} + // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) template class endpoint_impl; +#if VSOMEIP_BOOST_VERSION < 106600 template class endpoint_impl; +template class endpoint_impl; +#endif #endif template class endpoint_impl; template class endpoint_impl; -template class endpoint_impl; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_base.cpp b/implementation/endpoints/src/endpoint_manager_base.cpp index cfddc87a9..b8e18af90 100644 --- a/implementation/endpoints/src/endpoint_manager_base.cpp +++ b/implementation/endpoints/src/endpoint_manager_base.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,20 +9,28 @@ #include "../../utility/include/utility.hpp" #include "../../routing/include/routing_manager_base.hpp" #include "../../configuration/include/configuration.hpp" -#include "../include/local_client_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" +#include "../include/local_tcp_client_endpoint_impl.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" + +#if defined(__linux__) || defined(ANDROID) +#include "../include/local_uds_client_endpoint_impl.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#endif #include namespace vsomeip_v3 { -endpoint_manager_base::endpoint_manager_base(routing_manager_base* const _rm, - boost::asio::io_service& _io, - const std::shared_ptr& _configuration) : - rm_(_rm), - io_(_io), - configuration_(_configuration){ +endpoint_manager_base::endpoint_manager_base( + routing_manager_base* const _rm, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration) + : rm_(_rm), + io_(_io), + configuration_(_configuration), + local_port_(ILLEGAL_PORT) { + is_local_routing_ = configuration_->is_local_routing(); } std::shared_ptr endpoint_manager_base::create_local(client_t _client) { @@ -72,47 +80,81 @@ std::unordered_set endpoint_manager_base::get_connected_clients() cons return clients; } -std::shared_ptr endpoint_manager_base::create_local_server( - const std::shared_ptr& _routing_host) { - std::shared_ptr its_server_endpoint; +std::shared_ptr endpoint_manager_base::create_local_server( + const std::shared_ptr &_routing_host) { + std::shared_ptr its_server_endpoint; std::stringstream its_path; - its_path << utility::get_base_path(configuration_) << std::hex << rm_->get_client(); + its_path << utility::get_base_path(configuration_->get_network()) + << std::hex << rm_->get_client(); const client_t its_client = rm_->get_client(); -#ifdef _WIN32 - ::_unlink(its_path.str().c_str()); - int port = VSOMEIP_INTERNAL_BASE_PORT + its_client; -#else - if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" - << its_path.str() << "): "<< std::strerror(errno); - } -#endif - try { - its_server_endpoint = std::make_shared( - shared_from_this(), _routing_host, -#ifdef _WIN32 - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), -#else - boost::asio::local::stream_protocol_ext::endpoint(its_path.str()), -#endif - io_, - configuration_, false); -#ifdef _WIN32 - VSOMEIP_INFO << "Listening at " << port; -#else - VSOMEIP_INFO << "Listening at " << its_path.str(); -#endif - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Local server endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') << its_client -#ifdef _WIN32 - << " Port: " << std::dec << port + +#if defined(__linux__) || defined(ANDROID) + if (is_local_routing_) { + if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" + << its_path.str() << "): "<< std::strerror(errno); + } + try { + its_server_endpoint = std::make_shared( + shared_from_this(), _routing_host, +# if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext::endpoint(its_path.str()), +# else + boost::asio::local::stream_protocol::endpoint(its_path.str()), +# endif + io_, + configuration_, false); + + VSOMEIP_INFO << __func__ << ": Listening @ " << its_path.str(); + + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local UDS server endpoint creation failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Path: " << its_path.str() + << " Reason: " << e.what(); + } + } else { #else - << " Path: " << its_path.str() + { #endif - << " Reason: " << e.what(); + std::lock_guard its_lock(create_local_server_endpoint_mutex_); + ::unlink(its_path.str().c_str()); + port_t its_port; + std::set its_used_ports; + auto its_address = configuration_->get_routing_guest_address(); + while (get_local_server_port(its_port, its_used_ports) && !its_server_endpoint) { + try { + its_server_endpoint = std::make_shared( + shared_from_this(), _routing_host, + boost::asio::ip::tcp::endpoint(its_address, its_port), + io_, + configuration_, false); + + VSOMEIP_INFO << __func__ << ": Listening @ " + << its_address.to_string() << ":" << std::dec << its_port; + + if (rm_->is_routing_manager()) + local_port_ = port_t(configuration_->get_routing_host_port() + 1); + else + local_port_ = port_t(its_port + 1); + VSOMEIP_INFO << __func__ << ": Connecting to other clients from " + << its_address.to_string() << ":" << std::dec << local_port_; + + } catch (const std::exception&) { + its_used_ports.insert(its_port); + } + } + + if (!its_server_endpoint) { + VSOMEIP_ERROR << "Local TCP server endpoint creation failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Reason: No local port available!"; + } else { + rm_->add_guest(its_client, its_address, its_port); + } } - return its_server_endpoint; + + return (its_server_endpoint); } void endpoint_manager_base::on_connect(std::shared_ptr _endpoint) { @@ -123,23 +165,27 @@ void endpoint_manager_base::on_disconnect(std::shared_ptr _endpoint) { rm_->on_disconnect(_endpoint); } -bool endpoint_manager_base::on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port) { +bool endpoint_manager_base::on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port) { + (void)_endpoint; + (void)_remote_address; (void)_remote_port; + return true; - // intentionally left blank } void endpoint_manager_base::on_error( const byte_t *_data, length_t _length, endpoint* const _receiver, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + (void)_data; (void)_length; (void)_receiver; (void)_remote_address; (void)_remote_port; - // intentionally left blank } void endpoint_manager_base::release_port(uint16_t _port, bool _reliable) { @@ -152,6 +198,10 @@ client_t endpoint_manager_base::get_client() const { return rm_->get_client(); } +std::string endpoint_manager_base::get_client_host() const { + return rm_->get_client_host(); +} + std::map> endpoint_manager_base::get_local_endpoints() const { std::lock_guard its_lock(local_endpoint_mutex_); @@ -193,39 +243,69 @@ endpoint_manager_base::log_client_states() const { VSOMEIP_WARNING << "ICQ: [" << its_log.str() << "]"; } -std::shared_ptr endpoint_manager_base::create_local_unlocked(client_t _client) { +std::shared_ptr +endpoint_manager_base::create_local_unlocked(client_t _client) { + std::stringstream its_path; - its_path << utility::get_base_path(configuration_) << std::hex << _client; - std::shared_ptr its_endpoint; - -#ifdef _WIN32 - boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1"); - int port = VSOMEIP_INTERNAL_BASE_PORT + _client; - VSOMEIP_INFO << "Connecting to [" - << std::hex << _client << "] at " << port; -#else - VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to [" + its_path << utility::get_base_path(configuration_->get_network()) + << std::hex << _client; + std::shared_ptr its_endpoint; + +#if defined(__linux__) || defined(ANDROID) + if (is_local_routing_) { + VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to [" << std::hex << _client << "] at " << its_path.str(); -#endif - its_endpoint = std::make_shared( + its_endpoint = std::make_shared( shared_from_this(), rm_->shared_from_this(), -#ifdef _WIN32 - boost::asio::ip::tcp::endpoint(address, port) + boost::asio::local::stream_protocol::endpoint(its_path.str()), + io_, configuration_); + } else { #else - boost::asio::local::stream_protocol::endpoint(its_path.str()) + { #endif - , io_, configuration_); - - // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to - // external devices. Therefore, its local endpoint must not be found by - // a call to find_local. Thus it must not be inserted to the list of local - // clients. - if (_client != VSOMEIP_ROUTING_CLIENT) { - local_endpoints_[_client] = its_endpoint; + boost::asio::ip::address its_local_address, its_remote_address; + port_t its_remote_port; + + bool is_guest = rm_->get_guest(_client, its_remote_address, its_remote_port); + if (is_guest) { + try { + its_local_address = configuration_->get_routing_guest_address(); + its_endpoint = std::make_shared( + shared_from_this(), rm_->shared_from_this(), + boost::asio::ip::tcp::endpoint(its_local_address, local_port_), + boost::asio::ip::tcp::endpoint(its_remote_address, its_remote_port), + io_, configuration_); + + VSOMEIP_INFO << "Client [" + << std::hex << std::setw(4) << std::setfill('0') << rm_->get_client() + << "] @ " + << its_local_address.to_string() << ":" << std::dec << local_port_ + << " is connecting to [" + << std::hex << std::setw(4) << std::setfill('0') << _client << "] @ " + << its_remote_address.to_string() << ":" << std::dec << its_remote_port; + + } catch (...) { + } + } else { + VSOMEIP_ERROR << __func__ + << ": Cannot get guest address of client [" + << std::hex << std::setw(4) << std::setfill('0') + << _client << "]"; + } } - rm_->register_client_error_handler(_client, its_endpoint); - return its_endpoint; + if (its_endpoint) { + // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to + // external devices. Therefore, its local endpoint must not be found by + // a call to find_local. Thus it must not be inserted to the list of local + // clients. + if (_client != VSOMEIP_ROUTING_CLIENT) { + local_endpoints_[_client] = its_endpoint; + } + rm_->register_client_error_handler(_client, its_endpoint); + } + + return (its_endpoint); } std::shared_ptr endpoint_manager_base::find_local_unlocked(client_t _client) { @@ -237,4 +317,43 @@ std::shared_ptr endpoint_manager_base::find_local_unlocked(client_t _c return (its_endpoint); } +instance_t endpoint_manager_base::find_instance( + service_t _service, endpoint* const _endpoint) const { + + (void)_service; + (void)_endpoint; + + return (0xFFFF); +} + +bool +endpoint_manager_base::get_local_server_port(port_t &_port, + const std::set &_used_ports) const { + +#define SERVER_PORT_OFFSET 2 + + auto its_port_ranges = configuration_->get_routing_guest_ports(); + + for (const auto &its_range : its_port_ranges) { + for (int r = its_range.first; r < its_range.second; + r += SERVER_PORT_OFFSET) { + + if (_used_ports.find(port_t(r)) == _used_ports.end() + && r != configuration_->get_routing_host_port()) { + + _port = port_t(r); + return (true); + } + } + } + + return (false); +} + +void +endpoint_manager_base::add_multicast_option(const multicast_option_t &_option) { + + (void)_option; +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp index dbb210740..a47234c13 100644 --- a/implementation/endpoints/src/endpoint_manager_impl.cpp +++ b/implementation/endpoints/src/endpoint_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -7,17 +7,19 @@ #include +#include "../include/local_tcp_server_endpoint_impl.hpp" +#if defined(__linux__) || defined(ANDROID) +#include "../include/local_uds_server_endpoint_impl.hpp" +#endif #include "../include/udp_client_endpoint_impl.hpp" #include "../include/udp_server_endpoint_impl.hpp" #include "../include/tcp_client_endpoint_impl.hpp" #include "../include/tcp_server_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" #include "../include/virtual_server_endpoint_impl.hpp" #include "../include/endpoint_definition.hpp" #include "../../routing/include/routing_manager_base.hpp" #include "../../routing/include/routing_manager_impl.hpp" #include "../../routing/include/routing_host.hpp" -#include "../../security/include/security.hpp" #include "../../utility/include/utility.hpp" #include "../../utility/include/byteorder.hpp" @@ -33,9 +35,28 @@ namespace vsomeip_v3 { endpoint_manager_impl::endpoint_manager_impl( - routing_manager_base* const _rm, boost::asio::io_service& _io, + routing_manager_base* const _rm, boost::asio::io_context &_io, const std::shared_ptr& _configuration) : - endpoint_manager_base(_rm, _io, _configuration) { + endpoint_manager_base(_rm, _io, _configuration), + is_processing_options_(true), + options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) { + + local_port_ = port_t(_configuration->get_routing_host_port() + 1); + if (!is_local_routing_) { + VSOMEIP_INFO << __func__ << ": Connecting to other clients from " + << configuration_->get_routing_host_address().to_string() + << ":" << std::dec << local_port_; + } +} + +endpoint_manager_impl::~endpoint_manager_impl() { + + { + std::lock_guard its_guard(options_mutex_); + is_processing_options_ = false; + options_condition_.notify_one(); + } + options_thread_.join(); } std::shared_ptr endpoint_manager_impl::find_or_create_remote_client( @@ -266,9 +287,7 @@ std::shared_ptr endpoint_manager_impl::create_server_endpoint( << " Server endpoint creation failed." << " Reason: "<< e.what() << " Port: " << _port - << " (reliable=" - << (_reliable ? "reliable" : "unreliable") - << ")"; + << " (" << _reliable << ")"; } return (its_endpoint); @@ -457,6 +476,7 @@ void endpoint_manager_impl::find_or_create_multicast_endpoint( // Only save multicast info if we created a new endpoint // to be able to delete the new endpoint // as soon as the instance stops offering its service + std::lock_guard its_lock(endpoint_mutex_); std::shared_ptr endpoint_def = endpoint_definition::get(_address, _port, false, _service, _instance); multicast_info[_service][_instance] = endpoint_def; @@ -588,79 +608,139 @@ void endpoint_manager_impl::print_status() const { } } -std::shared_ptr -endpoint_manager_impl::create_local_server( - bool* _is_socket_activated, - const std::shared_ptr& _routing_host) { - std::shared_ptr its_endpoint; +bool +endpoint_manager_impl::create_routing_root( + std::shared_ptr &_root, + bool &_is_socket_activated, + const std::shared_ptr &_host) { + std::stringstream its_endpoint_path_ss; - its_endpoint_path_ss << utility::get_base_path(configuration_) << VSOMEIP_ROUTING_CLIENT; + its_endpoint_path_ss << utility::get_base_path(configuration_->get_network()) + << VSOMEIP_ROUTING_CLIENT; const std::string its_endpoint_path = its_endpoint_path_ss.str(); - client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host()); - if (security::get()->is_enabled() && get_client() != routing_host_id) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server: " - << std::hex << "Client " << get_client() << " isn't allowed" - << " to create the routing endpoint as its not configured as the routing master!"; - return its_endpoint; + client_t its_routing_host_id = configuration_->get_id(configuration_->get_routing_host_name()); + if (configuration_->is_security_enabled() && get_client() != its_routing_host_id) { + VSOMEIP_ERROR << "endpoint_manager_impl::" << __func__ << ": " + << "Client [" + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << "] does not match the configured routing manager client identifier [" + << std::hex << std::setw(4) << std::setfill('0') + << its_routing_host_id + << "]"; + + return (false); } - uint32_t native_socket_fd = 0; - int32_t num_fd = 0; + + if (configuration_->is_local_routing()) { + uint32_t native_socket_fd = 0; + int32_t num_fd = 0; #ifndef WITHOUT_SYSTEMD - num_fd = sd_listen_fds(0); + num_fd = sd_listen_fds(0); +#endif + +#if defined(__linux__) || defined(ANDROID) + if (num_fd > 1) { + VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd; + } else if (num_fd == 1) { + native_socket_fd = SD_LISTEN_FDS_START + 0; + VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd; + if (is_local_routing_) { + try { + _root = + std::make_shared ( + shared_from_this(), _host, +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), +#else + boost::asio::local::stream_protocol::endpoint(its_endpoint_path), #endif - if (num_fd > 1) { - VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd; - } else if (num_fd == 1) { - native_socket_fd = SD_LISTEN_FDS_START + 0; - VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd; - #ifndef _WIN32 - try { - its_endpoint = - std::make_shared ( - shared_from_this(), _routing_host, + io_, + native_socket_fd, + configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + } + } + _is_socket_activated = true; + + } else { + if (is_local_routing_) { + if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" + << its_endpoint_path << "): "<< std::strerror(errno); + } + VSOMEIP_INFO << __func__ << ": Routing root @ " << its_endpoint_path; + + try { + _root = + std::make_shared ( + shared_from_this(), _host, +#if VSOMEIP_BOOST_VERSION < 106600 boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), - io_, - native_socket_fd, - configuration_, true); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Server endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); +#else + boost::asio::local::stream_protocol::endpoint(its_endpoint_path), +#endif + io_, configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); + } } - #endif - *_is_socket_activated = true; + + _is_socket_activated = false; + } +#else + ::unlink(its_endpoint_path.c_str()); + port_t port = VSOMEIP_INTERNAL_BASE_PORT; + VSOMEIP_INFO << __func__ << ": Routing root @ " << std::dec << port; + + try { + _root = + std::make_shared ( + shared_from_this(), _host, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), + io_, configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); + } + + _is_socket_activated = false; +#endif // __linux__ || ANDROID } else { - #if _WIN32 - ::_unlink(its_endpoint_path.c_str()); - int port = VSOMEIP_INTERNAL_BASE_PORT; - VSOMEIP_INFO << "Routing endpoint at " << port; - #else - if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" - << its_endpoint_path << "): "<< std::strerror(errno); - } - VSOMEIP_INFO << __func__ << " Routing endpoint at " << its_endpoint_path; - #endif + auto its_address = configuration_->get_routing_host_address(); + auto its_port = configuration_->get_routing_host_port(); + + VSOMEIP_INFO << __func__ << ": Routing root @ " + << its_address.to_string() << ":" << std::dec << its_port; try { - its_endpoint = - std::make_shared ( - shared_from_this(), _routing_host, - #ifdef _WIN32 - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), - #else - boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), - #endif - io_, - configuration_, true); + _root = + std::make_shared ( + shared_from_this(), _host, + boost::asio::ip::tcp::endpoint(its_address, its_port), + io_, configuration_, true); } catch (const std::exception &e) { - VSOMEIP_ERROR << "Server endpoint creation failed. Client ID: " + VSOMEIP_ERROR << "Remote routing root endpoint creation failed. Client ID: " << std::hex << std::setw(4) << std::setfill('0') << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); } - *_is_socket_activated = false; + + _is_socket_activated = false; } - return its_endpoint; + + return (true); } instance_t endpoint_manager_impl::find_instance( @@ -807,8 +887,8 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr _endpoint) { if (!is_reliable) { static_cast(rm_)->on_availability( its_service.first, its_instance.first, - false, its_info->get_major(), - its_info->get_minor()); + availability_state_e::AS_UNAVAILABLE, + its_info->get_major(), its_info->get_minor()); } static_cast(rm_)->service_endpoint_disconnected( its_service.first, its_instance.first, @@ -820,7 +900,9 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr _endpoint) { } } -bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, std::uint16_t _remote_port) { +bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + std::lock_guard its_ep_lock(endpoint_mutex_); for (auto &its_service : remote_services_) { for (auto &its_instance : its_service.second) { @@ -833,15 +915,16 @@ bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, s uint16_t its_new_local_port(ILLEGAL_PORT); std::unique_lock its_lock(used_client_ports_mutex_); - if (configuration_->get_client_port(its_service.first, - its_instance.first, - _remote_port, - is_reliable, - used_client_ports_, - its_new_local_port)) { + std::map > its_used_client_ports; + get_used_client_ports(_remote_address, _remote_port, its_used_client_ports); + if (configuration_->get_client_port( + its_service.first, its_instance.first, + _remote_port, is_reliable, + its_used_client_ports, its_new_local_port)) { _endpoint->set_local_port(its_new_local_port); its_lock.unlock(); - release_port(its_old_local_port, _endpoint->is_reliable()); + release_used_client_port(_remote_address, _remote_port, + _endpoint->is_reliable(), its_old_local_port); return true; } } @@ -866,9 +949,43 @@ void endpoint_manager_impl::on_error( _receiver->is_reliable(), _receiver, _remote_address, _remote_port); } -void endpoint_manager_impl::release_port(uint16_t _port, bool _reliable) { +void +endpoint_manager_impl::get_used_client_ports( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + std::map > &_used_ports) { + auto find_address = used_client_ports_.find(_remote_address); + if (find_address != used_client_ports_.end()) { + auto find_port = find_address->second.find(_remote_port); + if (find_port != find_address->second.end()) + _used_ports = find_port->second; + } +} + +void +endpoint_manager_impl::request_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port) { + std::lock_guard its_lock(used_client_ports_mutex_); - used_client_ports_[_reliable].erase(_port); + used_client_ports_[_remote_address][_remote_port] + [_reliable].insert(_local_port); +} + +void +endpoint_manager_impl::release_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port) { + + std::lock_guard its_lock(used_client_ports_mutex_); + auto find_address = used_client_ports_.find(_remote_address); + if (find_address != used_client_ports_.end()) { + auto find_port = find_address->second.find(_remote_port); + if (find_port != find_address->second.end()) { + auto find_reliable = find_port->second.find(_reliable); + if (find_reliable != find_port->second.end()) + find_reliable->second.erase(_local_port); + } + } } std::shared_ptr @@ -946,6 +1063,8 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( std::shared_ptr its_endpoint; std::shared_ptr its_endpoint_def; uint16_t its_local_port; + + boost::asio::ip::address its_remote_address; uint16_t its_remote_port = ILLEGAL_PORT; auto found_service = remote_service_info_.find(_service); @@ -955,6 +1074,7 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( auto found_reliability = found_instance->second.find(_reliable); if (found_reliability != found_instance->second.end()) { its_endpoint_def = found_reliability->second; + its_remote_address = its_endpoint_def->get_address(); its_remote_port = its_endpoint_def->get_port(); } } @@ -963,25 +1083,31 @@ std::shared_ptr endpoint_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::unique_lock 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) { + std::map > its_used_client_ports; + { + std::lock_guard its_lock(used_client_ports_mutex_); + get_used_client_ports(its_remote_address, its_remote_port, its_used_client_ports); + } + if (configuration_->get_client_port(_service, _instance, + its_remote_port, _reliable, + its_used_client_ports, its_local_port)) { + if (its_endpoint_def) { its_endpoint = create_client_endpoint( - its_endpoint_def->get_address(), + its_remote_address, its_local_port, - its_endpoint_def->get_port(), + its_remote_port, _reliable); } if (its_endpoint) { - partition_id_t its_partition - = configuration_->get_partition_id(_service, _instance); - used_client_ports_[_reliable].insert(its_local_port); - its_lock.unlock(); + request_used_client_port(its_remote_address, its_remote_port, + _reliable, its_local_port); + service_instances_[_service][its_endpoint.get()] = _instance; remote_services_[_service][_instance][_reliable] = its_endpoint; + partition_id_t its_partition + = configuration_->get_partition_id(_service, _instance); client_endpoints_by_ip_[its_endpoint_def->get_address()] [its_endpoint_def->get_port()] [_reliable] @@ -1148,4 +1274,38 @@ endpoint_manager_impl::log_server_states() const { VSOMEIP_INFO << "ESQ: [" << its_log.str() << "]"; } +void +endpoint_manager_impl::add_multicast_option(const multicast_option_t &_option) { + + std::lock_guard its_guard(options_mutex_); + options_queue_.push(_option); + options_condition_.notify_one(); +} + +void +endpoint_manager_impl::process_multicast_options() { + + std::unique_lock its_lock(options_mutex_); + while (is_processing_options_) { + if (options_queue_.size() > 0) { + auto its_front = options_queue_.front(); + options_queue_.pop(); + auto its_udp_server_endpoint + = std::dynamic_pointer_cast(its_front.endpoint_); + if (its_udp_server_endpoint) { + // Unlock before setting the option as this might block + its_lock.unlock(); + its_udp_server_endpoint->set_multicast_option( + its_front.address_, its_front.is_join_); + // Lock again after setting the option + its_lock.lock(); + } + } else { + options_condition_.wait(its_lock, [this] { + return !options_queue_.empty() || !is_processing_options_; + }); + } + } +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp new file mode 100644 index 000000000..e72882718 --- /dev/null +++ b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp @@ -0,0 +1,382 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include + +#include +#include + +#include "../include/endpoint_host.hpp" +#include "../include/local_tcp_client_endpoint_impl.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../routing/include/routing_host.hpp" + +namespace vsomeip_v3 { + +local_tcp_client_endpoint_impl::local_tcp_client_endpoint_impl( + const std::shared_ptr &_endpoint_host, + const std::shared_ptr &_routing_host, + const endpoint_type & _local, + const endpoint_type &_remote, + boost::asio::io_context &_io, + const std::shared_ptr &_configuration) + : local_tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, + _local, _remote, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { + + is_supporting_magic_cookies_ = false; +} + +local_tcp_client_endpoint_impl::~local_tcp_client_endpoint_impl() { + +} + +bool local_tcp_client_endpoint_impl::is_local() const { + + return true; +} + +void local_tcp_client_endpoint_impl::restart(bool _force) { + + if (!_force && state_ == cei_state_e::CONNECTING) { + return; + } + state_ = cei_state_e::CONNECTING; + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + queue_.clear(); + queue_size_ = 0; + } + { + std::lock_guard its_lock(socket_mutex_); + shutdown_and_close_socket_unlocked(true); + } + was_not_connected_ = true; + reconnect_counter_ = 0; + start_connect_timer(); +} + +void local_tcp_client_endpoint_impl::start() { + + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + } + connect(); +} + +void local_tcp_client_endpoint_impl::stop() { + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = true; + } + { + std::lock_guard its_lock(connect_timer_mutex_); + boost::system::error_code ec; + connect_timer_.cancel(ec); + } + connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; + + bool is_open(false); + { + std::lock_guard its_lock(socket_mutex_); + is_open = socket_->is_open(); + } + if (is_open) { + bool send_queue_empty(false); + std::uint32_t times_slept(0); + + while (times_slept <= 50) { + mutex_.lock(); + send_queue_empty = (queue_.size() == 0); + mutex_.unlock(); + if (send_queue_empty) { + break; + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + times_slept++; + } + } + } + shutdown_and_close_socket(false); +} + +void local_tcp_client_endpoint_impl::connect() { + start_connecting_timer(); + boost::system::error_code its_connect_error; + { + std::lock_guard its_lock(socket_mutex_); + boost::system::error_code its_error; + socket_->open(remote_.protocol(), its_error); + + if (!its_error || its_error == boost::asio::error::already_open) { + socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ + << ": Cannot enable SO_REUSEADDR" + << "(" << its_error.message() << ")"; + } + + socket_->bind(local_, its_error); + if (its_error) { + VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ + << ": Cannot bind to client port " << local_.port() + << "(" << its_error.message() << ")"; + } + + state_ = cei_state_e::CONNECTING; + socket_->connect(remote_, its_connect_error); + } else { + VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " + << its_error.message() << " (" << std::dec << its_error.value() + << ")"; + its_connect_error = its_error; + } + } + // call connect_cbk asynchronously + try { + strand_.post( + std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), + its_connect_error)); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "local_client_endpoint_impl::connect: " << e.what(); + } +} + +void local_tcp_client_endpoint_impl::receive() { + std::lock_guard its_lock(socket_mutex_); + if (socket_->is_open()) { + socket_->async_receive( + boost::asio::buffer(recv_buffer_), + strand_.wrap( + std::bind( + &local_tcp_client_endpoint_impl::receive_cbk, + std::dynamic_pointer_cast< + local_tcp_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2 + ) + ) + ); + } +} + +// this overrides client_endpoint_impl::send to disable the pull method +// for local communication +bool local_tcp_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); + bool ret(true); + const bool queue_size_zero_on_entry(queue_.empty()); + if (endpoint_impl::sending_blocked_ || + check_message_size(nullptr, _size) != cms_ret_e::MSG_OK || + !check_packetizer_space(_size) || + !check_queue_limit(_data, _size)) { + ret = false; + } else { +#if 0 + std::stringstream msg; + msg << "lce::send: "; + for (uint32_t i = 0; i < _size; i++) + msg << std::hex << std::setw(2) << std::setfill('0') + << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + queue_train(train_, queue_size_zero_on_entry); + train_->buffer_ = std::make_shared(); + } + return ret; +} + +void local_tcp_client_endpoint_impl::send_queued(std::pair &_entry) { + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_entry.first)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + *socket_, + bufs, + std::bind( + &client_endpoint_impl::send_cbk, + std::dynamic_pointer_cast< + local_tcp_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2, + _entry.first + ) + ); + } +} + +void local_tcp_client_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; +} + +void local_tcp_client_endpoint_impl::send_magic_cookie() { + +} + +void local_tcp_client_endpoint_impl::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes) { + + if (_error) { + if (_error == boost::asio::error::operation_aborted) { + // endpoint was stopped + return; + } else if (_error == boost::asio::error::connection_reset + || _error == boost::asio::error::eof + || _error == boost::asio::error::bad_descriptor) { + VSOMEIP_INFO << __func__ << " local_tcp_client_endpoint:" + " connection_reset/EOF/bad_descriptor"; + } else if (_error) { + VSOMEIP_ERROR << "Local endpoint received message (" + << _error.message() << ")"; + } + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); + } else { + +#if 0 + std::stringstream msg; + msg << "lce<" << this << ">::recv: "; + for (std::size_t i = 0; i < recv_buffer_.size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)recv_buffer_[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + // We only handle a single message here. Check whether the message + // format matches what we do expect. + // TODO: Replace the magic numbers. + if (_bytes == VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE + && recv_buffer_[0] == 0x67 && recv_buffer_[1] == 0x37 + && recv_buffer_[2] == 0x6d && recv_buffer_[3] == 0x07 + && recv_buffer_[4] == byte_t(protocol::id_e::ASSIGN_CLIENT_ACK_ID) + && recv_buffer_[15] == 0x07 && recv_buffer_[16] == 0x6d + && recv_buffer_[17] == 0x37 && recv_buffer_[18] == 0x67) { + + auto its_routing_host = routing_host_.lock(); + if (its_routing_host) + its_routing_host->on_message(&recv_buffer_[4], + static_cast(recv_buffer_.size() - 8), this); + } + + receive(); + } +} + +bool local_tcp_client_endpoint_impl::get_remote_address( + boost::asio::ip::address &_address) const { + (void)_address; + return false; +} + +std::uint16_t local_tcp_client_endpoint_impl::get_remote_port() const { + return 0; +} + +void local_tcp_client_endpoint_impl::set_local_port() { + // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing +} + +void local_tcp_client_endpoint_impl::print_status() { + + std::string its_path(""); + std::size_t its_data_size(0); + std::size_t its_queue_size(0); + { + std::lock_guard its_lock(mutex_); + its_queue_size = queue_.size(); + its_data_size = queue_size_; + } + + VSOMEIP_INFO << "status lce: " << its_path << " queue: " + << its_queue_size << " data: " << its_data_size; +} + +std::string local_tcp_client_endpoint_impl::get_remote_information() const { + + boost::system::error_code ec; + return remote_.address().to_string(ec) + ":" + + std::to_string(remote_.port()); +} + + +bool local_tcp_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { + if (train_->buffer_->size() + _size < train_->buffer_->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if (train_->buffer_->size() + _size > max_message_size_ + && !train_->buffer_->empty()) { + queue_.push_back(std::make_pair(train_->buffer_, 0)); + queue_size_ += train_->buffer_->size(); + train_->buffer_ = std::make_shared(); + } + return true; +} + +bool local_tcp_client_endpoint_impl::is_reliable() const { + + return true; +} + +std::uint32_t local_tcp_client_endpoint_impl::get_max_allowed_reconnects() const { + + return (MAX_RECONNECTS_UNLIMITED); +} + +bool local_tcp_client_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +void local_tcp_client_endpoint_impl::max_allowed_reconnects_reached() { + + VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " + << get_remote_information(); + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp new file mode 100644 index 000000000..e3132fcc1 --- /dev/null +++ b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp @@ -0,0 +1,897 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include + +#include +#include + +#include + +#include "../include/endpoint_host.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" +#include "../include/local_server_endpoint_impl_receive_op.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../routing/include/routing_host.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/utility.hpp" + +namespace vsomeip_v3 { + +local_tcp_server_endpoint_impl::local_tcp_server_endpoint_impl( + const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint) + : local_tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, + _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + acceptor_(_io), + buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), + local_port_(_local.port()), + is_routing_endpoint_(_is_routing_endpoint) { + is_supporting_magic_cookies_ = false; + + boost::system::error_code ec; + acceptor_.open(_local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + + acceptor_.bind(_local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + + acceptor_.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); +} + +local_tcp_server_endpoint_impl::~local_tcp_server_endpoint_impl() { +} + +bool local_tcp_server_endpoint_impl::is_local() const { + + return true; +} + +void local_tcp_server_endpoint_impl::start() { + + std::lock_guard its_lock(acceptor_mutex_); + if (!acceptor_.is_open()) { + boost::system::error_code ec; + acceptor_.open(local_.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + acceptor_.bind(local_, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + acceptor_.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + } + + if (acceptor_.is_open()) { + connection::ptr new_connection = connection::create( + std::dynamic_pointer_cast( + shared_from_this()), max_message_size_, + buffer_shrink_threshold_, + io_); + + { + std::unique_lock its_lock(new_connection->get_socket_lock()); + acceptor_.async_accept( + new_connection->get_socket(), + std::bind( + &local_tcp_server_endpoint_impl::accept_cbk, + std::dynamic_pointer_cast< + local_tcp_server_endpoint_impl + >(shared_from_this()), + new_connection, + std::placeholders::_1 + ) + ); + } + } +} + +void local_tcp_server_endpoint_impl::stop() { + + server_endpoint_impl::stop(); + { + std::lock_guard its_lock(acceptor_mutex_); + if (acceptor_.is_open()) { + boost::system::error_code its_error; + acceptor_.close(its_error); + } + } + { + std::lock_guard its_lock(connections_mutex_); + for (const auto &c : connections_) { + c.second->stop(); + } + connections_.clear(); + } +} + +bool local_tcp_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "lse(" << get_local_port() << ")::send "; + for (uint32_t i = 0; i < _size; i++) + msg << std::setw(2) << std::setfill('0') << std::hex << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + std::lock_guard its_lock(mutex_); + if (endpoint_impl::sending_blocked_) { + return false; + } + + client_t its_client; + std::memcpy(&its_client, &_data[protocol::COMMAND_HEADER_SIZE], sizeof(its_client)); + + connection::ptr its_connection; + { + std::lock_guard its_lock(connections_mutex_); + const auto its_iterator = connections_.find(its_client); + if (its_iterator == connections_.end()) { + return false; + } else { + its_connection = its_iterator->second; + } + } + + auto its_buffer = std::make_shared(); + its_buffer->insert(its_buffer->end(), _data, _data + _size); + its_connection->send_queued(its_buffer); + + return true; +} + +bool local_tcp_server_endpoint_impl::send_to( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_tcp_server_endpoint_impl::send_error( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_tcp_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { + + (void)_it; + + return false; +} + +void local_tcp_server_endpoint_impl::receive() { + + // intentionally left empty +} + +bool local_tcp_server_endpoint_impl::get_default_target( + service_t, + local_tcp_server_endpoint_impl::endpoint_type &) const { + + return false; +} + +bool local_tcp_server_endpoint_impl::add_connection(const client_t &_client, + const std::shared_ptr &_connection) { + + bool ret = false; + std::lock_guard its_lock(connections_mutex_); + auto find_connection = connections_.find(_client); + if (find_connection == connections_.end()) { + connections_[_client] = _connection; + ret = true; + } else { + VSOMEIP_WARNING << "Attempt to add already existing " + "connection to client " << std::hex << _client; + } + return ret; +} + +void local_tcp_server_endpoint_impl::remove_connection( + const client_t &_client) { + + std::lock_guard its_lock(connections_mutex_); + connections_.erase(_client); +} + +void local_tcp_server_endpoint_impl::accept_cbk( + const connection::ptr& _connection, boost::system::error_code const &_error) { + if (_error != boost::asio::error::bad_descriptor + && _error != boost::asio::error::operation_aborted + && _error != boost::asio::error::no_descriptors) { + start(); + } else if (_error == boost::asio::error::no_descriptors) { + VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::accept_cbk: " + << _error.message() << " (" << std::dec << _error.value() + << ") Will try to accept again in 1000ms"; + std::shared_ptr its_timer = + std::make_shared(io_, + std::chrono::milliseconds(1000)); + auto its_ep = std::dynamic_pointer_cast( + shared_from_this()); + its_timer->async_wait([its_timer, its_ep] + (const boost::system::error_code& _error) { + if (!_error) { + its_ep->start(); + } + }); + } + + if (!_error) { + _connection->start(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// class local_service_impl::connection +/////////////////////////////////////////////////////////////////////////////// + +local_tcp_server_endpoint_impl::connection::connection( + const std::shared_ptr &_server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) + : socket_(_io), + server_(_server), + recv_buffer_size_initial_(_initial_recv_buffer_size + 8), + max_message_size_(_max_message_size), + recv_buffer_(recv_buffer_size_initial_, 0), + recv_buffer_size_(0), + missing_capacity_(0), + shrink_count_(0), + buffer_shrink_threshold_(_buffer_shrink_threshold), + bound_client_(VSOMEIP_CLIENT_UNSET), + bound_client_host_(""), + assigned_client_(false) { + if (_server->is_routing_endpoint_ && + !_server->configuration_->is_security_enabled()) { + assigned_client_ = true; + } + + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + sec_client_.client.ip_client.ip = 0; + sec_client_.client.ip_client.port = 0; +} + +local_tcp_server_endpoint_impl::connection::ptr +local_tcp_server_endpoint_impl::connection::create( + const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) { + const std::uint32_t its_initial_buffer_size + = static_cast(protocol::COMMAND_HEADER_SIZE + + sizeof(instance_t) + sizeof(bool) + sizeof(bool)); + return ptr(new connection(_server, _max_message_size, its_initial_buffer_size, + _buffer_shrink_threshold, _io)); +} + +local_tcp_server_endpoint_impl::socket_type & +local_tcp_server_endpoint_impl::connection::get_socket() { + return socket_; +} + +std::unique_lock +local_tcp_server_endpoint_impl::connection::get_socket_lock() { + return std::unique_lock(socket_mutex_); +} + +void local_tcp_server_endpoint_impl::connection::start() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { + const std::size_t its_capacity(recv_buffer_.capacity()); + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; + try { + if (missing_capacity_) { + if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { + VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!"; + return; + } + const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); + if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity + recv_buffer_.reserve(its_required_capacity); + recv_buffer_.resize(its_required_capacity, 0x0); + } + left_buffer_size = missing_capacity_; + missing_capacity_ = 0; + } else if (buffer_shrink_threshold_ + && shrink_count_ > buffer_shrink_threshold_ + && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; + shrink_count_ = 0; + } + } catch (const std::exception &e) { + handle_recv_buffer_exception(e); + // don't start receiving again + return; + } + +#if VSOMEIP_BOOST_VERSION < 106600 + socket_.async_receive( + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), + std::bind( + &local_tcp_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2 + ) + ); +#else + socket_.async_receive( + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), + std::bind( + &local_tcp_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2 + ) + ); +#endif + } +} + +void local_tcp_server_endpoint_impl::connection::stop() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { +#if defined(__linux__) || defined(ANDROID) + if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { + VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) + << "' (" << errno << ") " << get_path_local(); + } +#endif + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } +} + +void local_tcp_server_endpoint_impl::connection::send_queued( + const message_buffer_ptr_t& _buffer) { + + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_server_endpoint_impl::connection::send_queued " + " couldn't lock server_"; + return; + } + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + +#if 0 + std::stringstream msg; + msg << "lse::sq: "; + for (std::size_t i = 0; i < _buffer->size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)(*_buffer)[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_buffer)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + socket_, + bufs, + std::bind( + &local_tcp_server_endpoint_impl::connection::send_cbk, + shared_from_this(), + _buffer, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + } +} + +client_t local_tcp_server_endpoint_impl::assign_client( + const byte_t *_data, uint32_t _size) { + + std::vector its_data(_data, _data + _size); + + protocol::assign_client_command its_command; + protocol::error_e its_error; + + its_command.deserialize(its_data, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": assign client command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + return (VSOMEIP_CLIENT_UNSET); + } + + return (utility::request_client_id(configuration_, + its_command.get_name(), its_command.get_client())); +} + +void local_tcp_server_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, + method_t _method, std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::get_configured_times_from_endpoint."; +} + +void local_tcp_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes) { + (void)_buffer; + (void)_bytes; + if (_error) + VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); +} + +void local_tcp_server_endpoint_impl::connection::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes) +{ + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk " + " couldn't lock server_"; + return; + } + std::shared_ptr its_host = its_server->routing_host_.lock(); + if (!its_host) + return; + + if (_error == boost::asio::error::operation_aborted) { + if (its_server->is_routing_endpoint_ && its_server->configuration_ && + bound_client_ != VSOMEIP_CLIENT_UNSET) { + utility::release_client_id(its_server->configuration_->get_network(), + bound_client_); + set_bound_client(VSOMEIP_CLIENT_UNSET); + } + + // connection was stopped + return; + } + + bool is_error(false); + std::size_t its_start = 0; + std::size_t its_end = 0; + std::size_t its_iteration_gap = 0; + std::uint32_t its_command_size = 0; + + if (!_error && 0 < _bytes) { +#if 0 + std::stringstream msg; + msg << "lse::c<" << this << ">rcb: "; + for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + VSOMEIP_INFO << msg.str(); +#endif + + if (recv_buffer_size_ + _bytes < recv_buffer_size_) { + VSOMEIP_ERROR << "receive buffer overflow in local server endpoint ~> abort!"; + return; + } + recv_buffer_size_ += _bytes; + + bool message_is_empty(false); + bool found_message(false); + + do { + found_message = false; + message_is_empty = false; + + its_start = 0 + its_iteration_gap; + if (its_start + 3 < its_start) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_start + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_start] != 0x67 || + recv_buffer_[its_start+1] != 0x37 || + recv_buffer_[its_start+2] != 0x6d || + recv_buffer_[its_start+3] != 0x07)) { + its_start++; + } + + if (its_start + 3 == recv_buffer_size_ + its_iteration_gap) { + message_is_empty = true; + } else { + its_start += 4; + } + + if (!message_is_empty) { + if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { + its_command_size = VSOMEIP_BYTES_TO_LONG( + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); + + its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; + } else { + its_end = its_start; + } + if (its_command_size && max_message_size_ != MESSAGE_SIZE_UNLIMITED + && its_command_size > max_message_size_) { + std::lock_guard its_lock(socket_mutex_); + VSOMEIP_ERROR << "Received a local message which exceeds " + << "maximum message size (" << std::dec << its_command_size + << ") aborting! local: " << get_path_local() << " remote: " + << get_path_remote(); + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + return; + } + if (its_end + 3 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_end + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_end] != 0x07 || + recv_buffer_[its_end+1] != 0x6d || + recv_buffer_[its_end+2] != 0x37 || + recv_buffer_[its_end+3] != 0x67)) { + its_end ++; + } + if (its_end + 4 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + // check if we received a full message + if (recv_buffer_size_ + its_iteration_gap < its_end + 4 + || recv_buffer_[its_end] != 0x07 + || recv_buffer_[its_end+1] != 0x6d + || recv_buffer_[its_end+2] != 0x37 + || recv_buffer_[its_end+3] != 0x67) { + // command (1 Byte) + version (2 Byte) client id (2 Byte) + // + command size (4 Byte) + data itself + stop tag (4 byte) + // = 11 Bytes not covered in command size. + // If need to change the recv_buffer_, change the value of missing_capacity_ + // in this if/else, otherwise it is 0 + if (its_start - its_iteration_gap + its_command_size + + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE > recv_buffer_size_) { + missing_capacity_ = + std::uint32_t(its_start) - std::uint32_t(its_iteration_gap) + + its_command_size + std::uint32_t(protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) + - std::uint32_t(recv_buffer_size_); + } else if (recv_buffer_size_ < protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) { + // to little data to read out the command size + // minimal amount of data needed to read out command size = 11 + missing_capacity_ = static_cast( + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE - recv_buffer_size_); + } else { + std::stringstream local_msg; + for (std::size_t i = its_iteration_gap; + i < recv_buffer_size_ + its_iteration_gap && + i - its_iteration_gap < 32; i++) { + local_msg << std::setw(2) << std::setfill('0') + << std::hex << (int) recv_buffer_[i] << " "; + } + VSOMEIP_ERROR << "lse::c<" << this + << ">rcb: recv_buffer_size is: " << std::dec + << recv_buffer_size_ << " but couldn't read " + "out command size. recv_buffer_capacity: " + << std::dec << recv_buffer_.capacity() + << " its_iteration_gap: " << std::dec + << its_iteration_gap << " bound client: 0x" + << std::hex << bound_client_ << " buffer: " + << local_msg.str(); + recv_buffer_size_ = 0; + missing_capacity_ = 0; + its_iteration_gap = 0; + message_is_empty = true; + } + } + } + + if (!message_is_empty && + its_end + 3 < recv_buffer_size_ + its_iteration_gap) { + + if (its_server->is_routing_endpoint_ + && recv_buffer_[its_start] == protocol::id_e::ASSIGN_CLIENT_ID) { + client_t its_client = its_server->assign_client( + &recv_buffer_[its_start], uint32_t(its_end - its_start)); + { + set_bound_client(its_client); + its_host->add_known_client(its_client, get_bound_client_host()); + its_server->add_connection(its_client, shared_from_this()); + } + its_server->send_client_identifier(its_client); + assigned_client_ = true; + } else if (!its_server->is_routing_endpoint_ || assigned_client_) { + + auto its_address = socket_.remote_endpoint().address(); + auto its_port = socket_.remote_endpoint().port(); + + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + if (its_address.is_v4()) { + sec_client_.client.ip_client.ip + = htonl(uint32_t(its_address.to_v4().to_ulong())); + } + sec_client_.client.ip_client.port = its_port; + + its_host->on_message(&recv_buffer_[its_start], + uint32_t(its_end - its_start), its_server.get(), + false, bound_client_, &sec_client_, + its_address, its_port); + } else { + VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() + << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; + } + #if 0 + std::stringstream local_msg; + local_msg << "lse::c<" << this << ">rcb::thunk: "; + for (std::size_t i = its_start; i < its_end; i++) + local_msg << std::setw(2) << std::setfill('0') << std::hex + << (int) recv_buffer_[i] << " "; + VSOMEIP_INFO << local_msg.str(); + #endif + calculate_shrink_count(); + recv_buffer_size_ -= (its_end + 4 - its_iteration_gap); + missing_capacity_ = 0; + its_command_size = 0; + found_message = true; + its_iteration_gap = its_end + 4; + } else { + if (its_iteration_gap) { + // Message not complete and not in front of the buffer! + // Copy last part to front for consume in future receive_cbk call! + for (size_t i = 0; i < recv_buffer_size_; ++i) { + recv_buffer_[i] = recv_buffer_[i + its_iteration_gap]; + } + // Still more capacity needed after shifting everything to front? + if (missing_capacity_ && + missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) { + missing_capacity_ = 0; + } + } else if (message_is_empty) { + VSOMEIP_ERROR << "Received garbage data."; + is_error = true; + } + } + } while (recv_buffer_size_ > 0 && found_message); + } + + if (_error == boost::asio::error::eof + || _error == boost::asio::error::connection_reset + || is_error) { + stop(); + its_server->remove_connection(bound_client_); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); + } else if (_error != boost::asio::error::bad_descriptor) { + start(); + } +} + +void local_tcp_server_endpoint_impl::connection::set_bound_client(client_t _client) { + bound_client_ = _client; +} + +client_t local_tcp_server_endpoint_impl::connection::get_bound_client() const { + return bound_client_; +} + +void local_tcp_server_endpoint_impl::connection::set_bound_client_host( + const std::string &_bound_client_host) { + bound_client_host_ = _bound_client_host; +} + +std::string local_tcp_server_endpoint_impl::connection::get_bound_client_host() const { + return bound_client_host_; +} + +void local_tcp_server_endpoint_impl::connection::calculate_shrink_count() { + if (buffer_shrink_threshold_) { + if (recv_buffer_.capacity() != recv_buffer_size_initial_) { + if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) { + shrink_count_++; + } else { + shrink_count_ = 0; + } + } + } +} + +std::string local_tcp_server_endpoint_impl::connection::get_path_local() const { + boost::system::error_code ec; + std::string its_local_path; + if (socket_.is_open()) { + endpoint_type its_local_endpoint = socket_.local_endpoint(ec); + if (!ec) { + its_local_path += its_local_endpoint.address().to_string(ec); + its_local_path += ":"; + its_local_path += std::to_string(its_local_endpoint.port()); + } + } + return its_local_path; +} + +std::string local_tcp_server_endpoint_impl::connection::get_path_remote() const { + boost::system::error_code ec; + std::string its_remote_path; + if (socket_.is_open()) { + endpoint_type its_remote_endpoint = socket_.remote_endpoint(ec); + if (!ec) { + its_remote_path += its_remote_endpoint.address().to_string(ec); + its_remote_path += ":"; + its_remote_path += std::to_string(its_remote_endpoint.port()); + } + } + return its_remote_path; +} + +void local_tcp_server_endpoint_impl::connection::handle_recv_buffer_exception( + const std::exception &_e) { + std::stringstream its_message; + its_message <<"local_tcp_server_endpoint_impl::connection catched exception" + << _e.what() << " local: " << get_path_local() << " remote: " + << get_path_remote() << " shutting down connection. Start of buffer: "; + + for (std::size_t i = 0; i < recv_buffer_size_ && i < 16; i++) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + } + + its_message << " Last 16 Bytes captured: "; + for (int i = 15; recv_buffer_size_ > 15u && i >= 0; i--) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[static_cast(i)]) << " "; + } + VSOMEIP_ERROR << its_message.str(); + recv_buffer_.clear(); + if (socket_.is_open()) { + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } + std::shared_ptr its_server = server_.lock(); + if (its_server) { + its_server->remove_connection(bound_client_); + } +} + +std::size_t +local_tcp_server_endpoint_impl::connection::get_recv_buffer_capacity() const { + return recv_buffer_.capacity(); +} + +void local_tcp_server_endpoint_impl::print_status() { + std::lock_guard its_lock(mutex_); + connections_t its_connections; + { + std::lock_guard its_lock(connections_mutex_); + its_connections = connections_; + } + std::string its_local_path("TCP"); + VSOMEIP_INFO << "status lse: " << its_local_path << " connections: " + << std::dec << its_connections.size() << " queues: " + << std::dec << targets_.size(); + for (const auto &c : its_connections) { + std::string its_remote_path; // TODO: construct the path + + std::size_t its_recv_size(0); + { + std::unique_lock c_s_lock(c.second->get_socket_lock()); + its_recv_size = c.second->get_recv_buffer_capacity(); + } + + VSOMEIP_INFO << "status lse: client: " << its_remote_path + << " recv_buffer: " << std::dec << its_recv_size; + } +} +std::string local_tcp_server_endpoint_impl::get_remote_information( + const target_data_iterator_type _it) const { + boost::system::error_code ec; + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); +} + +std::string local_tcp_server_endpoint_impl::get_remote_information( + const endpoint_type& _remote) const { + + boost::system::error_code ec; + return _remote.address().to_string(ec) + ":" + + std::to_string(_remote.port()); +} + +bool local_tcp_server_endpoint_impl::is_reliable() const { + return false; +} + +std::uint16_t local_tcp_server_endpoint_impl::get_local_port() const { + + return local_port_; +} + +void local_tcp_server_endpoint_impl::set_local_port(std::uint16_t _port) { + + (void)_port; + // Intentionally left empty +} + +bool local_tcp_server_endpoint_impl::check_packetizer_space( + target_data_iterator_type _it, message_buffer_ptr_t* _packetizer, + std::uint32_t _size) { + + if ((*_packetizer)->size() + _size < (*_packetizer)->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if ((*_packetizer)->size() + _size > max_message_size_ + && !(*_packetizer)->empty()) { + _it->second.queue_.push_back(std::make_pair(*_packetizer, 0)); + _it->second.queue_size_ += (*_packetizer)->size(); + *_packetizer = std::make_shared(); + } + return true; +} + +void +local_tcp_server_endpoint_impl::send_client_identifier( + const client_t &_client) { + + protocol::assign_client_ack_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_assigned(_client); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + + VSOMEIP_ERROR << __func__ + << ": assign client ack command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + send(&its_buffer[0], static_cast(its_buffer.size())); +} + +bool local_tcp_server_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp similarity index 65% rename from implementation/endpoints/src/local_client_endpoint_impl.cpp rename to implementation/endpoints/src/local_uds_client_endpoint_impl.cpp index 04c778778..a69c3b861 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,45 +11,43 @@ #include #include +#include "../include/credentials.hpp" #include "../include/endpoint_host.hpp" -#include "../include/local_client_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" +#include "../include/local_uds_client_endpoint_impl.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#include "../../protocol/include/protocol.hpp" #include "../../routing/include/routing_host.hpp" -#include "../../security/include/security.hpp" - -// Credentials -#ifndef _WIN32 -#include "../include/credentials.hpp" -#endif namespace vsomeip_v3 { -local_client_endpoint_impl::local_client_endpoint_impl( +local_uds_client_endpoint_impl::local_uds_client_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) - : local_client_endpoint_base_impl(_endpoint_host, _routing_host, _remote, - _remote, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), - // Using _remote for the local(!) endpoint is ok, - // because we have no bind for local endpoints! - recv_buffer_(VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE + 8,0) { + : local_uds_client_endpoint_base_impl(_endpoint_host, _routing_host, _remote, + _remote, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + // Using _remote for the local(!) endpoint is ok, + // because we have no bind for local endpoints! + recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { + is_supporting_magic_cookies_ = false; } -local_client_endpoint_impl::~local_client_endpoint_impl() { +local_uds_client_endpoint_impl::~local_uds_client_endpoint_impl() { } -bool local_client_endpoint_impl::is_local() const { +bool local_uds_client_endpoint_impl::is_local() const { + return true; } -void local_client_endpoint_impl::restart(bool _force) { +void local_uds_client_endpoint_impl::restart(bool _force) { if (!_force && state_ == cei_state_e::CONNECTING) { return; } @@ -69,11 +67,12 @@ void local_client_endpoint_impl::restart(bool _force) { start_connect_timer(); } -void local_client_endpoint_impl::start() { +void local_uds_client_endpoint_impl::start() { + connect(); } -void local_client_endpoint_impl::stop() { +void local_uds_client_endpoint_impl::stop() { { std::lock_guard its_lock(mutex_); sending_blocked_ = true; @@ -109,7 +108,8 @@ void local_client_endpoint_impl::stop() { shutdown_and_close_socket(false); } -void local_client_endpoint_impl::connect() { +void local_uds_client_endpoint_impl::connect() { + start_connecting_timer(); boost::system::error_code its_connect_error; { std::lock_guard its_lock(socket_mutex_); @@ -125,13 +125,12 @@ void local_client_endpoint_impl::connect() { state_ = cei_state_e::CONNECTING; socket_->connect(remote_, its_connect_error); -// Credentials -#ifndef _WIN32 + // Credentials if (!its_connect_error) { auto its_host = endpoint_host_.lock(); if (its_host) { credentials::send_credentials(socket_->native_handle(), - its_host->get_client()); + its_host->get_client(), its_host->get_client_host()); } } else { VSOMEIP_WARNING << "local_client_endpoint::connect: Couldn't " @@ -139,8 +138,6 @@ void local_client_endpoint_impl::connect() { << its_connect_error.message() << " / " << std::dec << its_connect_error.value() << ")"; } -#endif - } else { VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " << its_error.message() << " (" << std::dec << its_error.value() @@ -158,16 +155,16 @@ void local_client_endpoint_impl::connect() { } } -void local_client_endpoint_impl::receive() { +void local_uds_client_endpoint_impl::receive() { std::lock_guard its_lock(socket_mutex_); if (socket_->is_open()) { socket_->async_receive( boost::asio::buffer(recv_buffer_), strand_.wrap( std::bind( - &local_client_endpoint_impl::receive_cbk, + &local_uds_client_endpoint_impl::receive_cbk, std::dynamic_pointer_cast< - local_client_endpoint_impl + local_uds_client_endpoint_impl >(shared_from_this()), std::placeholders::_1, std::placeholders::_2 @@ -179,7 +176,7 @@ void local_client_endpoint_impl::receive() { // this overrides client_endpoint_impl::send to disable the pull method // for local communication -bool local_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { +bool local_uds_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { std::lock_guard its_lock(mutex_); bool ret(true); const bool queue_size_zero_on_entry(queue_.empty()); @@ -197,19 +194,21 @@ bool local_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { << (int)_data[i] << " "; VSOMEIP_INFO << msg.str(); #endif - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - queue_train(queue_size_zero_on_entry); + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + queue_train(train_, queue_size_zero_on_entry); + train_->buffer_ = std::make_shared(); } return ret; } -void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { +void local_uds_client_endpoint_impl::send_queued(std::pair &_entry) { + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; std::vector bufs; bufs.push_back(boost::asio::buffer(its_start_tag)); - bufs.push_back(boost::asio::buffer(*_buffer)); + bufs.push_back(boost::asio::buffer(*_entry.first)); bufs.push_back(boost::asio::buffer(its_end_tag)); { @@ -220,20 +219,21 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { std::bind( &client_endpoint_impl::send_cbk, std::dynamic_pointer_cast< - local_client_endpoint_impl + local_uds_client_endpoint_impl >(shared_from_this()), std::placeholders::_1, std::placeholders::_2, - _buffer + _entry.first ) ); } } -void local_client_endpoint_impl::get_configured_times_from_endpoint( +void local_uds_client_endpoint_impl::get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const { + (void)_service; (void)_method; (void)_debouncing; @@ -241,11 +241,13 @@ void local_client_endpoint_impl::get_configured_times_from_endpoint( VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; } -void local_client_endpoint_impl::send_magic_cookie() { +void local_uds_client_endpoint_impl::send_magic_cookie() { + } -void local_client_endpoint_impl::receive_cbk( +void local_uds_client_endpoint_impl::receive_cbk( boost::system::error_code const &_error, std::size_t _bytes) { + if (_error) { if (_error == boost::asio::error::operation_aborted) { // endpoint was stopped @@ -253,8 +255,8 @@ void local_client_endpoint_impl::receive_cbk( } else if (_error == boost::asio::error::connection_reset || _error == boost::asio::error::eof || _error == boost::asio::error::bad_descriptor) { - VSOMEIP_TRACE << "local_client_endpoint:" - " connection_reseted/EOF/bad_descriptor"; + VSOMEIP_INFO << __func__ << " local_uds_client_endpoint:" + " connection_reset/EOF/bad_descriptor"; } else if (_error) { VSOMEIP_ERROR << "Local endpoint received message (" << _error.message() << ")"; @@ -279,12 +281,13 @@ void local_client_endpoint_impl::receive_cbk( // We only handle a single message here. Check whether the message // format matches what we do expect. - if (_bytes == VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE + 8 + // TODO: Replace the magic numbers. + if (_bytes == VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE && recv_buffer_[0] == 0x67 && recv_buffer_[1] == 0x37 && recv_buffer_[2] == 0x6d && recv_buffer_[3] == 0x07 - && recv_buffer_[4] == VSOMEIP_ASSIGN_CLIENT_ACK - && recv_buffer_[13] == 0x07 && recv_buffer_[14] == 0x6d - && recv_buffer_[15] == 0x37 && recv_buffer_[16] == 0x67) { + && recv_buffer_[4] == byte_t(protocol::id_e::ASSIGN_CLIENT_ACK_ID) + && recv_buffer_[15] == 0x07 && recv_buffer_[16] == 0x6d + && recv_buffer_[17] == 0x37 && recv_buffer_[18] == 0x67) { auto its_routing_host = routing_host_.lock(); if (its_routing_host) @@ -296,28 +299,26 @@ void local_client_endpoint_impl::receive_cbk( } } -bool local_client_endpoint_impl::get_remote_address( +bool local_uds_client_endpoint_impl::get_remote_address( boost::asio::ip::address &_address) const { (void)_address; return false; } -std::uint16_t local_client_endpoint_impl::get_remote_port() const { +std::uint16_t local_uds_client_endpoint_impl::get_remote_port() const { return 0; } -void local_client_endpoint_impl::set_local_port() { +void local_uds_client_endpoint_impl::set_local_port() { // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing } -void local_client_endpoint_impl::print_status() { -#ifndef _WIN32 +void local_uds_client_endpoint_impl::print_status() { + std::string its_path = remote_.path(); -#else - std::string its_path(""); -#endif std::size_t its_data_size(0); std::size_t its_queue_size(0); + { std::lock_guard its_lock(mutex_); its_queue_size = queue_.size(); @@ -328,77 +329,46 @@ void local_client_endpoint_impl::print_status() { << its_queue_size << " data: " << its_data_size; } -std::string local_client_endpoint_impl::get_remote_information() const { -#ifdef _WIN32 - boost::system::error_code ec; - return remote_.address().to_string(ec) + ":" - + std::to_string(remote_.port()); -#else +std::string local_uds_client_endpoint_impl::get_remote_information() const { + return remote_.path(); -#endif } -bool local_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { - if (train_.buffer_->size() + _size < train_.buffer_->size()) { +bool local_uds_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { + if (train_->buffer_->size() + _size < train_->buffer_->size()) { VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; return false; } - if (train_.buffer_->size() + _size > max_message_size_ - && !train_.buffer_->empty()) { - queue_.push_back(train_.buffer_); - queue_size_ += train_.buffer_->size(); - train_.buffer_ = std::make_shared(); + if (train_->buffer_->size() + _size > max_message_size_ + && !train_->buffer_->empty()) { + queue_.push_back(std::make_pair(train_->buffer_, 0)); + queue_size_ += train_->buffer_->size(); + train_->buffer_ = std::make_shared(); } return true; } -bool local_client_endpoint_impl::is_reliable() const { - return false; -} +bool local_uds_client_endpoint_impl::is_reliable() const { -std::uint32_t local_client_endpoint_impl::get_max_allowed_reconnects() const { - return 13; + return false; } -bool local_client_endpoint_impl::send(const std::vector& _cmd_header, - const byte_t *_data, uint32_t _size) { - std::lock_guard its_lock(mutex_); - bool ret(true); - const bool queue_size_zero_on_entry(queue_.empty()); +std::uint32_t local_uds_client_endpoint_impl::get_max_allowed_reconnects() const { - const std::uint32_t its_complete_size = static_cast( - _cmd_header.size() + _size); - if (endpoint_impl::sending_blocked_ || - check_message_size(nullptr, its_complete_size) != cms_ret_e::MSG_OK || - !check_packetizer_space(its_complete_size)|| - !check_queue_limit(_data, its_complete_size)) { - ret = false; - } else { -#if 0 - std::stringstream msg; - msg << "lce::send: "; - for (uint32_t i = 0; i < _size; i++) - msg << std::hex << std::setw(2) << std::setfill('0') - << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - train_.buffer_->reserve(its_complete_size); - train_.buffer_->insert(train_.buffer_->end(), _cmd_header.begin(), _cmd_header.end()); - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - queue_train(queue_size_zero_on_entry); - } - return ret; + return 13; } -bool local_client_endpoint_impl::tp_segmentation_enabled( +bool local_uds_client_endpoint_impl::tp_segmentation_enabled( service_t _service, method_t _method) const { + (void)_service; (void)_method; return false; } -void local_client_endpoint_impl::max_allowed_reconnects_reached() { +void local_uds_client_endpoint_impl::max_allowed_reconnects_reached() { + VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " << get_remote_information(); error_handler_t handler; diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp similarity index 60% rename from implementation/endpoints/src/local_server_endpoint_impl.cpp rename to implementation/endpoints/src/local_uds_server_endpoint_impl.cpp index ebf913f32..8aa213906 100644 --- a/implementation/endpoints/src/local_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,32 +12,31 @@ #include +#include "../include/credentials.hpp" #include "../include/endpoint_host.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#include "../include/local_server_endpoint_impl_receive_op.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" #include "../../routing/include/routing_host.hpp" -#include "../include/local_server_endpoint_impl.hpp" -#include "../../security/include/security.hpp" +#include "../../security/include/policy_manager_impl.hpp" #include "../../utility/include/byteorder.hpp" -#include "../../configuration/include/configuration.hpp" #include "../../utility/include/utility.hpp" -// Credentials -#ifndef _WIN32 -#include "../include/credentials.hpp" -#endif - namespace vsomeip_v3 { -local_server_endpoint_impl::local_server_endpoint_impl( +local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_service &_io, + const endpoint_type& _local, boost::asio::io_context &_io, const std::shared_ptr& _configuration, bool _is_routing_endpoint) - : local_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, + _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), acceptor_(_io), buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), is_routing_endpoint_(_is_routing_endpoint) { @@ -45,34 +44,43 @@ local_server_endpoint_impl::local_server_endpoint_impl( boost::system::error_code ec; acceptor_.open(_local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": open failed (" << ec.message() << ")"; + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; + acceptor_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": listen failed (" << ec.message() << ")"; -#ifndef _WIN32 if (chmod(_local.path().c_str(), static_cast(_configuration->get_permissions_uds())) == -1) { VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); } credentials::activate_credentials(acceptor_.native_handle()); -#endif } -local_server_endpoint_impl::local_server_endpoint_impl( +local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_service &_io, + const endpoint_type& _local, boost::asio::io_context &_io, int native_socket, const std::shared_ptr& _configuration, bool _is_routing_endpoint) - : local_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), acceptor_(_io), buffer_shrink_threshold_(configuration_->get_buffer_shrink_threshold()), is_routing_endpoint_(_is_routing_endpoint) { @@ -80,41 +88,44 @@ local_server_endpoint_impl::local_server_endpoint_impl( boost::system::error_code ec; acceptor_.assign(_local.protocol(), native_socket, ec); - boost::asio::detail::throw_error(ec, "acceptor assign native socket"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": assign failed (" << ec.message() << ")"; -#ifndef _WIN32 if (chmod(_local.path().c_str(), static_cast(_configuration->get_permissions_uds())) == -1) { VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); } credentials::activate_credentials(acceptor_.native_handle()); -#endif } -local_server_endpoint_impl::~local_server_endpoint_impl() { +local_uds_server_endpoint_impl::~local_uds_server_endpoint_impl() { + } -bool local_server_endpoint_impl::is_local() const { +bool local_uds_server_endpoint_impl::is_local() const { + return true; } -void local_server_endpoint_impl::start() { +void local_uds_server_endpoint_impl::start() { + std::lock_guard its_lock(acceptor_mutex_); if (acceptor_.is_open()) { connection::ptr new_connection = connection::create( - std::dynamic_pointer_cast( + std::dynamic_pointer_cast( shared_from_this()), max_message_size_, buffer_shrink_threshold_, - service_); + io_); { std::unique_lock its_lock(new_connection->get_socket_lock()); acceptor_.async_accept( new_connection->get_socket(), std::bind( - &local_server_endpoint_impl::accept_cbk, + &local_uds_server_endpoint_impl::accept_cbk, std::dynamic_pointer_cast< - local_server_endpoint_impl + local_uds_server_endpoint_impl >(shared_from_this()), new_connection, std::placeholders::_1 @@ -124,7 +135,8 @@ void local_server_endpoint_impl::start() { } } -void local_server_endpoint_impl::stop() { +void local_uds_server_endpoint_impl::stop() { + server_endpoint_impl::stop(); { std::lock_guard its_lock(acceptor_mutex_); @@ -142,7 +154,7 @@ void local_server_endpoint_impl::stop() { } } -bool local_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { +bool local_uds_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { #if 0 std::stringstream msg; msg << "lse::send "; @@ -156,7 +168,7 @@ bool local_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { } client_t its_client; - std::memcpy(&its_client, &_data[7], sizeof(its_client)); + std::memcpy(&its_client, &_data[protocol::COMMAND_HEADER_SIZE], sizeof(its_client)); connection::ptr its_connection; { @@ -176,41 +188,48 @@ bool local_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { return true; } -bool local_server_endpoint_impl::send_to( +bool local_uds_server_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; return false; } -bool local_server_endpoint_impl::send_error( +bool local_uds_server_endpoint_impl::send_error( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; return false; } -void local_server_endpoint_impl::send_queued( - const queue_iterator_type _queue_iterator) { - (void)_queue_iterator; +bool local_uds_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { + + (void)_it; + + return false; } -void local_server_endpoint_impl::receive() { +void local_uds_server_endpoint_impl::receive() { // intentionally left empty } -bool local_server_endpoint_impl::get_default_target( +bool local_uds_server_endpoint_impl::get_default_target( service_t, - local_server_endpoint_impl::endpoint_type &) const { + local_uds_server_endpoint_impl::endpoint_type &) const { + return false; } -bool local_server_endpoint_impl::add_connection(const client_t &_client, +bool local_uds_server_endpoint_impl::add_connection(const client_t &_client, const std::shared_ptr &_connection) { + bool ret = false; std::lock_guard its_lock(connections_mutex_); auto find_connection = connections_.find(_client); @@ -224,26 +243,27 @@ bool local_server_endpoint_impl::add_connection(const client_t &_client, return ret; } -void local_server_endpoint_impl::remove_connection( +void local_uds_server_endpoint_impl::remove_connection( const client_t &_client) { + std::lock_guard its_lock(connections_mutex_); connections_.erase(_client); } -void local_server_endpoint_impl::accept_cbk( +void local_uds_server_endpoint_impl::accept_cbk( const connection::ptr& _connection, boost::system::error_code const &_error) { if (_error != boost::asio::error::bad_descriptor && _error != boost::asio::error::operation_aborted && _error != boost::asio::error::no_descriptors) { start(); } else if (_error == boost::asio::error::no_descriptors) { - VSOMEIP_ERROR << "local_server_endpoint_impl::accept_cbk: " + VSOMEIP_ERROR << "local_usd_server_endpoint_impl::accept_cbk: " << _error.message() << " (" << std::dec << _error.value() << ") Will try to accept again in 1000ms"; std::shared_ptr its_timer = - std::make_shared(service_, + std::make_shared(io_, std::chrono::milliseconds(1000)); - auto its_ep = std::dynamic_pointer_cast( + auto its_ep = std::dynamic_pointer_cast( shared_from_this()); its_timer->async_wait([its_timer, its_ep] (const boost::system::error_code& _error) { @@ -254,65 +274,101 @@ void local_server_endpoint_impl::accept_cbk( } if (!_error) { -#ifndef _WIN32 auto its_host = endpoint_host_.lock(); - client_t client = 0; - - socket_type &new_connection_socket = _connection->get_socket(); - uid_t uid(ANY_UID); - gid_t gid(ANY_GID); - client = credentials::receive_credentials( - new_connection_socket.native_handle(), uid, gid); - - if (its_host && security::get()->is_enabled()) { - if (!configuration_->check_routing_credentials(client, uid, gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Rejecting new connection with routing manager client ID 0x" << std::hex << client - << " uid/gid= " << std::dec << uid << "/" << gid + client_t its_client = 0; + std::string its_client_host; + vsomeip_sec_client_t its_sec_client; + + its_sec_client.client_type = VSOMEIP_CLIENT_UDS; + its_sec_client.client.uds_client.user = ANY_UID; + its_sec_client.client.uds_client.group = ANY_GID; + + socket_type &its_socket = _connection->get_socket(); + if (auto creds = credentials::receive_credentials(its_socket.native_handle())) { + + its_client = std::get<0>(*creds); + its_client_host = std::get<3>(*creds); + + its_sec_client.client.uds_client.user = std::get<1>(*creds); + its_sec_client.client.uds_client.group = std::get<2>(*creds); + } else { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_host->get_client() + << " is rejecting new connection because client credentials couldn't be received!"; + boost::system::error_code er; + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); + return; + } + + if (its_host && configuration_->is_security_enabled()) { + if (!configuration_->check_routing_credentials(its_client, &its_sec_client)) { + VSOMEIP_WARNING << "vSomeIP Security: Rejecting new connection with routing manager client ID 0x" + << std::hex << its_client + << " uid/gid= " << std::dec + << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group << " because passed credentials do not match with routing manager credentials!"; boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); return; } if (is_routing_endpoint_) { // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later - _connection->set_bound_uid_gid(uid, gid); + _connection->set_bound_sec_client(its_sec_client); + _connection->set_bound_client_host(its_client_host); } else { { std::lock_guard its_connection_lock(connections_mutex_); // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later - const auto found_client = connections_.find(client); + const auto found_client = connections_.find(its_client); if (found_client != connections_.end()) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_host->get_client() << " is rejecting new connection with client ID 0x" - << client << " uid/gid= " << std::dec << uid << "/" << gid + << its_client << " uid/gid= " << std::dec + << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group << " because of already existing connection using same client ID"; boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); return; } } - if (!security::get()->check_credentials(client, uid, gid)) { + + // Add to known clients (loads new config if needed) + std::shared_ptr its_routing_host = routing_host_.lock(); + its_routing_host->add_known_client(its_client, its_client_host); + + if (!policy_manager_impl::get()->check_credentials(its_client, &its_sec_client)) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_host->get_client() << " received client credentials from client 0x" - << client << " which violates the security policy : uid/gid=" - << std::dec << uid << "/" << gid; + << its_client << " which violates the security policy : uid/gid=" + << std::dec << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group; boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); return; } // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> set later - _connection->set_bound_client(client); - add_connection(client, _connection); + _connection->set_bound_client(its_client); + _connection->set_bound_client_host(its_client_host); + add_connection(its_client, _connection); } } else { - security::get()->store_client_to_uid_gid_mapping(client, uid, gid); - security::get()->store_uid_gid_to_client_mapping(uid, gid, client); + policy_manager_impl::get()->store_client_to_sec_client_mapping(its_client, &its_sec_client); + policy_manager_impl::get()->store_sec_client_to_client_mapping(&its_sec_client, its_client); + + if (!is_routing_endpoint_) { + std::shared_ptr its_routing_host = routing_host_.lock(); + its_routing_host->add_known_client(its_client, its_client_host); + _connection->set_bound_client(its_client); + } + _connection->set_bound_client_host(its_client_host); } -#endif + _connection->start(); } } @@ -321,13 +377,13 @@ void local_server_endpoint_impl::accept_cbk( // class local_service_impl::connection /////////////////////////////////////////////////////////////////////////////// -local_server_endpoint_impl::connection::connection( - const std::shared_ptr& _server, +local_uds_server_endpoint_impl::connection::connection( + const std::shared_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _initial_recv_buffer_size, std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service) - : socket_(_io_service), + boost::asio::io_context &_io) + : socket_(_io), server_(_server), recv_buffer_size_initial_(_initial_recv_buffer_size + 8), max_message_size_(_max_message_size), @@ -337,45 +393,52 @@ local_server_endpoint_impl::connection::connection( shrink_count_(0), buffer_shrink_threshold_(_buffer_shrink_threshold), bound_client_(VSOMEIP_CLIENT_UNSET), -#ifndef _WIN32 - bound_uid_(ANY_UID), - bound_gid_(ANY_GID), -#endif + bound_client_host_(""), assigned_client_(false) { if (_server->is_routing_endpoint_ && - !security::get()->is_enabled()) { + !_server->configuration_->is_security_enabled()) { assigned_client_ = true; } + + sec_client_.client_type = VSOMEIP_CLIENT_UDS; + sec_client_.client.uds_client.user = ANY_UID; + sec_client_.client.uds_client.group = ANY_GID; } -local_server_endpoint_impl::connection::ptr -local_server_endpoint_impl::connection::create( - const std::shared_ptr& _server, +local_uds_server_endpoint_impl::connection::ptr +local_uds_server_endpoint_impl::connection::create( + const std::shared_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service) { - const std::uint32_t its_initial_buffer_size = VSOMEIP_COMMAND_HEADER_SIZE - + static_cast(sizeof(instance_t) + sizeof(bool) - + sizeof(bool)); + boost::asio::io_context &_io) { + const std::uint32_t its_initial_buffer_size + = static_cast(protocol::COMMAND_HEADER_SIZE + + sizeof(instance_t) + sizeof(bool) + sizeof(bool)); return ptr(new connection(_server, _max_message_size, its_initial_buffer_size, - _buffer_shrink_threshold, _io_service)); + _buffer_shrink_threshold, _io)); } -local_server_endpoint_impl::socket_type & -local_server_endpoint_impl::connection::get_socket() { +local_uds_server_endpoint_impl::socket_type & +local_uds_server_endpoint_impl::connection::get_socket() { return socket_; } std::unique_lock -local_server_endpoint_impl::connection::get_socket_lock() { +local_uds_server_endpoint_impl::connection::get_socket_lock() { return std::unique_lock(socket_mutex_); } -void local_server_endpoint_impl::connection::start() { +void local_uds_server_endpoint_impl::connection::start() { std::lock_guard its_lock(socket_mutex_); if (socket_.is_open()) { const std::size_t its_capacity(recv_buffer_.capacity()); - size_t buffer_size = its_capacity - recv_buffer_size_; + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; try { if (missing_capacity_) { if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { @@ -384,17 +447,20 @@ void local_server_endpoint_impl::connection::start() { } const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity recv_buffer_.reserve(its_required_capacity); recv_buffer_.resize(its_required_capacity, 0x0); } - buffer_size = missing_capacity_; + left_buffer_size = missing_capacity_; missing_capacity_ = 0; } else if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_ && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ recv_buffer_.resize(recv_buffer_size_initial_, 0x0); recv_buffer_.shrink_to_fit(); - buffer_size = recv_buffer_size_initial_; + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; shrink_count_ = 0; } } catch (const std::exception &e) { @@ -402,52 +468,60 @@ void local_server_endpoint_impl::connection::start() { // don't start receiving again return; } -#ifndef _WIN32 - socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), + +#if VSOMEIP_BOOST_VERSION >= 106600 + local_server_endpoint_impl_receive_op its_operation { + socket_, std::bind( - &local_server_endpoint_impl::connection::receive_cbk, + &local_uds_server_endpoint_impl::connection::receive_cbk, shared_from_this(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4 - ) - ); + ), + &recv_buffer_[recv_buffer_size_], + left_buffer_size, + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::min() + }; + socket_.async_wait(socket_type::wait_read, its_operation); #else socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), std::bind( - &local_server_endpoint_impl::connection::receive_cbk, + &local_uds_server_endpoint_impl::connection::receive_cbk, shared_from_this(), std::placeholders::_1, - std::placeholders::_2 + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4 ) ); #endif } } -void local_server_endpoint_impl::connection::stop() { +void local_uds_server_endpoint_impl::connection::stop() { std::lock_guard its_lock(socket_mutex_); if (socket_.is_open()) { -#ifndef _WIN32 if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) << "' (" << errno << ") " << get_path_local(); } -#endif boost::system::error_code its_error; socket_.shutdown(socket_.shutdown_both, its_error); socket_.close(its_error); } } -void local_server_endpoint_impl::connection::send_queued( +void local_uds_server_endpoint_impl::connection::send_queued( const message_buffer_ptr_t& _buffer) { - std::shared_ptr its_server(server_.lock()); + + std::shared_ptr its_server(server_.lock()); if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::send_queued " + VSOMEIP_TRACE << "local_uds_server_endpoint_impl::connection::send_queued " " couldn't lock server_"; return; } @@ -475,7 +549,7 @@ void local_server_endpoint_impl::connection::send_queued( socket_, bufs, std::bind( - &local_server_endpoint_impl::connection::send_cbk, + &local_uds_server_endpoint_impl::connection::send_cbk, shared_from_this(), _buffer, std::placeholders::_1, @@ -485,28 +559,27 @@ void local_server_endpoint_impl::connection::send_queued( } } -client_t local_server_endpoint_impl::assign_client( +client_t local_uds_server_endpoint_impl::assign_client( const byte_t *_data, uint32_t _size) { - client_t its_client(VSOMEIP_CLIENT_UNSET); - std::string its_name; - uint32_t its_name_length; - if (_size >= VSOMEIP_COMMAND_PAYLOAD_POS) { - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], sizeof(its_client)); - std::memcpy(&its_name_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_name_length)); + std::vector its_data(_data, _data + _size); - if (its_name_length > 0) - its_name.assign(reinterpret_cast( - &_data[VSOMEIP_COMMAND_PAYLOAD_POS]), its_name_length); - } + protocol::assign_client_command its_command; + protocol::error_e its_error; - its_client = utility::request_client_id(configuration_, its_name, its_client); + its_command.deserialize(its_data, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": assign client command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + return (VSOMEIP_CLIENT_UNSET); + } - return its_client; + return (utility::request_client_id(configuration_, + its_command.get_name(), its_command.get_client())); } -void local_server_endpoint_impl::get_configured_times_from_endpoint( +void local_uds_server_endpoint_impl::get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const { @@ -514,10 +587,10 @@ void local_server_endpoint_impl::get_configured_times_from_endpoint( (void)_method; (void)_debouncing; (void)_maximum_retention; - VSOMEIP_ERROR << "local_server_endpoint_impl::get_configured_times_from_endpoint."; + VSOMEIP_ERROR << "local_uds_server_endpoint_impl::get_configured_times_from_endpoint."; } -void local_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, +void local_uds_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes) { (void)_buffer; (void)_bytes; @@ -525,28 +598,26 @@ void local_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); } -void local_server_endpoint_impl::connection::receive_cbk( - boost::system::error_code const &_error, std::size_t _bytes -#ifndef _WIN32 - , std::uint32_t const &_uid, std::uint32_t const &_gid -#endif - ) +void local_uds_server_endpoint_impl::connection::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes, + std::uint32_t const &_uid, std::uint32_t const &_gid) { - std::shared_ptr its_server(server_.lock()); + std::shared_ptr its_server(server_.lock()); if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk " + VSOMEIP_TRACE << "local_uds_server_endpoint_impl::connection::receive_cbk " " couldn't lock server_"; return; } - std::shared_ptr its_host = its_server->routing_host_.lock(); if (!its_host) return; + std::shared_ptr its_config = its_server->configuration_; if (_error == boost::asio::error::operation_aborted) { if (its_server->is_routing_endpoint_ && - bound_client_ != VSOMEIP_CLIENT_UNSET) { - utility::release_client_id(bound_client_); + bound_client_ != VSOMEIP_CLIENT_UNSET && its_config) { + utility::release_client_id(its_config->get_network(), + bound_client_); set_bound_client(VSOMEIP_CLIENT_UNSET); } @@ -603,14 +674,14 @@ void local_server_endpoint_impl::connection::receive_cbk( } if (!message_is_empty) { - if (its_start + 6 < recv_buffer_size_ + its_iteration_gap) { + if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { its_command_size = VSOMEIP_BYTES_TO_LONG( - recv_buffer_[its_start + 6], - recv_buffer_[its_start + 5], - recv_buffer_[its_start + 4], - recv_buffer_[its_start + 3]); + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); - its_end = its_start + 6 + its_command_size; + its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; } else { its_end = its_start; } @@ -646,17 +717,22 @@ void local_server_endpoint_impl::connection::receive_cbk( || recv_buffer_[its_end+1] != 0x6d || recv_buffer_[its_end+2] != 0x37 || recv_buffer_[its_end+3] != 0x67) { - // command (1 Byte) + client id (2 Byte) + // command (1 Byte) + version (2 Byte) + client id (2 Byte) // + command size (4 Byte) + data itself + stop tag (4 byte) - // = 11 Bytes not covered in command size. - if (its_start - its_iteration_gap + its_command_size + 11 > recv_buffer_size_) { + // = 13 Bytes not covered in command size. + // If need to change the recv_buffer_, change the value of missing_capacity_ + // in this if/else, otherwise it is 0 + if (its_start - its_iteration_gap + its_command_size + + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE > recv_buffer_size_) { missing_capacity_ = std::uint32_t(its_start) - std::uint32_t(its_iteration_gap) - + its_command_size + 11 - std::uint32_t(recv_buffer_size_); - } else if (recv_buffer_size_ < 11) { + + its_command_size + std::uint32_t(protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) + - std::uint32_t(recv_buffer_size_); + } else if (recv_buffer_size_ < protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) { // to little data to read out the command size - // minimal amount of data needed to read out command size = 11 - missing_capacity_ = 11 - static_cast(recv_buffer_size_); + // minimal amount of data needed to read out command size = header + tag size + missing_capacity_ = static_cast( + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE - recv_buffer_size_); } else { std::stringstream local_msg; for (std::size_t i = its_iteration_gap; @@ -686,48 +762,57 @@ void local_server_endpoint_impl::connection::receive_cbk( its_end + 3 < recv_buffer_size_ + its_iteration_gap) { if (its_server->is_routing_endpoint_ - && recv_buffer_[its_start] == VSOMEIP_ASSIGN_CLIENT) { + && recv_buffer_[its_start] == byte_t(protocol::id_e::ASSIGN_CLIENT_ID)) { client_t its_client = its_server->assign_client( &recv_buffer_[its_start], uint32_t(its_end - its_start)); -#ifndef _WIN32 - if (security::get()->is_enabled()) { + + if (its_config && its_config->is_security_enabled()) { + // Add to known clients (loads new config if needed) + its_host->add_known_client(its_client, get_bound_client_host()); + if (!its_server->add_connection(its_client, shared_from_this())) { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() << " is rejecting new connection with client ID 0x" << its_client - << " uid/gid= " << std::dec << bound_uid_ << "/" << bound_gid_ + << " uid/gid= " << std::dec + << sec_client_.client.uds_client.user << "/" + << sec_client_.client.uds_client.group << " because of already existing connection using same client ID"; stop(); return; - } else if (!security::get()->check_credentials( - its_client, bound_uid_, bound_gid_)) { + } else if (!policy_manager_impl::get()->check_credentials( + its_client, &sec_client_)) { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() << " received client credentials from client 0x" << its_client << " which violates the security policy : uid/gid=" - << std::dec << bound_uid_ << "/" << bound_gid_; + << std::dec << sec_client_.client.uds_client.user << "/" + << sec_client_.client.uds_client.group; its_server->remove_connection(its_client); - utility::release_client_id(its_client); + utility::release_client_id(its_config->get_network(), + its_client); stop(); return; - } else { + } + else { set_bound_client(its_client); } - } else -#endif - { + } else { set_bound_client(its_client); + its_host->add_known_client(its_client, get_bound_client_host()); its_server->add_connection(its_client, shared_from_this()); } its_server->send_client_identifier(its_client); assigned_client_ = true; } else if (!its_server->is_routing_endpoint_ || assigned_client_) { -#ifndef _WIN32 - credentials_t its_credentials = std::make_pair(_uid, _gid); -#else - credentials_t its_credentials = std::make_pair(ANY_UID, ANY_GID); -#endif + + vsomeip_sec_client_t its_sec_client; + memset(&its_sec_client, 0, sizeof(its_sec_client)); + its_sec_client.client_type = VSOMEIP_CLIENT_UDS; + its_sec_client.client.uds_client.user = _uid; + its_sec_client.client.uds_client.group = _gid; + its_host->on_message(&recv_buffer_[its_start], uint32_t(its_end - its_start), its_server.get(), - boost::asio::ip::address(), bound_client_, its_credentials); + false, bound_client_, &its_sec_client); } else { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; @@ -771,28 +856,38 @@ void local_server_endpoint_impl::connection::receive_cbk( || is_error) { stop(); its_server->remove_connection(bound_client_); - security::get()->remove_client_to_uid_gid_mapping(bound_client_); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); } else if (_error != boost::asio::error::bad_descriptor) { start(); } } -void local_server_endpoint_impl::connection::set_bound_client(client_t _client) { +void local_uds_server_endpoint_impl::connection::set_bound_client(client_t _client) { bound_client_ = _client; } -client_t local_server_endpoint_impl::connection::get_bound_client() const { +client_t local_uds_server_endpoint_impl::connection::get_bound_client() const { return bound_client_; } -#ifndef _WIN32 -void local_server_endpoint_impl::connection::set_bound_uid_gid(uid_t _uid, gid_t _gid) { - bound_uid_ = _uid; - bound_gid_ = _gid; +void local_uds_server_endpoint_impl::connection::set_bound_client_host( + const std::string &_bound_client_host) { + + bound_client_host_ = _bound_client_host; +} + +std::string local_uds_server_endpoint_impl::connection::get_bound_client_host() const { + return bound_client_host_; } -#endif -void local_server_endpoint_impl::connection::calculate_shrink_count() { + +void local_uds_server_endpoint_impl::connection::set_bound_sec_client( + const vsomeip_sec_client_t &_sec_client) { + + sec_client_ = _sec_client; +} + +void local_uds_server_endpoint_impl::connection::calculate_shrink_count() { if (buffer_shrink_threshold_) { if (recv_buffer_.capacity() != recv_buffer_size_initial_) { if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) { @@ -804,47 +899,34 @@ void local_server_endpoint_impl::connection::calculate_shrink_count() { } } -const std::string local_server_endpoint_impl::connection::get_path_local() const { +std::string local_uds_server_endpoint_impl::connection::get_path_local() const { boost::system::error_code ec; std::string its_local_path; if (socket_.is_open()) { endpoint_type its_local_endpoint = socket_.local_endpoint(ec); if (!ec) { -#ifdef _WIN32 - its_local_path += its_local_endpoint.address().to_string(ec); - its_local_path += ":"; - its_local_path += std::to_string(its_local_endpoint.port()); -#else its_local_path += its_local_endpoint.path(); -#endif - } } return its_local_path; } -const std::string local_server_endpoint_impl::connection::get_path_remote() const { +std::string local_uds_server_endpoint_impl::connection::get_path_remote() const { boost::system::error_code ec; std::string its_remote_path; if (socket_.is_open()) { endpoint_type its_remote_endpoint = socket_.remote_endpoint(ec); if (!ec) { -#ifdef _WIN32 - its_remote_path += its_remote_endpoint.address().to_string(ec); - its_remote_path += ":"; - its_remote_path += std::to_string(its_remote_endpoint.port()); -#else its_remote_path += its_remote_endpoint.path(); -#endif } } return its_remote_path; } -void local_server_endpoint_impl::connection::handle_recv_buffer_exception( +void local_uds_server_endpoint_impl::connection::handle_recv_buffer_exception( const std::exception &_e) { std::stringstream its_message; - its_message <<"local_server_endpoint_impl::connection catched exception" + its_message <<"local_uds_server_endpoint_impl::connection catched exception" << _e.what() << " local: " << get_path_local() << " remote: " << get_path_remote() << " shutting down connection. Start of buffer: "; @@ -861,48 +943,40 @@ void local_server_endpoint_impl::connection::handle_recv_buffer_exception( VSOMEIP_ERROR << its_message.str(); recv_buffer_.clear(); if (socket_.is_open()) { -#ifndef _WIN32 if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) << "' (" << errno << ") " << get_path_local(); } -#endif boost::system::error_code its_error; socket_.shutdown(socket_.shutdown_both, its_error); socket_.close(its_error); } - std::shared_ptr its_server = server_.lock(); + std::shared_ptr its_server = server_.lock(); if (its_server) { its_server->remove_connection(bound_client_); } } std::size_t -local_server_endpoint_impl::connection::get_recv_buffer_capacity() const { +local_uds_server_endpoint_impl::connection::get_recv_buffer_capacity() const { return recv_buffer_.capacity(); } -void local_server_endpoint_impl::print_status() { +void local_uds_server_endpoint_impl::print_status() { std::lock_guard its_lock(mutex_); connections_t its_connections; { std::lock_guard its_lock(connections_mutex_); its_connections = connections_; } -#ifndef _WIN32 + std::string its_local_path(local_.path()); -#else - std::string its_local_path(""); -#endif + VSOMEIP_INFO << "status lse: " << its_local_path << " connections: " - << std::dec << its_connections.size() << " queues: " - << std::dec << queues_.size(); + << std::dec << its_connections.size() << " targets: " + << std::dec << targets_.size(); for (const auto &c : its_connections) { -#ifndef _WIN32 std::string its_remote_path; // TODO: construct the path -#else - std::string its_remote_path(""); -#endif std::size_t its_recv_size(0); { @@ -914,80 +988,80 @@ void local_server_endpoint_impl::print_status() { << " recv_buffer: " << std::dec << its_recv_size; } } -std::string local_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { -#ifdef _WIN32 - boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); -#else - (void)_queue_iterator; +std::string local_uds_server_endpoint_impl::get_remote_information( + const target_data_iterator_type _it) const { + + (void)_it; return "local"; -#endif } -std::string local_server_endpoint_impl::get_remote_information( +std::string local_uds_server_endpoint_impl::get_remote_information( const endpoint_type& _remote) const { -#ifdef _WIN32 - boost::system::error_code ec; - return _remote.address().to_string(ec) + ":" - + std::to_string(_remote.port()); -#else + (void)_remote; return "local"; -#endif } -bool local_server_endpoint_impl::is_reliable() const { +bool local_uds_server_endpoint_impl::is_reliable() const { return false; } -std::uint16_t local_server_endpoint_impl::get_local_port() const { +std::uint16_t local_uds_server_endpoint_impl::get_local_port() const { + return 0; } -void local_server_endpoint_impl::set_local_port(std::uint16_t _port) { - (void) _port; +void local_uds_server_endpoint_impl::set_local_port(std::uint16_t _port) { + + (void)_port; + // Intentionally left empty } -bool local_server_endpoint_impl::check_packetizer_space( - queue_iterator_type _queue_iterator, message_buffer_ptr_t* _packetizer, +bool local_uds_server_endpoint_impl::check_packetizer_space( + target_data_iterator_type _it, message_buffer_ptr_t* _packetizer, std::uint32_t _size) { + if ((*_packetizer)->size() + _size < (*_packetizer)->size()) { VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; return false; } if ((*_packetizer)->size() + _size > max_message_size_ && !(*_packetizer)->empty()) { - _queue_iterator->second.second.push_back(*_packetizer); - _queue_iterator->second.first += (*_packetizer)->size(); + _it->second.queue_.push_back(std::make_pair(*_packetizer, 0)); + _it->second.queue_size_ += (*_packetizer)->size(); *_packetizer = std::make_shared(); } return true; } void -local_server_endpoint_impl::send_client_identifier( +local_uds_server_endpoint_impl::send_client_identifier( const client_t &_client) { - byte_t its_command[] = { - VSOMEIP_ASSIGN_CLIENT_ACK, - 0x0, 0x0, // client - 0x2, 0x0, 0x0, 0x0, // size - 0x0, 0x0 // assigned client - }; - std::memcpy(its_command+7, &_client, sizeof(_client)); + protocol::assign_client_ack_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_assigned(_client); - send(its_command, sizeof(its_command)); -} + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": assign client ack command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + send(&its_buffer[0], static_cast(its_buffer.size())); +} -bool local_server_endpoint_impl::tp_segmentation_enabled( +bool local_uds_server_endpoint_impl::tp_segmentation_enabled( service_t _service, method_t _method) const { + (void)_service; (void)_method; return false; } - } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/netlink_connector.cpp b/implementation/endpoints/src/netlink_connector.cpp index ebd432dd4..be5a103be 100644 --- a/implementation/endpoints/src/netlink_connector.cpp +++ b/implementation/endpoints/src/netlink_connector.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include @@ -17,12 +17,6 @@ namespace vsomeip_v3 { -namespace { - const std::uint32_t ifa_request_sequence = 1; - const std::uint32_t ifi_request_sequence = 2; - const std::uint32_t rt_request_sequence = 3; -} - void netlink_connector::register_net_if_changes_handler(const net_if_changed_handler_t& _handler) { handler_ = _handler; } @@ -66,15 +60,14 @@ void netlink_connector::start() { RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_MROUTE), ec); - if (ec) { + if (ec && ec != boost::asio::error::address_in_use) { VSOMEIP_WARNING << "Error binding NETLINK socket: " << ec.message(); if (handler_) { handler_(true, "n/a", true); handler_(false, "n/a", true); } -#ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS + return; -#endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } send_ifa_request(); @@ -122,7 +115,7 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, auto its_if = net_if_flags_.find(static_cast(ifa->ifa_index)); if (its_if != net_if_flags_.end()) { if ((its_if->second & IFF_UP) && - (its_if->second & IFF_RUNNING)) { + (is_requiring_link_ ? (its_if->second & IFF_RUNNING) : true)) { if (handler_) { if_indextoname(ifa->ifa_index,ifname); handler_(true, ifname, true); @@ -148,7 +141,7 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, net_if_flags_[ifi->ifi_index] = ifi->ifi_flags; if (net_if_index_for_address_ == ifi->ifi_index) { if ((ifi->ifi_flags & IFF_UP) && - (ifi->ifi_flags & IFF_RUNNING)) { + (is_requiring_link_ ? (ifi->ifi_flags & IFF_RUNNING) : true)) { if (handler_) { if_indextoname(static_cast(ifi->ifi_index),ifname); handler_(true, ifname, true); @@ -187,32 +180,9 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, } case NLMSG_ERROR: { struct nlmsgerr *errmsg = (nlmsgerr *)NLMSG_DATA(nlh); - if (errmsg->error == 0) { - // Ack from netlink - break; - } - VSOMEIP_ERROR << "netlink_connector::receive_cbk received " - "error message: " << strerror(errmsg->error) - << " type " << std::dec << errmsg->msg.nlmsg_type + "error message: " << std::dec << nlh->nlmsg_type << " seq " << errmsg->msg.nlmsg_seq; - - std::string request_type{}; - if (errmsg->msg.nlmsg_type == RTM_GETADDR && errmsg->msg.nlmsg_seq == ifa_request_sequence) { - request_type = "address request"; - send_ifa_request(); - } else if (errmsg->msg.nlmsg_type == RTM_GETLINK && errmsg->msg.nlmsg_seq == ifi_request_sequence) { - request_type = "link request"; - send_ifi_request(); - } else if (errmsg->msg.nlmsg_type == RTM_GETROUTE && errmsg->msg.nlmsg_seq == rt_request_sequence) { - request_type = "route request"; - send_rt_request(); - } - - if (!request_type.empty()) { - VSOMEIP_INFO << "Retrying netlink " << request_type; - } - break; } case NLMSG_DONE: @@ -271,16 +241,16 @@ void netlink_connector::send_cbk(boost::system::error_code const &_error, std::s } void netlink_connector::send_ifa_request() { - typedef struct { + struct netlink_address_msg { struct nlmsghdr nlhdr; struct ifaddrmsg addrmsg; - } netlink_address_msg; + }; netlink_address_msg get_address_msg; memset(&get_address_msg, 0, sizeof(get_address_msg)); get_address_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); get_address_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; get_address_msg.nlhdr.nlmsg_type = RTM_GETADDR; - get_address_msg.nlhdr.nlmsg_seq = ifa_request_sequence; + get_address_msg.nlhdr.nlmsg_seq = 1; if (address_.is_v4()) { get_address_msg.addrmsg.ifa_family = AF_INET; } else { @@ -299,17 +269,17 @@ void netlink_connector::send_ifa_request() { } void netlink_connector::send_ifi_request() { - typedef struct { + struct netlink_link_msg { struct nlmsghdr nlhdr; struct ifinfomsg infomsg; - } netlink_link_msg; + }; netlink_link_msg get_link_msg; memset(&get_link_msg, 0, sizeof(get_link_msg)); get_link_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); get_link_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; get_link_msg.nlhdr.nlmsg_type = RTM_GETLINK; get_link_msg.infomsg.ifi_family = AF_UNSPEC; - get_link_msg.nlhdr.nlmsg_seq = ifi_request_sequence; + get_link_msg.nlhdr.nlmsg_seq = 2; { std::lock_guard its_lock(socket_mutex_); @@ -326,17 +296,17 @@ void netlink_connector::send_ifi_request() { } void netlink_connector::send_rt_request() { - typedef struct { + struct netlink_route_msg { struct nlmsghdr nlhdr; struct rtgenmsg routemsg; - } netlink_route_msg; + }; netlink_route_msg get_route_msg; memset(&get_route_msg, 0, sizeof(get_route_msg)); get_route_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); get_route_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; get_route_msg.nlhdr.nlmsg_type = RTM_GETROUTE; - get_route_msg.nlhdr.nlmsg_seq = rt_request_sequence; + get_route_msg.nlhdr.nlmsg_seq = 3; if (multicast_address_.is_v6()) { get_route_msg.routemsg.rtgen_family = AF_INET6; } else { @@ -470,5 +440,4 @@ bool netlink_connector::check_sd_multicast_route_match(struct rtmsg* _routemsg, } // namespace vsomeip_v3 -#endif // #ifndef _WIN32 - +#endif // __linux__ or ANDROID diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp index ddf6b2505..0d0653792 100644 --- a/implementation/endpoints/src/server_endpoint_impl.cpp +++ b/implementation/endpoints/src/server_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,8 +11,13 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 #include +#include +#else +#include +#include +#endif #include #include @@ -30,69 +35,73 @@ template server_endpoint_impl::server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, endpoint_type _local, - boost::asio::io_service &_io, std::uint32_t _max_message_size, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) : endpoint_impl(_endpoint_host, _routing_host, _local, _io, _max_message_size, _queue_limit, _configuration), sent_timer_(_io) { + is_sending_ = false; } template server_endpoint_impl::~server_endpoint_impl() { + } template void server_endpoint_impl::prepare_stop( - endpoint::prepare_stop_handler_t _handler, service_t _service) { + const endpoint::prepare_stop_handler_t &_handler, service_t _service) { + std::lock_guard its_lock(mutex_); bool queued_train(false); + std::vector its_erased; + boost::system::error_code ec; + if (_service == ANY_SERVICE) { // endpoint is shutting down completely endpoint_impl::sending_blocked_ = true; - boost::system::error_code ec; - for (auto const& train_iter : trains_) { - train_iter.second->departure_timer_->cancel(ec); - if (train_iter.second->buffer_->size() > 0) { - auto target_queue_iter = queues_.find(train_iter.first); - if (target_queue_iter != queues_.end()) { - auto& its_qpair = target_queue_iter->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); - queue_train(target_queue_iter, train_iter.second, - queue_size_zero_on_entry); - queued_train = true; - } + for (auto t = targets_.begin(); t != targets_.end(); t++) { + auto its_train (t->second.train_); + // cancel dispatch timer + t->second.dispatch_timer_->cancel(ec); + if (its_train->buffer_->size() > 0) { + const bool queue_size_zero_on_entry(t->second.queue_.empty()); + if (queue_train(t, its_train, queue_size_zero_on_entry)) + its_erased.push_back(t); + queued_train = true; } } } else { - for (auto const& train_iter : trains_) { - for (auto const& passenger_iter : train_iter.second->passengers_) { + for (auto t = targets_.begin(); t != targets_.end(); t++) { + auto its_train(t->second.train_); + for (auto const& passenger_iter : its_train->passengers_) { if (passenger_iter.first == _service) { - // cancel departure timer - boost::system::error_code ec; - train_iter.second->departure_timer_->cancel(ec); + // cancel dispatch timer + t->second.dispatch_timer_->cancel(ec); // queue train - auto target_queue_iter = queues_.find(train_iter.first); - if (target_queue_iter != queues_.end()) { - const auto& its_qpair = target_queue_iter->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); - queue_train(target_queue_iter, train_iter.second, - queue_size_zero_on_entry); - queued_train = true; - } + const bool queue_size_zero_on_entry(t->second.queue_.empty()); + // TODO: Queue all(!) trains here... + if (queue_train(t, its_train, queue_size_zero_on_entry)) + its_erased.push_back(t); + queued_train = true; break; } } } } + + for (const auto t : its_erased) + targets_.erase(t); + if (!queued_train) { if (_service == ANY_SERVICE) { - if (std::all_of(queues_.begin(), queues_.end(), - [&](const typename queue_type::value_type& q) - { return q.second.second.empty(); })) { + if (std::all_of(targets_.begin(), targets_.end(), + [&](const typename target_data_type::value_type &_t) + { return _t.second.queue_.empty(); })) { // nothing was queued and all queues are empty -> ensure cbk is called auto ptr = this->shared_from_this(); - endpoint_impl::service_.post([ptr, _handler, _service](){ + endpoint_impl::io_.post([ptr, _handler, _service](){ _handler(ptr, _service); }); } else { @@ -101,11 +110,11 @@ void server_endpoint_impl::prepare_stop( } else { // check if any of the queues contains a message of to be stopped service bool found_service_msg(false); - for (const auto& q : queues_) { - for (const auto& msg : q.second.second ) { + for (const auto &t : targets_) { + for (const auto &q : t.second.queue_) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*msg)[VSOMEIP_SERVICE_POS_MIN], - (*msg)[VSOMEIP_SERVICE_POS_MAX]); + (*q.first)[VSOMEIP_SERVICE_POS_MIN], + (*q.first)[VSOMEIP_SERVICE_POS_MAX]); if (its_service == _service) { found_service_msg = true; break; @@ -119,7 +128,7 @@ void server_endpoint_impl::prepare_stop( prepare_stop_handlers_[_service] = _handler; } else { // no messages of the to be stopped service are or have been queued auto ptr = this->shared_from_this(); - endpoint_impl::service_.post([ptr, _handler, _service](){ + endpoint_impl::io_.post([ptr, _handler, _service](){ _handler(ptr, _service); }); } @@ -170,7 +179,7 @@ templatebool server_endpoint_impl::send(const uint8 std::stringstream msg; msg << "sei::send "; for (uint32_t i = 0; i < _size; i++) - msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; VSOMEIP_INFO << msg.str(); #endif endpoint_type its_target; @@ -185,45 +194,38 @@ templatebool server_endpoint_impl::send(const uint8 const service_t its_service = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); - requests_mutex_.lock(); - auto found_client = requests_.find(its_client); - if (found_client != requests_.end()) { - auto its_request = std::make_tuple(its_service, its_method, its_session); - auto found_request = found_client->second.find(its_request); - if (found_request != found_client->second.end()) { - its_target = found_request->second; + clients_mutex_.lock(); + auto found_client = clients_.find(its_client); + if (found_client != clients_.end()) { + auto found_session = found_client->second.find(its_session); + if (found_session != found_client->second.end()) { + its_target = found_session->second; is_valid_target = true; - found_client->second.erase(found_request); + found_client->second.erase(its_session); } else { - VSOMEIP_WARNING << "server_endpoint::send: request [" - << std::hex << std::setw(4) << std::setfill('0') - << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') - << its_method << "/" - << std::hex << std::setw(4) << std::setfill('0') - << its_client << "." - << std::hex << std::setw(4) << std::setfill('0') - << its_session - << "] could not be found."; + VSOMEIP_WARNING << "server_endpoint::send: session_id 0x" + << std::hex << its_session + << " not found for client 0x" << its_client; + const method_t its_method = + VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], + _data[VSOMEIP_METHOD_POS_MAX]); if (its_service == VSOMEIP_SD_SERVICE && its_method == VSOMEIP_SD_METHOD) { VSOMEIP_ERROR << "Clearing clients map as a request was " "received on SD port"; - requests_.clear(); + clients_.clear(); is_valid_target = get_default_target(its_service, its_target); } } } else { is_valid_target = get_default_target(its_service, its_target); } - requests_mutex_.unlock(); + clients_mutex_.unlock(); if (is_valid_target) { is_valid_target = send_intern(its_target, _data, _size); @@ -276,9 +278,11 @@ bool server_endpoint_impl::send_intern( } } - const queue_iterator_type target_queue_iterator = find_or_create_queue_unlocked(_target); + const auto its_target_iterator = find_or_create_target_unlocked(_target); + auto &its_data(its_target_iterator->second); bool must_depart(false); + auto its_now(std::chrono::steady_clock::now()); #if 0 std::stringstream msg; @@ -287,15 +291,12 @@ bool server_endpoint_impl::send_intern( msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; VSOMEIP_DEBUG << msg.str(); #endif - // STEP 1: determine the correct train - std::shared_ptr target_train = find_or_create_train_unlocked(_target); - - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); - if (!check_queue_limit(_data, _size, target_queue_iterator->second.first)) { + // STEP 1: Check queue limit + if (!check_queue_limit(_data, _size, its_data.queue_size_)) { return false; } - // STEP 2: Determine elapsed time and update the departure time and cancel the timer - target_train->update_departure_time_and_stop_departure(); + // STEP 2: Cancel the dispatch timer + cancel_dispatch_timer(its_target_iterator); // STEP 3: Get configured timings const service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -310,38 +311,38 @@ bool server_endpoint_impl::send_intern( } // STEP 4: Check if the passenger enters an empty train - const std::pair its_identifier = std::make_pair( - its_service, its_method); - if (target_train->passengers_.empty()) { - target_train->departure_ = its_retention; + const std::pair its_identifier + = std::make_pair(its_service, its_method); + if (its_data.train_->passengers_.empty()) { + its_data.train_->departure_ = its_now + its_retention; } else { - if (target_train->passengers_.end() - != target_train->passengers_.find(its_identifier)) { + if (its_data.train_->passengers_.end() + != its_data.train_->passengers_.find(its_identifier)) { must_depart = true; } else { // STEP 5: Check whether the current message fits into the current train - if (target_train->buffer_->size() + _size > endpoint_impl::max_message_size_) { + if (its_data.train_->buffer_->size() + _size > endpoint_impl::max_message_size_) { must_depart = true; } else { // STEP 6: Check debouncing time - if (its_debouncing > target_train->minimal_max_retention_time_) { + if (its_debouncing > its_data.train_->minimal_max_retention_time_) { // train's latest departure would already undershot new // passenger's debounce time must_depart = true; } else { - if (its_debouncing > target_train->departure_) { + if (its_now + its_debouncing > its_data.train_->departure_) { // train departs earlier as the new passenger's debounce // time allows must_depart = true; } else { // STEP 7: Check maximum retention time - if (its_retention < target_train->minimal_debounce_time_) { + if (its_retention < its_data.train_->minimal_debounce_time_) { // train's earliest departure would already exceed // the new passenger's retention time. must_depart = true; } else { - if (its_retention < target_train->departure_) { - target_train->departure_ = its_retention; + if (its_now + its_retention < its_data.train_->departure_) { + its_data.train_->departure_ = its_now + its_retention; } } } @@ -354,52 +355,42 @@ bool server_endpoint_impl::send_intern( if (must_depart) { // STEP 8.1: check if debounce time would be undershot here if the train // departs. Block sending until train is allowed to depart. - wait_until_debounce_time_reached(target_train); - queue_train(target_queue_iterator, target_train, - queue_size_zero_on_entry); - target_train->departure_ = its_retention; + schedule_train(its_data); + + its_data.train_ = std::make_shared(); + its_data.train_->departure_ = its_now + its_retention; } // STEP 9: insert current message buffer - target_train->buffer_->insert(target_train->buffer_->end(), _data, _data + _size); - target_train->passengers_.insert(its_identifier); + its_data.train_->buffer_->insert(its_data.train_->buffer_->end(), _data, _data + _size); + its_data.train_->passengers_.insert(its_identifier); // STEP 9.1: update the trains minimal debounce time if necessary - if (its_debouncing < target_train->minimal_debounce_time_) { - target_train->minimal_debounce_time_ = its_debouncing; + if (its_debouncing < its_data.train_->minimal_debounce_time_) { + its_data.train_->minimal_debounce_time_ = its_debouncing; } // STEP 9.2: update the trains minimal maximum retention time if necessary - if (its_retention < target_train->minimal_max_retention_time_) { - target_train->minimal_max_retention_time_ = its_retention; + if (its_retention < its_data.train_->minimal_max_retention_time_) { + its_data.train_->minimal_max_retention_time_ = its_retention; } // STEP 10: restart timer with current departure time -#ifndef _WIN32 - target_train->departure_timer_->expires_from_now(target_train->departure_); -#else - target_train->departure_timer_->expires_from_now( - std::chrono::duration_cast< - std::chrono::steady_clock::duration>(target_train->departure_)); -#endif - target_train->departure_timer_->async_wait( - std::bind(&server_endpoint_impl::flush_cbk, - this->shared_from_this(), _target, - target_train, std::placeholders::_1)); + start_dispatch_timer(its_target_iterator, its_now); return (true); } template void server_endpoint_impl::send_segments( - const tp::tp_split_messages_t &_segments, const endpoint_type &_target) { + const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time, + const endpoint_type &_target) { if (_segments.size() == 0) return; - const queue_iterator_type target_queue_iterator = find_or_create_queue_unlocked(_target); - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); + const auto its_target_iterator = find_or_create_target_unlocked(_target); + auto &its_data = its_target_iterator->second; - std::shared_ptr target_train = find_or_create_train_unlocked(_target); - target_train->update_departure_time_and_stop_departure(); + auto its_now(std::chrono::steady_clock::now()); const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], (*(_segments[0]))[VSOMEIP_SERVICE_POS_MAX]); @@ -412,47 +403,63 @@ void server_endpoint_impl::send_segments( &its_debouncing, &its_retention); } // update the trains minimal debounce time if necessary - if (its_debouncing < target_train->minimal_debounce_time_) { - target_train->minimal_debounce_time_ = its_debouncing; + if (its_debouncing < its_data.train_->minimal_debounce_time_) { + its_data.train_->minimal_debounce_time_ = its_debouncing; } // update the trains minimal maximum retention time if necessary - if (its_retention < target_train->minimal_max_retention_time_) { - target_train->minimal_max_retention_time_ = its_retention; + if (its_retention < its_data.train_->minimal_max_retention_time_) { + its_data.train_->minimal_max_retention_time_ = its_retention; } // We only need to respect the debouncing. There is no need to wait for further // messages as we will send several now anyway. - if (!target_train->passengers_.empty()) { - wait_until_debounce_time_reached(target_train); - queue_train(target_queue_iterator, target_train, queue_size_zero_on_entry); + if (!its_data.train_->passengers_.empty()) { + schedule_train(its_data); + its_data.train_->departure_ = its_now + its_retention; } - const bool queue_size_still_zero(target_queue_iterator->second.second.empty()); + const bool queue_size_still_zero(its_data.queue_.empty()); for (const auto &s : _segments) { - target_queue_iterator->second.second.emplace_back(s); - target_queue_iterator->second.first += s->size(); + its_data.queue_.emplace_back(std::make_pair(s, _separation_time)); + its_data.queue_size_ += s->size(); } - if (queue_size_still_zero && !target_queue_iterator->second.second.empty()) { // no writing in progress + + if (queue_size_still_zero && !its_data.queue_.empty()) { // no writing in progress // respect minimal debounce time - wait_until_debounce_time_reached(target_train); + schedule_train(its_data); // ignore retention time and send immediately as the train is full anyway - send_queued(target_queue_iterator); + (void)send_queued(its_target_iterator); } - target_train->last_departure_ = std::chrono::steady_clock::now(); } template -void server_endpoint_impl::wait_until_debounce_time_reached( - const std::shared_ptr& _train) const { - const std::chrono::nanoseconds time_since_last_departure = - std::chrono::duration_cast( - std::chrono::steady_clock::now() - _train->last_departure_); - - if (time_since_last_departure < _train->minimal_debounce_time_) { - std::this_thread::sleep_for( - _train->minimal_debounce_time_ - time_since_last_departure); +typename server_endpoint_impl::target_data_iterator_type +server_endpoint_impl::find_or_create_target_unlocked(endpoint_type _target) { + + auto its_iterator = targets_.find(_target); + if (its_iterator == targets_.end()) { + + auto its_result = targets_.emplace( + std::make_pair(_target, endpoint_data_type(this->io_))); + its_iterator = its_result.first; } + + return (its_iterator); } +template +void server_endpoint_impl::schedule_train(endpoint_data_type &_data) { + + if (_data.has_last_departure_) { + if (_data.last_departure_ + _data.train_->minimal_debounce_time_ + > _data.train_->departure_) { + _data.train_->departure_ = _data.last_departure_ + + _data.train_->minimal_debounce_time_; + } + } + + _data.dispatched_trains_[_data.train_->departure_] + .push_back(_data.train_); +} template typename endpoint_impl::cms_ret_e server_endpoint_impl::check_message_size( @@ -469,11 +476,21 @@ typename endpoint_impl::cms_ret_e server_endpoint_impl::chec _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); if (tp_segmentation_enabled(its_service, its_method)) { - send_segments(tp::tp::tp_split_message(_data, _size), _target); - return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + instance_t its_instance = this->get_instance(its_service); + if (its_instance != 0xFFFF) { + std::uint16_t its_max_segment_length; + std::uint32_t its_separation_time; + + this->configuration_->get_tp_configuration( + its_service, its_instance, its_method, false, + its_max_segment_length, its_separation_time); + send_segments(tp::tp::tp_split_message(_data, _size, + its_max_segment_length), its_separation_time, _target); + return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + } } } - VSOMEIP_ERROR << "sei::send_intern: Dropping too big message (" << _size + VSOMEIP_ERROR << "sei::send_intern: Dropping to big message (" << _size << " Bytes). Maximum allowed message size is: " << endpoint_impl::max_message_size_ << " Bytes."; ret = endpoint_impl::cms_ret_e::MSG_TOO_BIG; @@ -523,72 +540,67 @@ bool server_endpoint_impl::check_queue_limit(const uint8_t *_data, std } template -void server_endpoint_impl::queue_train( - const queue_iterator_type _queue_iterator, - const std::shared_ptr& _train, - bool _queue_size_zero_on_entry) { - _queue_iterator->second.second.emplace_back(_train->buffer_); - _queue_iterator->second.first += _train->buffer_->size(); - _train->last_departure_ = std::chrono::steady_clock::now(); - _train->passengers_.clear(); - _train->buffer_ = std::make_shared(); - _train->minimal_debounce_time_ = std::chrono::nanoseconds::max(); - _train->minimal_max_retention_time_ = std::chrono::nanoseconds::max(); - if (_queue_size_zero_on_entry && !_queue_iterator->second.second.empty()) { // no writing in progress - send_queued(_queue_iterator); - } -} +bool server_endpoint_impl::queue_train( + target_data_iterator_type _it, const std::shared_ptr &_train, + bool _queue_size_zero_on_entry) { -template -typename server_endpoint_impl::queue_iterator_type -server_endpoint_impl::find_or_create_queue_unlocked(const endpoint_type& _target) { - queue_iterator_type target_queue_iterator = queues_.find(_target); - if (target_queue_iterator == queues_.end()) { - target_queue_iterator = queues_.insert(queues_.begin(), - std::make_pair( - _target, - std::make_pair(std::size_t(0), - std::deque()) - )); - } - return target_queue_iterator; -} + bool must_erase(false); -template -std::shared_ptr server_endpoint_impl::find_or_create_train_unlocked( - const endpoint_type& _target) { - auto train_iter = trains_.find(_target); - if (train_iter == trains_.end()) { - train_iter = trains_.insert(trains_.begin(), - std::make_pair(_target, std::make_shared(this->service_))); + auto &its_data = _it->second; + its_data.queue_.push_back(std::make_pair(_train->buffer_, 0)); + its_data.queue_size_ += _train->buffer_->size(); + + if (_queue_size_zero_on_entry && !its_data.queue_.empty()) { // no writing in progress + must_erase = send_queued(_it); } - return train_iter->second; + + return must_erase; } template -bool server_endpoint_impl::flush( - endpoint_type _target, - const std::shared_ptr& _train) { +bool server_endpoint_impl::flush(target_data_iterator_type _it) { + + bool has_queued(true); + bool is_current_train(true); + auto &its_data = _it->second; + std::lock_guard its_lock(mutex_); - bool is_flushed = false; - if (!_train->buffer_->empty()) { - const queue_iterator_type target_queue_iterator = queues_.find(_target); - if (target_queue_iterator != queues_.end()) { - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); - queue_train(target_queue_iterator, _train, queue_size_zero_on_entry); - is_flushed = true; - } else { - std::stringstream ss; - ss << "sei::flush couldn't find target queue, won't queue train to: " - << get_remote_information(_target) << " passengers: "; - for (const auto& p : _train->passengers_) { - ss << "[" << std::hex << std::setw(4) << std::setfill('0') - << p.first << ":" << p.second << "] "; + + auto its_train(its_data.train_); + if (!its_data.dispatched_trains_.empty()) { + + auto its_dispatched = its_data.dispatched_trains_.begin(); + if (its_dispatched->first <= its_train->departure_) { + + is_current_train = false; + its_train = its_dispatched->second.front(); + its_dispatched->second.pop_front(); + if (its_dispatched->second.empty()) { + + its_data.dispatched_trains_.erase(its_dispatched); } - VSOMEIP_WARNING << ss.str(); } } - return is_flushed; + + if (!its_train->buffer_->empty()) { + + queue_train(_it, its_train, its_data.queue_.empty()); + + // Reset current train if necessary + if (is_current_train) { + its_train->reset(); + } + } else { + has_queued = false; + } + + if (!is_current_train || !its_data.dispatched_trains_.empty()) { + + auto its_now(std::chrono::steady_clock::now()); + start_dispatch_timer(_it, its_now); + } + + return (has_queued); } template @@ -599,7 +611,7 @@ void server_endpoint_impl::connect_cbk( template void server_endpoint_impl::send_cbk( - const queue_iterator_type _queue_iterator, + const target_data_iterator_type _it, boost::system::error_code const &_error, std::size_t _bytes) { (void)_bytes; @@ -623,11 +635,11 @@ void server_endpoint_impl::send_cbk( ++stp_hndlr_iter; continue; } - for (const auto& q : queues_) { - for (const auto& msg : q.second.second ) { + for (const auto& t : targets_) { + for (const auto& e : t.second.queue_ ) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*msg)[VSOMEIP_SERVICE_POS_MIN], - (*msg)[VSOMEIP_SERVICE_POS_MAX]); + (*e.first)[VSOMEIP_SERVICE_POS_MIN], + (*e.first)[VSOMEIP_SERVICE_POS_MAX]); if (its_service == its_stopped_service) { found_service_msg = true; break; @@ -639,14 +651,13 @@ void server_endpoint_impl::send_cbk( } if (found_service_msg) { ++stp_hndlr_iter; - found_service_msg = false; } else { // all messages of the to be stopped service have been sent auto handler = stp_hndlr_iter->second; auto ptr = this->shared_from_this(); - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) endpoint_impl:: - #endif - service_.post([ptr, handler, its_stopped_service](){ +#endif + io_.post([ptr, handler, its_stopped_service](){ handler(ptr, its_stopped_service); }); stp_hndlr_iter = prepare_stop_handlers_.erase(stp_hndlr_iter); @@ -660,22 +671,18 @@ void server_endpoint_impl::send_cbk( // prepare_stop_handlers have been queued ensure to call them as well check_if_all_msgs_for_stopped_service_are_sent(); } - if (std::all_of(queues_.begin(), queues_.end(), [&] - #ifndef _WIN32 - (const typename queue_type::value_type& q) - #else - (const std::pair>>& q) - #endif - { return q.second.second.empty(); })) { + if (std::all_of(targets_.begin(), targets_.end(), + [&](const typename target_data_type::value_type &_t) + { return _t.second.queue_.empty(); })) { // all outstanding response have been sent. auto found_cbk = prepare_stop_handlers_.find(ANY_SERVICE); if (found_cbk != prepare_stop_handlers_.end()) { auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) endpoint_impl:: - #endif - service_.post([ptr, handler](){ +#endif + io_.post([ptr, handler](){ handler(ptr, ANY_SERVICE); }); prepare_stop_handlers_.erase(found_cbk); @@ -683,27 +690,30 @@ void server_endpoint_impl::send_cbk( } }; - auto& its_qpair = _queue_iterator->second; + auto& its_data = _it->second; if (!_error) { - its_qpair.first -= its_qpair.second.front()->size(); - its_qpair.second.pop_front(); + its_data.queue_size_ -= its_data.queue_.front().first->size(); + its_data.queue_.pop_front(); + + update_last_departure(its_data); if (!prepare_stop_handlers_.empty() && !endpoint_impl::sending_blocked_) { // only one service instance is stopped check_if_all_msgs_for_stopped_service_are_sent(); } - if (its_qpair.second.size() > 0) { - send_queued(_queue_iterator); + if (!its_data.queue_.empty()) { + (void)send_queued(_it); } else if (!prepare_stop_handlers_.empty() && endpoint_impl::sending_blocked_) { // endpoint is shutting down completely - queues_.erase(_queue_iterator); + cancel_dispatch_timer(_it); + targets_.erase(_it); check_if_all_queues_are_empty(); } } else { message_buffer_ptr_t its_buffer; - if (_queue_iterator->second.second.size()) { - its_buffer = _queue_iterator->second.second.front(); + if (its_data.queue_.size()) { + its_buffer = its_data.queue_.front().first; } service_t its_service(0); method_t its_method(0); @@ -727,14 +737,15 @@ void server_endpoint_impl::send_cbk( // delete remaining outstanding responses VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " - << get_remote_information(_queue_iterator) << " " - << std::dec << _queue_iterator->second.second.size() << " " - << std::dec << _queue_iterator->second.first << " (" + << get_remote_information(_it) << " " + << std::dec << its_data.queue_.size() << " " + << std::dec << its_data.queue_size_ << " (" << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_method << "." << std::hex << std::setw(4) << std::setfill('0') << its_session << "]"; - queues_.erase(_queue_iterator); + cancel_dispatch_timer(_it); + targets_.erase(_it); if (!prepare_stop_handlers_.empty()) { if (endpoint_impl::sending_blocked_) { // endpoint is shutting down completely, ensure to call @@ -751,32 +762,92 @@ void server_endpoint_impl::send_cbk( template void server_endpoint_impl::flush_cbk( - endpoint_type _target, - const std::shared_ptr& _train, const boost::system::error_code &_error_code) { + target_data_iterator_type _it, + const boost::system::error_code &_error_code) { + if (!_error_code) { - (void) flush(_target, _train); + + (void) flush(_it); } } template size_t server_endpoint_impl::get_queue_size() const { size_t its_queue_size(0); - { std::lock_guard its_lock(mutex_); - for (const auto &q : queues_) { - its_queue_size += q.second.second.size(); + for (const auto &t : targets_) { + its_queue_size += t.second.queue_size_; } } + return (its_queue_size); +} + +template +void server_endpoint_impl::start_dispatch_timer( + target_data_iterator_type _it, + const std::chrono::steady_clock::time_point &_now) { + + auto &its_data = _it->second; + std::shared_ptr its_train(its_data.train_); + + if (!its_data.dispatched_trains_.empty()) { + + auto its_dispatched = its_data.dispatched_trains_.begin(); + if (its_dispatched->first < its_train->departure_) { - return its_queue_size; + its_train = its_dispatched->second.front(); + } + } + + std::chrono::nanoseconds its_offset; + if (its_train->departure_ > _now) { + + its_offset = std::chrono::duration_cast( + its_train->departure_ - _now); + } else { // already departure time + + its_offset = std::chrono::nanoseconds::zero(); + } + +#if defined(__linux__) || defined(ANDROID) + its_data.dispatch_timer_->expires_from_now(its_offset); +#else + its_data.dispatch_timer_->expires_from_now( + std::chrono::duration_cast< + std::chrono::steady_clock::duration>(its_offset)); +#endif + its_data.dispatch_timer_->async_wait( + std::bind(&server_endpoint_impl::flush_cbk, + this->shared_from_this(), _it, std::placeholders::_1)); +} + +template +void server_endpoint_impl::cancel_dispatch_timer( + target_data_iterator_type _it) { + + boost::system::error_code ec; + _it->second.dispatch_timer_->cancel(ec); +} + +template +void server_endpoint_impl::update_last_departure( + endpoint_data_type &_data) { + + _data.last_departure_ = std::chrono::steady_clock::now(); + _data.has_last_departure_ = true; } // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) +#if VSOMEIP_BOOST_VERSION < 106600 template class server_endpoint_impl; +template class server_endpoint_impl; +#else +template class server_endpoint_impl; +template class server_endpoint_impl; +#endif #endif template class server_endpoint_impl; -template class server_endpoint_impl; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index f88d2a2b9..588d252c3 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,7 +26,7 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, @@ -78,7 +78,7 @@ void tcp_client_endpoint_impl::restart(bool _force) { if (!_force && self->state_ == cei_state_e::CONNECTING) { std::chrono::steady_clock::time_point its_current = std::chrono::steady_clock::now(); - long its_connect_duration = std::chrono::duration_cast( + std::int64_t its_connect_duration = std::chrono::duration_cast( its_current - self->connect_timepoint_).count(); if (self->aborted_restart_count_ < self->tcp_restart_aborts_max_ && its_connect_duration < self->tcp_connect_time_max_) { @@ -102,26 +102,26 @@ void tcp_client_endpoint_impl::restart(bool _force) { self->reconnect_counter_ = 0; { std::lock_guard its_lock(self->mutex_); - for (const auto&m : self->queue_) { + for (const auto &q : self->queue_) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_SERVICE_POS_MIN], - (*m)[VSOMEIP_SERVICE_POS_MAX]); + (*q.first)[VSOMEIP_SERVICE_POS_MIN], + (*q.first)[VSOMEIP_SERVICE_POS_MAX]); const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_METHOD_POS_MIN], - (*m)[VSOMEIP_METHOD_POS_MAX]); + (*q.first)[VSOMEIP_METHOD_POS_MIN], + (*q.first)[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_CLIENT_POS_MIN], - (*m)[VSOMEIP_CLIENT_POS_MAX]); + (*q.first)[VSOMEIP_CLIENT_POS_MIN], + (*q.first)[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_SESSION_POS_MIN], - (*m)[VSOMEIP_SESSION_POS_MAX]); + (*q.first)[VSOMEIP_SESSION_POS_MIN], + (*q.first)[VSOMEIP_SESSION_POS_MAX]); VSOMEIP_WARNING << "tce::restart: dropping message: " << "remote:" << self->get_address_port_remote() << " (" << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_method << "." << std::hex << std::setw(4) << std::setfill('0') << its_session << "]" - << " size: " << std::dec << m->size(); + << " size: " << std::dec << q.first->size(); } self->queue_.clear(); self->queue_size_ = 0; @@ -136,6 +136,7 @@ void tcp_client_endpoint_impl::restart(bool _force) { } void tcp_client_endpoint_impl::connect() { + start_connecting_timer(); std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); @@ -172,7 +173,7 @@ void tcp_client_endpoint_impl::connect() { << " remote:" << get_address_port_remote(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -191,14 +192,13 @@ void tcp_client_endpoint_impl::connect() { if(its_bind_error) { VSOMEIP_WARNING << "tcp_client_endpoint::connect: " "Error binding socket: " << its_bind_error.message() - << " local: " << local_.address().to_string() - << ":" << std::dec << local_.port() + << " local: " << get_address_port_local() << " remote:" << get_address_port_remote(); std::shared_ptr its_host = endpoint_host_.lock(); if (its_host) { // set new client port depending on service / instance / remote port - if (!its_host->on_bind_error(shared_from_this(), remote_port_)) { + if (!its_host->on_bind_error(shared_from_this(), remote_address_, remote_port_)) { VSOMEIP_WARNING << "tcp_client_endpoint::connect: " "Failed to set new local port for tce: " << " local: " << local_.address().to_string() @@ -220,15 +220,12 @@ void tcp_client_endpoint_impl::connect() { } catch (const std::exception &e) { VSOMEIP_ERROR << "tcp_client_endpoint_impl::connect: " << e.what() - << " local: " << local_.address().to_string() - << ":" << std::dec << local_.port() + << " local: " << get_address_port_local() << " remote:" << get_address_port_remote(); } return; } - return; } - state_ = cei_state_e::CONNECTING; connect_timepoint_ = std::chrono::steady_clock::now(); aborted_restart_count_ = 0; @@ -316,26 +313,26 @@ void tcp_client_endpoint_impl::receive(message_buffer_ptr_t _recv_buffer, } } -void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { +void tcp_client_endpoint_impl::send_queued(std::pair &_entry) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_SERVICE_POS_MIN], - (*_buffer)[VSOMEIP_SERVICE_POS_MAX]); + (*_entry.first)[VSOMEIP_SERVICE_POS_MIN], + (*_entry.first)[VSOMEIP_SERVICE_POS_MAX]); const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_METHOD_POS_MIN], - (*_buffer)[VSOMEIP_METHOD_POS_MAX]); + (*_entry.first)[VSOMEIP_METHOD_POS_MIN], + (*_entry.first)[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_CLIENT_POS_MIN], - (*_buffer)[VSOMEIP_CLIENT_POS_MAX]); + (*_entry.first)[VSOMEIP_CLIENT_POS_MIN], + (*_entry.first)[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_SESSION_POS_MIN], - (*_buffer)[VSOMEIP_SESSION_POS_MAX]); + (*_entry.first)[VSOMEIP_SESSION_POS_MIN], + (*_entry.first)[VSOMEIP_SESSION_POS_MAX]); if (has_enabled_magic_cookies_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); if (std::chrono::duration_cast( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { - send_magic_cookie(_buffer); + send_magic_cookie(_entry.first); last_cookie_sent_ = now; } } @@ -347,7 +344,7 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { << std::dec << remote_.port() << ">::sq: "; for (std::size_t i = 0; i < _buffer->size(); i++) msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*_buffer)[i] << " "; + << (int)(*_entry.first)[i] << " "; VSOMEIP_INFO << msg.str(); #endif { @@ -359,13 +356,13 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { } boost::asio::async_write( *socket_, - boost::asio::buffer(*_buffer), + boost::asio::buffer(*_entry.first), std::bind( &tcp_client_endpoint_impl::write_completion_condition, std::static_pointer_cast(shared_from_this()), std::placeholders::_1, std::placeholders::_2, - _buffer->size(), + _entry.first->size(), its_service, its_method, its_client, its_session, std::chrono::steady_clock::now()), strand_.wrap( @@ -374,7 +371,7 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { shared_from_this(), std::placeholders::_1, std::placeholders::_2, - _buffer + _entry.first )) ); } @@ -510,7 +507,7 @@ void tcp_client_endpoint_impl::receive_cbk( if (its_host) { std::uint32_t its_missing_capacity(0); if (!_error && 0 < _bytes) { - if (_recv_buffer_size + _bytes < _recv_buffer_size) { + if (_recv_buffer_size + _bytes > _recv_buffer->size()) { VSOMEIP_ERROR << "receive buffer overflow in tcp client endpoint ~> abort!"; return; } @@ -548,9 +545,9 @@ void tcp_client_endpoint_impl::receive_cbk( if (!has_enabled_magic_cookies_) { its_host->on_message(&(*_recv_buffer)[its_iteration_gap], current_message_size, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else { @@ -558,9 +555,9 @@ void tcp_client_endpoint_impl::receive_cbk( if (!is_magic_cookie(_recv_buffer, its_iteration_gap)) { its_host->on_message(&(*_recv_buffer)[its_iteration_gap], current_message_size, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } @@ -597,11 +594,12 @@ void tcp_client_endpoint_impl::receive_cbk( << " remote: " << get_address_port_remote(); // ensure to send back a message w/ wrong protocol version its_lock.unlock(); + its_host->on_message(&(*_recv_buffer)[its_iteration_gap], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); its_lock.lock(); @@ -761,8 +759,7 @@ void tcp_client_endpoint_impl::calculate_shrink_count(const message_buffer_ptr_t } -const std::string tcp_client_endpoint_impl::get_address_port_remote() const { - boost::system::error_code ec; +std::string tcp_client_endpoint_impl::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::asio::ip::address its_address; @@ -774,7 +771,7 @@ const std::string tcp_client_endpoint_impl::get_address_port_remote() const { return its_address_port; } -const std::string tcp_client_endpoint_impl::get_address_port_local() const { +std::string tcp_client_endpoint_impl::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -793,7 +790,6 @@ void tcp_client_endpoint_impl::handle_recv_buffer_exception( const std::exception &_e, const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size) { - boost::system::error_code ec; std::stringstream its_message; its_message <<"tcp_client_endpoint_impl::connection catched exception" @@ -877,13 +873,16 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) { + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { auto self = std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()); strand_.dispatch( - [self, its_buffer]() { self->send_queued(its_buffer);} + [self, &its_entry]() { self->send_queued(its_entry);} ); } } diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 37db3f50f..f23e9bea8 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,7 +26,7 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, _configuration->get_max_message_size_reliable(_local.address().to_string(), _local.port()), @@ -41,11 +41,16 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( boost::system::error_code ec; acceptor_.open(_local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": open failed (" << ec.message() << ")"; + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -57,9 +62,14 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( #endif acceptor_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": listen failed (" << ec.message() << ")"; } tcp_server_endpoint_impl::~tcp_server_endpoint_impl() { @@ -76,7 +86,7 @@ void tcp_server_endpoint_impl::start() { std::dynamic_pointer_cast( shared_from_this()), max_message_size_, buffer_shrink_threshold_, has_enabled_magic_cookies_, - service_, send_timeout_); + io_, send_timeout_); { std::unique_lock its_socket_lock(new_connection->get_socket_lock()); @@ -121,44 +131,47 @@ bool tcp_server_endpoint_impl::send_error( bool ret(false); std::lock_guard its_lock(mutex_); const endpoint_type its_target(_target->get_address(), _target->get_port()); - const queue_iterator_type target_queue_iterator(find_or_create_queue_unlocked(its_target)); - auto& its_qpair = target_queue_iterator->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); + const auto its_target_iterator(find_or_create_target_unlocked(its_target)); + auto &its_data = its_target_iterator->second; + const bool queue_size_zero_on_entry(its_data.queue_.empty()); if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_qpair.first)) { - its_qpair.second.emplace_back( - std::make_shared(_data, _data + _size)); - its_qpair.first += _size; + check_queue_limit(_data, _size, its_data.queue_size_)) { + its_data.queue_.emplace_back( + std::make_pair(std::make_shared(_data, _data + _size), 0)); + its_data.queue_size_ += _size; if (queue_size_zero_on_entry) { // no writing in progress - send_queued(target_queue_iterator); + send_queued(its_target_iterator); } ret = true; } return ret; } -void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iterator) { +bool tcp_server_endpoint_impl::send_queued(const target_data_iterator_type _it) { + + bool must_erase(false); connection::ptr its_connection; { std::lock_guard its_lock(connections_mutex_); - auto connection_iterator = connections_.find(_queue_iterator->first); + auto connection_iterator = connections_.find(_it->first); if (connection_iterator != connections_.end()) { its_connection = connection_iterator->second; } else { VSOMEIP_INFO << "Didn't find connection: " - << _queue_iterator->first.address().to_string() << ":" << std::dec - << static_cast(_queue_iterator->first.port()) + << _it->first.address().to_string() << ":" << std::dec + << static_cast(_it->first.port()) << " dropping outstanding messages (" << std::dec - << _queue_iterator->second.second.size() << ")."; + << _it->second.queue_.size() << ")."; - if (_queue_iterator->second.second.size()) { + if (_it->second.queue_.size()) { std::set its_services; // check all outstanding messages of this connection // whether stop handlers need to be called - for (const auto &its_buffer : _queue_iterator->second.second) { + for (const auto &its_q : _it->second.queue_) { + auto its_buffer(its_q.first); if (its_buffer && its_buffer->size() > VSOMEIP_SESSION_POS_MAX) { service_t its_service = VSOMEIP_BYTES_TO_WORD( (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], @@ -176,7 +189,7 @@ void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iter << its_service; auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - service_.post([ptr, handler, its_service](){ + io_.post([ptr, handler, its_service](){ handler(ptr, its_service); }); prepare_stop_handlers_.erase(found_cbk); @@ -184,12 +197,14 @@ void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iter } } - queues_.erase(_queue_iterator->first); + must_erase = true; } } if (its_connection) { - its_connection->send_queued(_queue_iterator); + its_connection->send_queued(_it); } + + return (must_erase); } void tcp_server_endpoint_impl::get_configured_times_from_endpoint( @@ -202,7 +217,7 @@ void tcp_server_endpoint_impl::get_configured_times_from_endpoint( _debouncing, _maximum_retention); } -bool tcp_server_endpoint_impl::is_established(const std::shared_ptr& _endpoint) { +bool tcp_server_endpoint_impl::is_established_to(const std::shared_ptr& _endpoint) { bool is_connected = false; endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port()); { @@ -274,7 +289,7 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection, << _error.message() << " (" << std::dec << _error.value() << ") Will try to accept again in 1000ms"; std::shared_ptr its_timer = - std::make_shared(service_, + std::make_shared(io_, std::chrono::milliseconds(1000)); auto its_ep = std::dynamic_pointer_cast( shared_from_this()); @@ -288,6 +303,7 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection, } std::uint16_t tcp_server_endpoint_impl::get_local_port() const { + return local_port_; } @@ -308,9 +324,9 @@ tcp_server_endpoint_impl::connection::connection( std::uint32_t _recv_buffer_size_initial, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service &_io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout) : - socket_(_io_service), + socket_(_io), server_(_server), max_message_size_(_max_message_size), recv_buffer_size_initial_(_recv_buffer_size_initial), @@ -326,20 +342,33 @@ tcp_server_endpoint_impl::connection::connection( send_timeout_warning_(_send_timeout / 2) { } +tcp_server_endpoint_impl::connection::~connection() { + + auto its_server(server_.lock()); + if (its_server) { + auto its_routing_host(its_server->routing_host_.lock()); + if (its_routing_host) { + its_routing_host->remove_subscriptions( + its_server->local_port_, + remote_address_, remote_port_); + } + } +} + tcp_server_endpoint_impl::connection::ptr tcp_server_endpoint_impl::connection::create( const std::weak_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout) { const std::uint32_t its_initial_receveive_buffer_size = VSOMEIP_SOMEIP_HEADER_SIZE + 8 + MAGIC_COOKIE_SIZE + 8; return ptr(new connection(_server, _max_message_size, its_initial_receveive_buffer_size, _buffer_shrink_threshold, _magic_cookies_enabled, - _io_service, _send_timeout)); + _io, _send_timeout)); } tcp_server_endpoint_impl::socket_type & @@ -360,7 +389,13 @@ void tcp_server_endpoint_impl::connection::receive() { std::lock_guard its_lock(socket_mutex_); if(socket_.is_open()) { const std::size_t its_capacity(recv_buffer_.capacity()); - size_t buffer_size = its_capacity - recv_buffer_size_; + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; try { if (missing_capacity_) { if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { @@ -369,6 +404,7 @@ void tcp_server_endpoint_impl::connection::receive() { } const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity recv_buffer_.reserve(its_required_capacity); recv_buffer_.resize(its_required_capacity, 0x0); if (recv_buffer_.size() > 1048576) { @@ -378,14 +414,16 @@ void tcp_server_endpoint_impl::connection::receive() { << " remote: " << get_address_port_remote(); } } - buffer_size = missing_capacity_; + left_buffer_size = missing_capacity_; missing_capacity_ = 0; } else if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_ && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ recv_buffer_.resize(recv_buffer_size_initial_, 0x0); recv_buffer_.shrink_to_fit(); - buffer_size = recv_buffer_size_initial_; + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; shrink_count_ = 0; } } catch (const std::exception &e) { @@ -393,7 +431,7 @@ void tcp_server_endpoint_impl::connection::receive() { // don't start receiving again return; } - socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), + socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), std::bind(&tcp_server_endpoint_impl::connection::receive_cbk, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); @@ -410,14 +448,15 @@ void tcp_server_endpoint_impl::connection::stop() { } void tcp_server_endpoint_impl::connection::send_queued( - const queue_iterator_type _queue_iterator) { + const target_data_iterator_type _it) { + std::shared_ptr its_server(server_.lock()); if (!its_server) { VSOMEIP_TRACE << "tcp_server_endpoint_impl::connection::send_queued " " couldn't lock server_"; return; } - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + message_buffer_ptr_t its_buffer = _it->second.queue_.front().first; const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], (*its_buffer)[VSOMEIP_SERVICE_POS_MAX]); @@ -437,7 +476,7 @@ void tcp_server_endpoint_impl::connection::send_queued( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { if (send_magic_cookie(its_buffer)) { last_cookie_sent_ = now; - _queue_iterator->second.first += sizeof(SERVICE_COOKIE); + _it->second.queue_size_ += sizeof(SERVICE_COOKIE); } } } @@ -459,15 +498,16 @@ void tcp_server_endpoint_impl::connection::send_queued( std::chrono::steady_clock::now()), std::bind(&tcp_server_endpoint_base_impl::send_cbk, its_server, - _queue_iterator, + _it, std::placeholders::_1, std::placeholders::_2)); } } void tcp_server_endpoint_impl::connection::send_queued_sync( - const queue_iterator_type _queue_iterator) { - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + const target_data_iterator_type _it) { + + message_buffer_ptr_t its_buffer = _it->second.queue_.front().first; if (magic_cookies_enabled_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); @@ -475,7 +515,7 @@ void tcp_server_endpoint_impl::connection::send_queued_sync( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { if (send_magic_cookie(its_buffer)) { last_cookie_sent_ = now; - _queue_iterator->second.first += sizeof(SERVICE_COOKIE); + _it->second.queue_size_ += sizeof(SERVICE_COOKIE); } } } @@ -587,36 +627,29 @@ void tcp_server_endpoint_impl::connection::receive_cbk( recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MIN], recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MAX]); if (its_client != MAGIC_COOKIE_CLIENT) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_SERVICE_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_METHOD_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_METHOD_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MIN], recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MAX]); - - std::lock_guard its_requests_guard(its_server->requests_mutex_); - its_server->requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = remote_; + its_server->clients_mutex_.lock(); + its_server->clients_[its_client][its_session] = remote_; + its_server->clients_mutex_.unlock(); } } if (!magic_cookies_enabled_) { its_host->on_message(&recv_buffer_[its_iteration_gap], current_message_size, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else { // Only call on_message without a magic cookie in front of the buffer! if (!is_magic_cookie(its_iteration_gap)) { its_host->on_message(&recv_buffer_[its_iteration_gap], current_message_size, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } } @@ -677,9 +710,9 @@ void tcp_server_endpoint_impl::connection::receive_cbk( // ensure to send back a error message w/ wrong protocol version its_host->on_message(&recv_buffer_[its_iteration_gap], VSOMEIP_SOMEIP_HEADER_SIZE + 8, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else if (!utility::is_valid_message_type(static_cast( recv_buffer_[its_iteration_gap + VSOMEIP_MESSAGE_TYPE_POS]))) { @@ -814,7 +847,7 @@ void tcp_server_endpoint_impl::connection::set_remote_info( remote_port_ = _remote.port(); } -const std::string tcp_server_endpoint_impl::connection::get_address_port_remote() const { +std::string tcp_server_endpoint_impl::connection::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -824,7 +857,7 @@ const std::string tcp_server_endpoint_impl::connection::get_address_port_remote( return its_address_port; } -const std::string tcp_server_endpoint_impl::connection::get_address_port_local() const { +std::string tcp_server_endpoint_impl::connection::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -954,7 +987,7 @@ void tcp_server_endpoint_impl::print_status() { VSOMEIP_INFO << "status tse: " << std::dec << local_port_ << " connections: " << std::dec << its_connections.size() - << " queues: " << std::dec << queues_.size(); + << " targets: " << std::dec << targets_.size(); for (const auto &c : its_connections) { std::size_t its_data_size(0); std::size_t its_queue_size(0); @@ -963,10 +996,10 @@ void tcp_server_endpoint_impl::print_status() { std::unique_lock c_s_lock(c.second->get_socket_lock()); its_recv_size = c.second->get_recv_buffer_capacity(); } - auto found_queue = queues_.find(c.first); - if (found_queue != queues_.end()) { - its_queue_size = found_queue->second.second.size(); - its_data_size = found_queue->second.first; + auto found_queue = targets_.find(c.first); + if (found_queue != targets_.end()) { + its_queue_size = found_queue->second.queue_.size(); + its_data_size = found_queue->second.queue_size_; } VSOMEIP_INFO << "status tse: client: " << c.second->get_address_port_remote() @@ -977,10 +1010,10 @@ void tcp_server_endpoint_impl::print_status() { } std::string tcp_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { + const target_data_iterator_type _it) const { boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); } std::string tcp_server_endpoint_impl::get_remote_information( diff --git a/implementation/endpoints/src/tp.cpp b/implementation/endpoints/src/tp.cpp index 0a2578dcf..f5a2f4535 100644 --- a/implementation/endpoints/src/tp.cpp +++ b/implementation/endpoints/src/tp.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,7 +16,7 @@ #include "../../configuration/include/internal.hpp" #endif // ANDROID -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #else #include @@ -26,10 +26,10 @@ namespace vsomeip_v3 { namespace tp { -const std::uint16_t tp::tp_max_segment_length_ = 1392; +tp_split_messages_t +tp::tp_split_message(const std::uint8_t * const _data, std::uint32_t _size, + std::uint16_t _max_segment_length) { -tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, - std::uint32_t _size) { tp_split_messages_t split_messages; if (_size < VSOMEIP_MAX_UDP_MESSAGE_SIZE) { @@ -38,16 +38,15 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, } const auto data_end = _data + _size; - for (auto current_offset = _data + VSOMEIP_FULL_HEADER_SIZE; current_offset < data_end;) { auto msg = std::make_shared(); - msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + tp_max_segment_length_); + msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + _max_segment_length); // copy the header msg->insert(msg->end(), _data, _data + VSOMEIP_FULL_HEADER_SIZE); // change the message type (*msg)[VSOMEIP_MESSAGE_TYPE_POS] = (*msg)[VSOMEIP_MESSAGE_TYPE_POS] | 0x20; // check if last segment - const auto segment_end = current_offset + tp_max_segment_length_; + const auto segment_end = current_offset + _max_segment_length; const bool is_last_segment = (segment_end >= data_end); // insert tp_header const tp_header_t header = htonl( @@ -63,7 +62,7 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, current_offset = data_end; } else { msg->insert(msg->end(), current_offset, segment_end); - current_offset += tp_max_segment_length_; + current_offset += _max_segment_length; } // update length const length_t its_length = static_cast(msg->size() @@ -75,5 +74,7 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, return split_messages; } +const std::uint16_t tp::tp_max_segment_length_; + } // namespace tp } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/tp_message.cpp b/implementation/endpoints/src/tp_message.cpp index 57696caee..6961511f3 100644 --- a/implementation/endpoints/src/tp_message.cpp +++ b/implementation/endpoints/src/tp_message.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,7 +18,7 @@ #include "../../configuration/include/internal.hpp" #endif // ANDROID -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #else #include diff --git a/implementation/endpoints/src/tp_reassembler.cpp b/implementation/endpoints/src/tp_reassembler.cpp index 07a31e091..49e573130 100644 --- a/implementation/endpoints/src/tp_reassembler.cpp +++ b/implementation/endpoints/src/tp_reassembler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,7 +23,7 @@ namespace vsomeip_v3 { namespace tp { -tp_reassembler::tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_service &_io) : +tp_reassembler::tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_context &_io) : max_message_size_(_max_message_size), cleanup_timer_running_(false), cleanup_timer_(_io) { @@ -175,7 +175,6 @@ void tp_reassembler::cleanup_timer_start(bool _force) { } void tp_reassembler::cleanup_timer_start_unlocked(bool _force) { - boost::system::error_code ec; if (!cleanup_timer_running_ || _force) { cleanup_timer_.expires_from_now(std::chrono::seconds(5)); cleanup_timer_running_ = true; diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index 3b9a212f6..5d675f6ef 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -1,10 +1,11 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include #include #include @@ -16,7 +17,6 @@ #include "../../utility/include/utility.hpp" #include "../../utility/include/byteorder.hpp" - namespace vsomeip_v3 { udp_client_endpoint_impl::udp_client_endpoint_impl( @@ -24,7 +24,7 @@ udp_client_endpoint_impl::udp_client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, @@ -53,6 +53,7 @@ bool udp_client_endpoint_impl::is_local() const { } void udp_client_endpoint_impl::connect() { + start_connecting_timer(); std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); @@ -63,11 +64,9 @@ void udp_client_endpoint_impl::connect() { 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() - << " local port:" << std::dec << local_.port() - << " remote:" << get_address_port_remote(); + << "SO_REUSEADDR: " << its_error.message() << " remote:" + << get_address_port_remote(); } - socket_->set_option(boost::asio::socket_base::receive_buffer_size( udp_receive_buffer_size_), its_error); if (its_error) { @@ -109,12 +108,17 @@ void udp_client_endpoint_impl::connect() { << " remote:" << get_address_port_remote(); } -#ifndef _WIN32 + if (local_.port() == ILLEGAL_PORT) { + // Let the OS assign the port + local_.port(0); + } + +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { if (setsockopt(socket_->native_handle(), - SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (socklen_t)its_device.size()) == -1) { + SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), socklen_t(its_device.size())) == -1) { VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\""; } } @@ -135,7 +139,7 @@ void udp_client_endpoint_impl::connect() { std::shared_ptr its_host = endpoint_host_.lock(); if (its_host) { // set new client port depending on service / instance / remote port - if (!its_host->on_bind_error(shared_from_this(), remote_port_)) { + if (!its_host->on_bind_error(shared_from_this(), remote_address_, remote_port_)) { VSOMEIP_WARNING << "udp_client_endpoint::connect: " "Failed to set new local port for uce: " << " local: " << local_.address().to_string() @@ -162,7 +166,6 @@ void udp_client_endpoint_impl::connect() { } return; } - return; } state_ = cei_state_e::CONNECTING; @@ -210,26 +213,44 @@ void udp_client_endpoint_impl::restart(bool _force) { start_connect_timer(); } -void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { +void udp_client_endpoint_impl::send_queued(std::pair &_entry) { + static std::chrono::steady_clock::time_point its_last_sent; #if 0 std::stringstream msg; msg << "ucei<" << remote_.address() << ":" << std::dec << remote_.port() << ">::sq: "; for (std::size_t i = 0; i < _buffer->size(); i++) msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*_buffer)[i] << " "; + << (int)(*_entry.first)[i] << " "; VSOMEIP_INFO << msg.str(); #endif { std::lock_guard its_lock(socket_mutex_); + + // Check whether we need to wait (SOME/IP-TP separation time) + if (_entry.second > 0) { + if (its_last_sent != std::chrono::steady_clock::time_point()) { + const auto its_elapsed + = std::chrono::duration_cast( + std::chrono::steady_clock::now() - its_last_sent).count(); + if (_entry.second > its_elapsed) + std::this_thread::sleep_for( + std::chrono::microseconds(_entry.second - its_elapsed)); + } + its_last_sent = std::chrono::steady_clock::now(); + } else { + its_last_sent = std::chrono::steady_clock::time_point(); + } + + // Send socket_->async_send( - boost::asio::buffer(*_buffer), + boost::asio::buffer(*_entry.first), std::bind( &udp_client_endpoint_base_impl::send_cbk, shared_from_this(), std::placeholders::_1, std::placeholders::_2, - _buffer + _entry.first ) ); } @@ -342,9 +363,9 @@ void udp_client_endpoint_impl::receive_cbk( // ensure to send back a message w/ wrong protocol version its_host->on_message(&(*_recv_buffer)[i], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset( @@ -371,17 +392,19 @@ void udp_client_endpoint_impl::receive_cbk( if (res.first) { its_host->on_message(&res.second[0], static_cast(res.second.size()), - this, boost::asio::ip::address(), + this, + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } } else { its_host->on_message(&(*_recv_buffer)[i], current_message_size, - this, boost::asio::ip::address(), + this, + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } @@ -412,8 +435,7 @@ void udp_client_endpoint_impl::receive_cbk( } } -const std::string udp_client_endpoint_impl::get_address_port_remote() const { - boost::system::error_code ec; +std::string udp_client_endpoint_impl::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::asio::ip::address its_address; @@ -425,7 +447,7 @@ const std::string udp_client_endpoint_impl::get_address_port_remote() const { return its_address_port; } -const std::string udp_client_endpoint_impl::get_address_port_local() const { +std::string udp_client_endpoint_impl::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -466,17 +488,21 @@ std::string udp_client_endpoint_impl::get_remote_information() const { + std::to_string(remote_.port()); } -void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, std::size_t _bytes, - const message_buffer_ptr_t &_sent_msg) { +void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, + std::size_t _bytes, const message_buffer_ptr_t &_sent_msg) { (void)_bytes; if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) - send_queued(its_buffer); + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { + send_queued(its_entry); + } } } else if (_error == boost::asio::error::broken_pipe) { state_ = cei_state_e::CLOSED; @@ -594,10 +620,12 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, } } -bool udp_client_endpoint_impl::tp_segmentation_enabled(service_t _service, - method_t _method) const { - return configuration_->tp_segment_messages_client_to_service(_service, - remote_address_.to_string(), remote_port_, _method); +bool udp_client_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + return configuration_->is_tp_client(_service, + remote_address_.to_string(), remote_port_, + _method); } bool udp_client_endpoint_impl::is_reliable() const { diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index bd44b48db..79dee1c3e 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -1,12 +1,17 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include #include +#if VSOMEIP_BOOST_VERSION >= 106600 +#include +#include +#endif #include #include @@ -14,8 +19,9 @@ #include "../include/endpoint_definition.hpp" #include "../include/endpoint_host.hpp" #include "../include/tp.hpp" -#include "../../routing/include/routing_host.hpp" #include "../include/udp_server_endpoint_impl.hpp" +#include "../include/udp_server_endpoint_impl_receive_op.hpp" +#include "../../routing/include/routing_host.hpp" #include "../../configuration/include/configuration.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" @@ -29,16 +35,24 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : - server_endpoint_impl(_endpoint_host, _routing_host, _local, - _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, - _configuration->get_endpoint_queue_limit(_configuration->get_unicast_address().to_string(), _local.port()), - _configuration), +#if VSOMEIP_BOOST_VERSION >= 106600 + server_endpoint_impl( +#else + server_endpoint_impl( +#endif + _endpoint_host, _routing_host, _local, + _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, + _configuration->get_endpoint_queue_limit(_configuration->get_unicast_address().to_string(), _local.port()), + _configuration), unicast_socket_(_io, _local.protocol()), unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), + is_v4_(false), multicast_id_(0), joined_group_(false), + netmask_(_configuration->get_netmask()), + prefix_(_configuration->get_prefix()), local_port_(_local.port()), tp_reassembler_(std::make_shared(_configuration->get_max_message_size_unreliable(), _io)), tp_cleanup_timer_(_io) { @@ -48,9 +62,11 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( boost::asio::socket_base::reuse_address optionReuseAddress(true); unicast_socket_.set_option(optionReuseAddress, ec); - boost::asio::detail::throw_error(ec, "reuse address"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -62,27 +78,37 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( #endif unicast_socket_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "bind"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; if (local_.address().is_v4()) { + is_v4_ = true; boost::asio::ip::multicast::outbound_interface option(_local.address().to_v4()); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "outbound interface option IPv4"); - } else if (local_.address().is_v6()) { + if (ec) + VSOMEIP_ERROR << __func__ + << ": set IPv4 outbound interface option failed (" << ec.message() << ")"; + } else { boost::asio::ip::multicast::outbound_interface option( static_cast(local_.address().to_v6().scope_id())); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "outbound interface option IPv6"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set IPv6 outbound interface option failed (" << ec.message() << ")"; } boost::asio::socket_base::broadcast option(true); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "broadcast option"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set broadcast option failed (" << ec.message() << ")"; const int its_udp_recv_buffer_size = configuration_->get_udp_receive_buffer_size(); unicast_socket_.set_option(boost::asio::socket_base::receive_buffer_size( its_udp_recv_buffer_size), ec); + if (ec) { VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " << "SO_RCVBUF: " << ec.message() << " to: " << std::dec @@ -118,17 +144,6 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( << " (" << its_udp_recv_buffer_size << ") local port:" << std::dec << local_port_; } - - -#ifdef _WIN32 - const char* optval("0001"); - ::setsockopt(unicast_socket_.native_handle(), IPPROTO_IP, IP_PKTINFO, - optval, sizeof(optval)); -#else - int optval(1); - ::setsockopt(unicast_socket_.native_handle(), IPPROTO_IP, IP_PKTINFO, - &optval, sizeof(optval)); -#endif } udp_server_endpoint_impl::~udp_server_endpoint_impl() { @@ -175,7 +190,7 @@ void udp_server_endpoint_impl::receive_unicast() { std::lock_guard its_lock(unicast_mutex_); - if(unicast_socket_.is_open()) { + if (unicast_socket_.is_open()) { unicast_socket_.async_receive_from( boost::asio::buffer(&unicast_recv_buffer_[0], max_message_size_), unicast_remote_, @@ -184,8 +199,7 @@ void udp_server_endpoint_impl::receive_unicast() { std::dynamic_pointer_cast< udp_server_endpoint_impl >(shared_from_this()), std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 + std::placeholders::_2 ) ); } @@ -197,8 +211,9 @@ void udp_server_endpoint_impl::receive_unicast() { void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { if (_multicast_id == multicast_id_ && multicast_socket_ && multicast_socket_->is_open()) { - multicast_socket_->async_receive_from( - boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), +#if VSOMEIP_BOOST_VERSION >= 106600 + udp_server_endpoint_impl_receive_op its_operation { + *multicast_socket_, multicast_remote_, std::bind( &udp_server_endpoint_impl::on_multicast_received, @@ -207,9 +222,31 @@ void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - _multicast_id + std::placeholders::_4 + ), + &multicast_recv_buffer_[0], + max_message_size_, + _multicast_id, + is_v4_, + boost::asio::ip::address(), + std::numeric_limits::min() + }; + multicast_socket_->async_wait(socket_type::wait_read, its_operation); +#else + multicast_socket_->async_receive_from( + boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), + multicast_remote_, + std::bind( + &udp_server_endpoint_impl::on_multicast_received, + std::dynamic_pointer_cast< + udp_server_endpoint_impl >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2, + _multicast_id, + std::placeholders::_3 ) ); +#endif } } @@ -229,50 +266,68 @@ bool udp_server_endpoint_impl::send_error( bool ret(false); std::lock_guard its_lock(mutex_); const endpoint_type its_target(_target->get_address(), _target->get_port()); - const queue_iterator_type target_queue_iterator(find_or_create_queue_unlocked(its_target)); - auto& its_qpair = target_queue_iterator->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); + const auto its_target_iterator(find_or_create_target_unlocked(its_target)); + auto& its_data = its_target_iterator->second; + const bool queue_size_zero_on_entry(its_data.queue_.empty()); if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_qpair.first)) { - its_qpair.second.emplace_back( - std::make_shared(_data, _data + _size)); - its_qpair.first += _size; + check_queue_limit(_data, _size, its_data.queue_size_)) { + its_data.queue_.emplace_back( + std::make_pair(std::make_shared(_data, _data + _size), 0)); + its_data.queue_size_ += _size; if (queue_size_zero_on_entry) { // no writing in progress - send_queued(target_queue_iterator); + (void)send_queued(its_target_iterator); } ret = true; } return ret; } -void udp_server_endpoint_impl::send_queued( - const queue_iterator_type _queue_iterator) { +bool udp_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + static std::chrono::steady_clock::time_point its_last_sent; + const auto its_entry = _it->second.queue_.front(); #if 0 - std::stringstream msg; - msg << "usei::sq(" << _queue_iterator->first.address().to_string() << ":" - << _queue_iterator->first.port() << "): "; - for (std::size_t i = 0; i < its_buffer->size(); ++i) - msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*its_buffer)[i] << " "; - VSOMEIP_INFO << msg.str(); + std::stringstream msg; + msg << "usei::sq(" << _queue_iterator->first.address().to_string() << ":" + << _queue_iterator->first.port() << "): "; + for (std::size_t i = 0; i < its_buffer->size(); ++i) + msg << std::hex << std::setw(2) << std::setfill('0') + << (int)(*its_entry.first)[i] << " "; + VSOMEIP_INFO << msg.str(); #endif std::lock_guard its_lock(unicast_mutex_); + // Check whether we need to wait (SOME/IP-TP separation time) + if (its_entry.second > 0) { + if (its_last_sent != std::chrono::steady_clock::time_point()) { + const auto its_elapsed + = std::chrono::duration_cast( + std::chrono::steady_clock::now() - its_last_sent).count(); + if (its_entry.second > its_elapsed) + std::this_thread::sleep_for( + std::chrono::microseconds(its_entry.second - its_elapsed)); + } + its_last_sent = std::chrono::steady_clock::now(); + } else { + its_last_sent = std::chrono::steady_clock::time_point(); + } + unicast_socket_.async_send_to( - boost::asio::buffer(*its_buffer), - _queue_iterator->first, + boost::asio::buffer(*its_entry.first), + _it->first, std::bind( &udp_server_endpoint_base_impl::send_cbk, shared_from_this(), - _queue_iterator, + _it, std::placeholders::_1, std::placeholders::_2 ) ); + + return false; } void udp_server_endpoint_impl::get_configured_times_from_endpoint( @@ -325,126 +380,18 @@ void udp_server_endpoint_impl::join_unlocked(const std::string &_address) { VSOMEIP_DEBUG << "Joining to multicast group " << _address << " from " << local_.address().to_string(); - boost::system::error_code ec; - - bool is_v4(false); - bool is_v6(false); - { - std::lock_guard its_lock(local_mutex_); - is_v4 = local_.address().is_v4(); - is_v6 = local_.address().is_v6(); - } - - if (multicast_recv_buffer_.empty()) - multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); - - if (!multicast_local_) { - if (is_v4) { - multicast_local_ = std::unique_ptr( - new endpoint_type(boost::asio::ip::address_v4::any(), local_port_)); - } - if (is_v6) { - multicast_local_ = std::unique_ptr( - new endpoint_type(boost::asio::ip::address_v6::any(), local_port_)); - } - } - - if (!multicast_socket_) { - multicast_socket_ = std::unique_ptr( - new socket_type(service_, local_.protocol())); - - boost::asio::socket_base::reuse_address optionReuseAddress(true); - multicast_socket_->set_option(optionReuseAddress, ec); - boost::asio::detail::throw_error(ec, "reuse address in multicast"); - boost::asio::socket_base::broadcast optionBroadcast(true); - multicast_socket_->set_option(optionBroadcast, ec); - boost::asio::detail::throw_error(ec, "set broadcast option"); - - multicast_socket_->bind(*multicast_local_, ec); - boost::asio::detail::throw_error(ec, "bind multicast"); - - const int its_udp_recv_buffer_size = - configuration_->get_udp_receive_buffer_size(); - multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( - its_udp_recv_buffer_size), ec); - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " - << "SO_RCVBUF: " << ec.message() << " to: " << std::dec - << its_udp_recv_buffer_size << " local port: " << std::dec - << local_port_; - } - - boost::asio::socket_base::receive_buffer_size its_option; - multicast_socket_->get_option(its_option, ec); - #ifdef __linux__ - // If regular setting of the buffer size did not work, try to force - // (requires CAP_NET_ADMIN to be successful) - if (its_option.value() < 0 - || its_option.value() < its_udp_recv_buffer_size) { - ec.assign(setsockopt(multicast_socket_->native_handle(), - SOL_SOCKET, SO_RCVBUFFORCE, - &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), - boost::system::generic_category()); - if (!ec) { - VSOMEIP_INFO << "udp_server_endpoint_impl: " - << "SO_RCVBUFFORCE: successful."; - } - multicast_socket_->get_option(its_option, ec); - } - #endif - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " - << "SO_RCVBUF: " << ec.message() << " local port:" - << std::dec << local_port_; - } else { - VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " - << std::dec << its_option.value() - << " (" << its_udp_recv_buffer_size << ") local port:" - << std::dec << local_port_; - } - -#ifdef _WIN32 - const char* optval("0001"); - if (is_v4) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO, - optval, sizeof(optval)); - } else if (is_v6) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IPV6, IPV6_PKTINFO, - optval, sizeof(optval)); - } + auto its_endpoint_host = endpoint_host_.lock(); + if (its_endpoint_host) { + multicast_option_t its_join_option { shared_from_this(), true, +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::ip::address::from_string(_address) }; #else - int optval(1); - if (is_v4) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO, - &optval, sizeof(optval)); - } else { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IPV6, IPV6_RECVPKTINFO, - &optval, sizeof(optval)); - } + boost::asio::ip::make_address(_address) }; #endif - multicast_id_++; - receive_multicast(multicast_id_); - } - - if (is_v4) { - multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); - multicast_socket_->set_option( - boost::asio::ip::multicast::enable_loopback(false)); - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v4(), - local_.address().to_v4())); - } else if (is_v6) { - multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); - multicast_socket_->set_option( - boost::asio::ip::multicast::enable_loopback(false)); - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v6(), - local_.address().to_v6().scope_id())); + its_endpoint_host->add_multicast_option(its_join_option); } joined_[_address] = false; - joined_group_ = true; - } catch (const std::exception &e) { VSOMEIP_ERROR << "udp_server_endpoint_impl::join" << ":" << e.what() << " address: " << _address; @@ -473,31 +420,20 @@ void udp_server_endpoint_impl::leave_unlocked(const std::string &_address) { VSOMEIP_DEBUG << "Leaving the multicast group " << _address << " from " << local_.address().to_string(); - bool is_v4(false); - bool is_v6(false); - { - std::lock_guard its_lock(local_mutex_); - is_v4 = local_.address().is_v4(); - is_v6 = local_.address().is_v6(); - } - if (is_v4) { - multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( - boost::asio::ip::address::from_string(_address))); - } else if (is_v6) { - multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( - boost::asio::ip::address::from_string(_address))); + if (multicast_socket_) { + auto its_endpoint_host = endpoint_host_.lock(); + if (its_endpoint_host) { + multicast_option_t its_leave_option { shared_from_this(), +#if VSOMEIP_BOOST_VERSION < 106600 + false, boost::asio::ip::address::from_string(_address) }; +#else + false, boost::asio::ip::make_address(_address) }; +#endif + its_endpoint_host->add_multicast_option(its_leave_option); + } } joined_.erase(_address); - if (0 == joined_.size()) { - joined_group_ = false; - - boost::system::error_code ec; - multicast_socket_->cancel(ec); - - multicast_socket_.reset(nullptr); - multicast_local_.reset(nullptr); - } } } catch (const std::exception &e) { @@ -541,8 +477,7 @@ void udp_server_endpoint_impl::set_local_port(std::uint16_t _port) { void udp_server_endpoint_impl::on_unicast_received( boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination) { + std::size_t _bytes) { if (_error != boost::asio::error::operation_aborted) { { @@ -550,7 +485,7 @@ void udp_server_endpoint_impl::on_unicast_received( // & multicast messages are not processed in parallel. This aligns // the behavior of endpoints with one and two active sockets. std::lock_guard its_lock(multicast_mutex_); - on_message_received(_error, _bytes, _destination, + on_message_received(_error, _bytes, false, unicast_remote_, unicast_recv_buffer_); } receive_unicast(); @@ -560,14 +495,20 @@ void udp_server_endpoint_impl::on_unicast_received( void udp_server_endpoint_impl::on_multicast_received( boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, - uint8_t _multicast_id) { + uint8_t _multicast_id, + const boost::asio::ip::address &_destination) { std::lock_guard its_lock(multicast_mutex_); if (_error != boost::asio::error::operation_aborted) { // Filter messages sent from the same source address - if (multicast_remote_.address() != local_.address()) { - on_message_received(_error, _bytes, _destination, + if (multicast_remote_.address() != local_.address() + && is_same_subnet(multicast_remote_.address())) { + + auto find_joined = joined_.find(_destination.to_string()); + if (find_joined != joined_.end()) + find_joined->second = true; + + on_message_received(_error, _bytes, true, multicast_remote_, multicast_recv_buffer_); } @@ -577,7 +518,7 @@ void udp_server_endpoint_impl::on_multicast_received( void udp_server_endpoint_impl::on_message_received( boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, + bool _is_multicast, endpoint_type const &_remote, message_buffer_t const &_buffer) { #if 0 @@ -585,7 +526,7 @@ void udp_server_endpoint_impl::on_message_received( msg << "usei::rcb(" << _error.message() << "): "; for (std::size_t i = 0; i < _bytes; ++i) msg << std::hex << std::setw(2) << std::setfill('0') - << (int) recv_buffer_[i] << " "; + << (int) _buffer[i] << " "; VSOMEIP_INFO << msg.str(); #endif std::shared_ptr its_host = routing_host_.lock(); @@ -613,7 +554,7 @@ void udp_server_endpoint_impl::on_message_received( } else if (current_message_size > VSOMEIP_RETURN_CODE_POS && (_buffer[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION || !utility::is_valid_message_type(tp::tp::tp_flag_unset(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) || - /*!utility::is_valid_return_code(static_cast(_buffer[i + VSOMEIP_RETURN_CODE_POS])) ||*/ + !utility::is_valid_return_code(static_cast(_buffer[i + VSOMEIP_RETURN_CODE_POS])) || (tp::tp::tp_flag_is_set(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS]) && get_local_port() == configuration_->get_sd_port()) )) { if (_buffer[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION) { @@ -625,9 +566,9 @@ void udp_server_endpoint_impl::on_message_received( // ensure to send back a message w/ wrong protocol version its_host->on_message(&_buffer[i], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - _destination, + _is_multicast, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, its_remote_address, its_remote_port); } else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset( _buffer[i + VSOMEIP_MESSAGE_TYPE_POS]))) { @@ -663,21 +604,9 @@ void udp_server_endpoint_impl::on_message_received( const session_t its_session = VSOMEIP_BYTES_TO_WORD( _buffer[i + VSOMEIP_SESSION_POS_MIN], _buffer[i + VSOMEIP_SESSION_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _buffer[i + VSOMEIP_METHOD_POS_MIN], - _buffer[i + VSOMEIP_METHOD_POS_MAX]); - - std::lock_guard its_requests_guard(requests_mutex_); - requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = _remote; - } - } else if (its_service != VSOMEIP_SD_SERVICE - && utility::is_notification(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS]) - && joined_group_) { - boost::system::error_code ec; - const auto found_address = joined_.find(_destination.to_string(ec)); - if (found_address != joined_.end()) { - found_address->second = true; + clients_mutex_.lock(); + clients_[its_client][its_session] = _remote; + clients_mutex_.unlock(); } } if (tp::tp::tp_flag_is_set(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) { @@ -699,33 +628,17 @@ void udp_server_endpoint_impl::on_message_received( res.second[VSOMEIP_CLIENT_POS_MIN], res.second[VSOMEIP_CLIENT_POS_MAX]); if (its_client != MAGIC_COOKIE_CLIENT) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_SERVICE_POS_MIN], - res.second[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_METHOD_POS_MIN], - res.second[VSOMEIP_METHOD_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( res.second[VSOMEIP_SESSION_POS_MIN], res.second[VSOMEIP_SESSION_POS_MAX]); - - std::lock_guard its_requests_guard(requests_mutex_); - requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = _remote; - } - } else if (its_service != VSOMEIP_SD_SERVICE - && utility::is_notification(res.second[VSOMEIP_MESSAGE_TYPE_POS]) - && joined_group_) { - boost::system::error_code ec; - const auto found_address = joined_.find(_destination.to_string(ec)); - if (found_address != joined_.end()) { - found_address->second = true; + std::lock_guard its_client_lock(clients_mutex_); + clients_[its_client][its_session] = _remote; } } its_host->on_message(&res.second[0], static_cast(res.second.size()), - this, _destination, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + this, _is_multicast, VSOMEIP_ROUTING_CLIENT, + nullptr, its_remote_address, its_remote_port); } } else { @@ -733,9 +646,9 @@ void udp_server_endpoint_impl::on_message_received( (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE && current_message_size >= remaining_bytes)) { its_host->on_message(&_buffer[i], - current_message_size, this, _destination, + current_message_size, this, _is_multicast, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, its_remote_address, its_remote_port); } else { //ignore messages for service discovery with shorter SomeIP length @@ -772,21 +685,63 @@ void udp_server_endpoint_impl::on_message_received( } } +bool udp_server_endpoint_impl::is_same_subnet(const boost::asio::ip::address &_address) const { + + bool is_same(true); +#if VSOMEIP_BOOST_VERSION < 106600 + // TODO: This needs some (more) testing + if (_address.is_v4()) { + uint32_t its_local(uint32_t(local_.address().to_v4().to_ulong())); + uint32_t its_mask(uint32_t(netmask_.to_v4().to_ulong())); + uint32_t its_address(uint32_t(_address.to_v4().to_ulong())); + + return ((its_local & its_mask) == (its_address & its_mask)); + } else { + boost::asio::ip::address_v6::bytes_type its_local(local_.address().to_v6().to_bytes()); + boost::asio::ip::address_v6::bytes_type its_address(_address.to_v6().to_bytes()); + + for (size_t i = 0; i < its_local.size(); ++i) { + byte_t its_mask(0x00); + if ((i+1) * sizeof(byte_t) <= prefix_) + its_mask = 0xff; + else if (i <= prefix_) + its_mask = byte_t(0xff << (((i+1) * sizeof(byte_t)) - prefix_)); + + if ((its_local[i] & its_mask) != (its_address[i] & its_mask)) + return (false); + } + + return (true); + } +#else + if (_address.is_v4()) { + boost::asio::ip::network_v4 its_network(local_.address().to_v4(), netmask_.to_v4()); + boost::asio::ip::address_v4_range its_hosts = its_network.hosts(); + is_same = (its_hosts.find(_address.to_v4()) != its_hosts.end()); + } else { + boost::asio::ip::network_v6 its_network(local_.address().to_v6(), prefix_); + boost::asio::ip::address_v6_range its_hosts = its_network.hosts(); + is_same = (its_hosts.find(_address.to_v6()) != its_hosts.end()); + } +#endif + return (is_same); +} + void udp_server_endpoint_impl::print_status() { std::lock_guard its_lock(mutex_); VSOMEIP_INFO << "status use: " << std::dec << local_port_ - << " number queues: " << std::dec << queues_.size() + << " number targets: " << std::dec << targets_.size() << " recv_buffer: " << std::dec << unicast_recv_buffer_.capacity() << " multicast_recv_buffer: " << std::dec << multicast_recv_buffer_.capacity(); - for (const auto &c : queues_) { + for (const auto &c : targets_) { std::size_t its_data_size(0); std::size_t its_queue_size(0); - its_queue_size = c.second.second.size(); - its_data_size = c.second.first; + its_queue_size = c.second.queue_.size(); + its_data_size = c.second.queue_size_; boost::system::error_code ec; VSOMEIP_INFO << "status use: client: " @@ -798,14 +753,16 @@ void udp_server_endpoint_impl::print_status() { } std::string udp_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { + const target_data_iterator_type _it) const { + boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); } std::string udp_server_endpoint_impl::get_remote_information( const endpoint_type& _remote) const { + boost::system::error_code ec; return _remote.address().to_string(ec) + ":" + std::to_string(_remote.port()); @@ -815,7 +772,7 @@ bool udp_server_endpoint_impl::is_reliable() const { return false; } -const std::string udp_server_endpoint_impl::get_address_port_local() const { +std::string udp_server_endpoint_impl::get_address_port_local() const { std::lock_guard its_lock(unicast_mutex_); std::string its_address_port; @@ -835,9 +792,171 @@ const std::string udp_server_endpoint_impl::get_address_port_local() const { bool udp_server_endpoint_impl::tp_segmentation_enabled( service_t _service, method_t _method) const { - return configuration_->tp_segment_messages_service_to_client(_service, - local_.address().to_string(), - local_.port(), _method); + return configuration_->is_tp_service(_service, + local_.address().to_string(), local_.port(), + _method); +} + +void +udp_server_endpoint_impl::set_multicast_option( + const boost::asio::ip::address &_address, bool _is_join) { + + boost::system::error_code ec; + + if (_is_join) { + if (!multicast_socket_) { + std::lock_guard its_guard(multicast_mutex_); + + multicast_socket_ = std::unique_ptr( + new socket_type(io_, local_.protocol())); + + multicast_socket_->set_option(ip::udp::socket::reuse_address(true), ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; + +#ifdef _WIN32 + const char *its_option("0001"); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), + its_option, sizeof(its_option)); +#else + int its_pktinfo_option(1); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), + &its_pktinfo_option, sizeof(its_pktinfo_option)); +#endif + + if (multicast_recv_buffer_.empty()) + multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); + + if (!multicast_local_) { + if (is_v4_) { + multicast_local_ = std::unique_ptr( + new endpoint_type(boost::asio::ip::address_v4::any(), local_port_)); + } else { // is_v6 + multicast_local_ = std::unique_ptr( + new endpoint_type(boost::asio::ip::address_v6::any(), local_port_)); + } + } + + multicast_socket_->bind(*multicast_local_, ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + + const int its_udp_recv_buffer_size = + configuration_->get_udp_receive_buffer_size(); + + multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( + its_udp_recv_buffer_size), ec); + +#ifndef _WIN32 + // define socket timeout + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = VSOMEIP_SETSOCKOPT_TIMEOUT_US; + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_RCVTIMEO"; + } + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_SNDTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_SNDTIMEO"; + } +#endif + + if (ec) { + VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " + << "SO_RCVBUF: " << ec.message() << " to: " << std::dec + << its_udp_recv_buffer_size << " local port: " << std::dec + << local_port_; + } + + boost::asio::socket_base::receive_buffer_size its_option; + multicast_socket_->get_option(its_option, ec); +#ifdef __linux__ + // If regular setting of the buffer size did not work, try to force + // (requires CAP_NET_ADMIN to be successful) + if (its_option.value() < 0 + || its_option.value() < its_udp_recv_buffer_size) { + ec.assign(setsockopt(multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVBUFFORCE, + &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), + boost::system::generic_category()); + if (!ec) { + VSOMEIP_INFO << "udp_server_endpoint_impl: " + << "SO_RCVBUFFORCE: successful."; + } + multicast_socket_->get_option(its_option, ec); + } +#endif + if (ec) { + VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " + << "SO_RCVBUF: " << ec.message() << " local port:" + << std::dec << local_port_; + } else { + VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " + << std::dec << its_option.value() + << " (" << its_udp_recv_buffer_size << ") local port:" + << std::dec << local_port_; + } + + multicast_id_++; + receive_multicast(multicast_id_); + } + + boost::asio::ip::multicast::join_group its_join_option; + { + std::lock_guard its_lock(local_mutex_); + if (is_v4_) { + + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v4(), + local_.address().to_v4()); + } else { + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v6(), + static_cast(local_.address().to_v6().scope_id())); + } + } + multicast_socket_->set_option(its_join_option, ec); + + if (!ec) { + std::lock_guard its_guard(multicast_mutex_); + joined_[_address.to_string()] = false; + joined_group_ = true; + } + } else { + if (multicast_socket_) { + boost::asio::ip::multicast::leave_group its_leave_option(_address); + multicast_socket_->set_option(its_leave_option, ec); + + if (!ec) { + std::lock_guard its_guard(multicast_mutex_); + joined_.erase(_address.to_string()); + + if (0 == joined_.size()) { + joined_group_ = false; + + multicast_socket_->cancel(ec); + + multicast_socket_.reset(nullptr); + multicast_local_.reset(nullptr); + } + } + } + } } } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp index 5c8981cd6..e4441a982 100644 --- a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,9 +12,9 @@ namespace vsomeip_v3 { virtual_server_endpoint_impl::virtual_server_endpoint_impl( const std::string &_address, uint16_t _port, bool _reliable, - boost::asio::io_service& _service) + boost::asio::io_context &_io) : address_(_address), port_(_port), reliable_(_reliable), use_count_(0), - service_(_service) { + io_(_io) { } virtual_server_endpoint_impl::~virtual_server_endpoint_impl() { @@ -23,10 +23,10 @@ virtual_server_endpoint_impl::~virtual_server_endpoint_impl() { void virtual_server_endpoint_impl::start() { } -void virtual_server_endpoint_impl::prepare_stop(endpoint::prepare_stop_handler_t _handler, +void virtual_server_endpoint_impl::prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service) { auto ptr = shared_from_this(); - service_.post([ptr, _handler, _service]() { + io_.post([ptr, _handler, _service]() { _handler(ptr, _service); }); } @@ -56,14 +56,6 @@ bool virtual_server_endpoint_impl::send(const byte_t *_data, uint32_t _size) { return false; } -bool virtual_server_endpoint_impl::send(const std::vector& _cmd_header, - const byte_t *_data, uint32_t _size) { - (void)_cmd_header; - (void)_data; - (void)_size; - return false; -} - bool virtual_server_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { @@ -147,7 +139,7 @@ void virtual_server_endpoint_impl::restart(bool _force) { } void virtual_server_endpoint_impl::register_error_handler( - error_handler_t _handler) { + const error_handler_t &_handler) { (void)_handler; } diff --git a/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 2820f81d6..000000000 --- a/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1043 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#include -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template )> -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext< - Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - */ - explicit basic_datagram_socket_ext(boost::asio::io_context& io_context) - : basic_socket_ext(io_context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_socket_ext(io_context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_socket_ext(io_context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext( - io_context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - template - basic_datagram_socket_ext( - basic_datagram_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_datagram_socket_ext>::type& operator=( - basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().send_to(this->get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 92d71e30e..000000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,1989 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::null_socket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local -# endif -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template )> -class basic_socket_acceptor_ext - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor_ext acceptor(io_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(listen_backlog); - * @endcode - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - this->get_service().set_option(this->get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor_ext on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor_ext from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_context&) constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket_acceptor_ext from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_context&) constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor_ext from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_ext_local(io_context&) constructor. - */ - template - basic_socket_acceptor_ext( - basic_socket_acceptor_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket_acceptor_ext from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_ext_local(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_acceptor_ext>::type& operator=( - basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - this->get_service().listen(this->get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * acceptor.accept(socket); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, - boost::system::error_code& ec, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - void accept(basic_socket_ext_local& peer, endpoint_type& peer_endpoint) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - peer, &peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept( - this->get_implementation(), 0, 0, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), 0, 0, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept( - this->get_implementation(), static_cast(0), - static_cast(0), - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept( - this->get_implementation(), static_cast(0), - static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept(boost::asio::io_context& io_context) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - &io_context, static_cast(0), ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - boost::asio::io_context& io_context, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - &io_context, static_cast(0), ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_accept(io_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(boost::asio::io_context& io_context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - &io_context, static_cast(0), - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - &io_context, static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - static_cast(0), &peer_endpoint, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - static_cast(0), &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - static_cast(0), &peer_endpoint, - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - static_cast(0), &peer_endpoint, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(io_context2, endpoint)); - * @endcode - */ - typename Protocol::socket accept( - boost::asio::io_context& io_context, endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - &io_context, &peer_endpoint, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(io_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::asio::io_context& io_context, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - &io_context, &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(io_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(boost::asio::io_context& io_context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept( - this->get_implementation(), &io_context, &peer_endpoint, - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - &io_context, &peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index cdf4029c0..000000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1760 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext -# endif -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_ext>::type& operator=( - basic_socket_ext&& other) - { - basic_socket_ext tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = this->get_service().at_mark(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return this->get_service().at_mark(this->get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = this->get_service().available( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return this->get_service().available(this->get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (!is_open()) - { - boost::system::error_code ec; - const protocol_type protocol = peer_endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - if (ec) - { - async_completion init(handler); - - boost::asio::post(this->get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( - ConnectHandler, void (boost::system::error_code)))( - init.completion_handler), ec)); - - return init.result.get(); - } - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_connect( - this->get_implementation(), peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().remote_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return this->get_service().remote_endpoint(this->get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - this->get_service().shutdown(this->get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index e13154cfe..000000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1760 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local -# endif -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_ext_local>::type& operator=( - basic_socket_ext_local&& other) - { - basic_socket_ext_local tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = this->get_service().at_mark(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return this->get_service().at_mark(this->get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = this->get_service().available( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return this->get_service().available(this->get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (!is_open()) - { - boost::system::error_code ec; - const protocol_type protocol = peer_endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - if (ec) - { - async_completion init(handler); - - boost::asio::post(this->get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( - ConnectHandler, void (boost::system::error_code)))( - init.completion_handler), ec)); - - return init.result.get(); - } - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_connect( - this->get_implementation(), peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().remote_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return this->get_service().remote_endpoint(this->get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - this->get_service().shutdown(this->get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index 99d29c3fc..000000000 --- a/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,924 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template )> -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext_local< - Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket_ext without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(boost::asio::io_context& io_context) - : basic_socket_ext_local(io_context) - { - } - - /// Construct and open a basic_stream_socket_ext. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_socket_ext_local(io_context, protocol) - { - } - - /// Construct a basic_stream_socket_ext, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_socket_ext_local(io_context, endpoint) - { - } - - /// Construct a basic_stream_socket_ext on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local( - io_context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket_ext from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket_ext from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - template - basic_stream_socket_ext( - basic_stream_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - template - typename enable_if::value, - basic_stream_socket_ext>::type& operator=( - basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send( - this->get_implementation(), buffers, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send( - this->get_implementation(), buffers, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send( - this->get_implementation(), buffers, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send( - this->get_implementation(), buffers, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().send(this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 89f1594c1..000000000 --- a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,565 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index e12b1ca15..000000000 --- a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,592 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, \ - std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 6219e1f44..000000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - boost::asio::io_context& io_context) - : io_context_(io_context), reactor_(use_service(io_context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 02a628be9..000000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - boost::asio::io_context& io_context) - : io_context_(io_context), reactor_(use_service(io_context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 484976688..000000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,230 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 2a066b8e7..000000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 4f7828498..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index 994a495bf..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 969e8aba4..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index a8a2af70b..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index 0efd6c33f..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index c992283a6..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index b6a80bd3e..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,517 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext( - boost::asio::io_context& io_context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The io_context that owns this socket service - io_context& io_context_; - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index e23357498..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,514 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local( - boost::asio::io_context& io_context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The io_context that owns this socket service. - io_context& io_context_; - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 761f2bbde..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,531 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(boost::asio::io_context& io_context) - : service_base >(io_context), - reactive_socket_service_base_ext(io_context) - { - } - - // Destroy all user-defined handler objects owned by the service - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Accept a new connection. - typename Protocol::socket accept(implementation_type& impl, - io_context* peer_io_context, endpoint_type* peer_endpoint, - boost::system::error_code& ec) - { - typename Protocol::socket peer( - peer_io_context ? *peer_io_context : io_context_); - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return peer; - } - #endif // defined(BOOST_ASIO_HAS_MOVE) - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_accept(implementation_type& impl, - boost::asio::io_context* peer_io_context, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_, - impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index a9468516f..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,529 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(boost::asio::io_context& io_context) - : service_base >(io_context), - reactive_socket_service_base_ext_local(io_context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Accept a new connection. - typename Protocol::socket accept(implementation_type& impl, - io_context* peer_io_context, endpoint_type* peer_endpoint, - boost::system::error_code& ec) - { - typename Protocol::socket peer( - peer_io_context ? *peer_io_context : io_context_); - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return peer; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_accept(implementation_type& impl, - boost::asio::io_context* peer_io_context, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_, - impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 04c2c70ef..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3a2727212..000000000 --- a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - - // The passed credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index cc28d9cb5..000000000 --- a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index e08a64370..000000000 --- a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac444..000000000 --- a/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 6ccd0ad0f..000000000 --- a/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp deleted file mode 100644 index ff5c5f8cc..000000000 --- a/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp +++ /dev/null @@ -1,415 +0,0 @@ -// -// stream_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a stream socket. -template -class stream_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_context::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_context::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::winrt_ssocket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext_local service_impl_type; -#endif - -public: - /// The type of a stream socket implementation. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new stream socket service for the specified io_context. - explicit stream_socket_service_ext(boost::asio::io_context& io_context) - : boost::asio::detail::service_base< - stream_socket_service_ext >(io_context), - service_impl_(io_context) - { - } - - /// Construct a new stream socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new stream socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another stream socket implementation. - void move_assign(implementation_type& impl, - stream_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - // All socket services have access to each other's implementations. - template friend class stream_socket_service_ext; - - /// Move-construct a new stream socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - stream_socket_service_ext& other_service, - typename stream_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_service.service_impl_, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a stream socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a stream socket. - BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to a stream socket. - BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - service_impl_.assign(impl, protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a stream socket implementation. - BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl, - boost::system::error_code& ec) - { - service_impl_.close(impl, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying socket. - native_handle_type release(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.release(impl, ec); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl, - boost::system::error_code& ec) - { - service_impl_.cancel(impl, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - /// Bind the stream socket to the specified local endpoint. - BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - service_impl_.bind(impl, endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the stream socket to the specified endpoint. - BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - service_impl_.connect(impl, peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - async_completion init(handler); - - service_impl_.async_connect(impl, peer_endpoint, init.completion_handler); - - return init.result.get(); - } - - /// Set a socket option. - template - BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - service_impl_.set_option(impl, option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get a socket option. - template - BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - service_impl_.get_option(impl, option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - template - BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - service_impl_.io_control(impl, command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - service_impl_.non_blocking(impl, mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - service_impl_.native_non_blocking(impl, mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - service_impl_.shutdown(impl, what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - service_impl_.wait(impl, w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(implementation_type& impl, socket_base::wait_type w, - BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - async_completion init(handler); - - service_impl_.async_wait(impl, w, init.completion_handler); - - return init.result.get(); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - async_completion init(handler); - - service_impl_.async_send(impl, buffers, flags, init.completion_handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - async_completion init(handler); - - service_impl_.async_receive(impl, buffers, flags, init.completion_handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - service_impl_.shutdown(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 58a553fa3..000000000 --- a/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index e3e296624..000000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 523f97a2f..000000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 855d01c1f..000000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index 325157abd..000000000 --- a/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd98..000000000 --- a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640adf8..000000000 --- a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036adf8..000000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf1931..000000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index a4546ca92..000000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,230 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 5050f248a..000000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,303 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index da8cd83b3..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index ce5ca289d..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 6cc244366..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index 81485ffd5..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index cd027301b..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 059cddb57..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 3fc3a5a44..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index 8c5503f74..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 1eae3570f..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index e55cfb16a..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index b267cf67a..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index cd81ffb4b..000000000 --- a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fedb5..000000000 --- a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index f494d7944..000000000 --- a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac444..000000000 --- a/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62fa..000000000 --- a/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 49a4950a5..000000000 --- a/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 998b86d4f..000000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 523f97a2f..000000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 855d01c1f..000000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index e77f5ebba..000000000 --- a/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd98..000000000 --- a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640adf8..000000000 --- a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036adf8..000000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf1931..000000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 39e2ed84e..000000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,234 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - signed_size_type result; - - result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL); - get_last_error(ec, true); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - result = WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL); - get_last_error(ec, true); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 83a673b81..000000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,307 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0); - get_last_error(ec, true); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = ::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0); - get_last_error(ec, true); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 1167d57fa..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index bedbd2903..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 875fe1420..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - success_ec, socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index f9fef2b83..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index bd315dcfe..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 81486904c..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(success_ec, - socket, buffers, in_flags, out_flags, - &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 2e68a877c..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index a71fce5ba..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 7254ccddb..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 8ac326548..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 697cd9ffe..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3d9ae5fa5..000000000 --- a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fedb5..000000000 --- a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index a937bb652..000000000 --- a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac444..000000000 --- a/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62fa..000000000 --- a/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 49a4950a5..000000000 --- a/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 0a86539ad..000000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 777a0bf72..000000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 2c898fc6c..000000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index e77f5ebba..000000000 --- a/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd98..000000000 --- a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640adf8..000000000 --- a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036adf8..000000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf1931..000000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 39e2ed84e..000000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,234 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - signed_size_type result; - - result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL); - get_last_error(ec, true); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - result = WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL); - get_last_error(ec, true); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 83a673b81..000000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,307 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0); - get_last_error(ec, true); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = ::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0); - get_last_error(ec, true); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 1167d57fa..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index bedbd2903..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 875fe1420..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - success_ec, socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index f9fef2b83..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index bd315dcfe..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 81486904c..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(success_ec, - socket, buffers, in_flags, out_flags, - &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 2e68a877c..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index a71fce5ba..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 7254ccddb..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 8ac326548..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 697cd9ffe..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3d9ae5fa5..000000000 --- a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fedb5..000000000 --- a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index a937bb652..000000000 --- a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac444..000000000 --- a/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62fa..000000000 --- a/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp rename to implementation/helper/boost/asio/basic_datagram_socket_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp rename to implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/boost/asio/basic_stream_socket_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp rename to implementation/helper/boost/asio/basic_stream_socket_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp b/implementation/helper/boost/asio/datagram_socket_service_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp rename to implementation/helper/boost/asio/datagram_socket_service_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp rename to implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp rename to implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp rename to implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp diff --git a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp rename to implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp diff --git a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp similarity index 75% rename from implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp rename to implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp index fb6f77bc1..fe90e83e9 100644 --- a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp +++ b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp @@ -59,30 +59,20 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, if (result >= 0) { ec = boost::system::error_code(); - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } + // Find destination address + for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) + continue; + + struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); + if (pi) + { + da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); + } + } } else { dwNumberOfBytesRecvd = -1; } @@ -101,30 +91,20 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, if (result >= 0) { ec = boost::system::error_code(); - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } + // Find destination address + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) + continue; + + struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); + if (pi) + { + da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); + } + } } return result; #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) diff --git a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp rename to implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp rename to implementation/helper/boost/asio/detail/reactor_op_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp rename to implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp rename to implementation/helper/boost/asio/detail/socket_ops_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp rename to implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp diff --git a/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp b/implementation/helper/boost/asio/ip/udp_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/ip/udp_ext.hpp rename to implementation/helper/boost/asio/ip/udp_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/boost/asio/local/stream_protocol_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp rename to implementation/helper/boost/asio/local/stream_protocol_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp b/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp rename to implementation/helper/boost/asio/socket_acceptor_service_ext.hpp diff --git a/implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/boost/asio/stream_socket_service_ext.hpp similarity index 100% rename from implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp rename to implementation/helper/boost/asio/stream_socket_service_ext.hpp diff --git a/implementation/logger/include/logger_impl.hpp b/implementation/logger/include/logger_impl.hpp index bb8336398..c827bf4f6 100644 --- a/implementation/logger/include/logger_impl.hpp +++ b/implementation/logger/include/logger_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,8 +10,10 @@ #include #ifdef USE_DLT +#ifndef ANDROID #include #endif +#endif #include @@ -43,7 +45,9 @@ class logger_impl { std::shared_ptr configuration_; #ifdef USE_DLT - DLT_DECLARE_CONTEXT(dlt_); +#ifndef ANDROID + DLT_DECLARE_CONTEXT(dlt_) +#endif #endif }; diff --git a/implementation/logger/src/logger_impl.cpp b/implementation/logger/src/logger_impl.cpp index 7e79aa232..b909c34e4 100644 --- a/implementation/logger/src/logger_impl.cpp +++ b/implementation/logger/src/logger_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,18 +25,22 @@ logger_impl::init(const std::shared_ptr &_configuration) { # define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP" # define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context" +#ifndef ANDROID std::string its_context_id = runtime::get_property("LogContext"); if (its_context_id == "") its_context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID; DLT_REGISTER_CONTEXT(its_logger->dlt_, its_context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME); #endif +#endif } logger_impl::~logger_impl() { #ifdef USE_DLT +#ifndef ANDROID DLT_UNREGISTER_CONTEXT(dlt_); #endif +#endif } std::shared_ptr @@ -45,6 +49,7 @@ logger_impl::get_configuration() const { } #ifdef USE_DLT +#ifndef ANDROID void logger_impl::log(level_e _level, const char *_data) { @@ -76,13 +81,14 @@ logger_impl::log(level_e _level, const char *_data) { DLT_LOG_STRING(dlt_, its_level, _data); } #endif +#endif static std::shared_ptr *the_logger_ptr__(nullptr); static std::mutex the_logger_mutex__; std::shared_ptr logger_impl::get() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) std::lock_guard its_lock(the_logger_mutex__); #endif if (the_logger_ptr__ == nullptr) { @@ -97,12 +103,15 @@ logger_impl::get() { return (nullptr); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) static void logger_impl_teardown(void) __attribute__((destructor)); static void logger_impl_teardown(void) { + // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. + // Since this function only runs on the main thread, no mutex should be needed. Leaving a + // comment pending a refactor. + // std::lock_guard its_lock(the_logger_mutex__); if (the_logger_ptr__ != nullptr) { - std::lock_guard its_lock(the_logger_mutex__); the_logger_ptr__->reset(); delete the_logger_ptr__; the_logger_ptr__ = nullptr; diff --git a/implementation/logger/src/message.cpp b/implementation/logger/src/message.cpp index 6787452b8..b89816c41 100644 --- a/implementation/logger/src/message.cpp +++ b/implementation/logger/src/message.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,14 +10,57 @@ #include #ifdef ANDROID -#include +#include -#ifndef LOG_TAG -#define LOG_TAG NULL +#ifdef ALOGE +#undef ALOGE #endif + +#define ALOGE(LOG_TAG, ...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGE ALOGE +#endif + +#ifdef ALOGW +#undef ALOGW +#endif + +#define ALOGW(LOG_TAG, ...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGW ALOGW +#endif + +#ifdef ALOGI +#undef ALOGI +#endif + +#define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGI ALOGI +#endif + +#ifdef ALOGD +#undef ALOGD +#endif + +#define ALOGD(LOG_TAG, ...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGD ALOGD +#endif + +#ifdef ALOGV +#undef ALOGV +#endif + +#define ALOGV(LOG_TAG, ...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGV ALOGV +#endif + #endif #include +#include #include "../include/logger_impl.hpp" #include "../../configuration/include/configuration.hpp" @@ -34,7 +77,7 @@ message::message(level_e _level) when_ = std::chrono::system_clock::now(); } -message::~message() { +message::~message() try { std::lock_guard its_lock(mutex__); auto its_logger = logger_impl::get(); auto its_configuration = its_logger->get_configuration(); @@ -75,44 +118,47 @@ message::~message() { // Prepare time stamp auto its_time_t = std::chrono::system_clock::to_time_t(when_); - auto its_time = std::localtime(&its_time_t); + struct tm its_time; + localtime_r(&its_time_t, &its_time); auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000; if (its_configuration->has_console_log()) { #ifndef ANDROID std::cout - << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon + 1 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() << std::endl; #else + std::string app = runtime::get_property("LogApplication"); + switch (level_) { case level_e::LL_FATAL: - (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_ERROR: - (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_WARNING: - (void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGW(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_INFO: - (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_DEBUG: - (void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGD(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_VERBOSE: - (void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGV(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; default: - (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); }; #endif // !ANDROID } @@ -123,12 +169,12 @@ message::~message() { std::ios_base::app); if (its_logfile.is_open()) { its_logfile - << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon + 1 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() @@ -138,9 +184,13 @@ message::~message() { } if (its_configuration->has_dlt_log()) { #ifdef USE_DLT +#ifndef ANDROID its_logger->log(level_, buffer_.data_.str().c_str()); +#endif #endif // USE_DLT } +} catch (const std::exception& e) { + std::cout << "\nVSIP: Error destroying message class: " << e.what() << '\n'; } std::streambuf::int_type diff --git a/implementation/message/include/deserializer.hpp b/implementation/message/include/deserializer.hpp index 058fe9442..098698d04 100644 --- a/implementation/message/include/deserializer.hpp +++ b/implementation/message/include/deserializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,7 @@ class deserializer { VSOMEIP_EXPORT virtual ~deserializer(); VSOMEIP_EXPORT void set_data(const byte_t *_data, std::size_t _length); + VSOMEIP_EXPORT void set_data(const std::vector &_data); VSOMEIP_EXPORT void append_data(const byte_t *_data, std::size_t _length); VSOMEIP_EXPORT void drop_data(std::size_t _length); diff --git a/implementation/message/include/message_base_impl.hpp b/implementation/message/include/message_base_impl.hpp index 216656ba2..acad2e899 100644 --- a/implementation/message/include/message_base_impl.hpp +++ b/implementation/message/include/message_base_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/message_header_impl.hpp b/implementation/message/include/message_header_impl.hpp index b6e305a0f..f82775fb2 100644 --- a/implementation/message/include/message_header_impl.hpp +++ b/implementation/message/include/message_header_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/message_impl.hpp b/implementation/message/include/message_impl.hpp index b121c4667..e04d4a7eb 100644 --- a/implementation/message/include/message_impl.hpp +++ b/implementation/message/include/message_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -47,16 +47,20 @@ class message_impl VSOMEIP_EXPORT bool is_valid_crc() const; VSOMEIP_EXPORT uid_t get_uid() const; - VSOMEIP_EXPORT void set_uid(uid_t _uid); VSOMEIP_EXPORT gid_t get_gid() const; - VSOMEIP_EXPORT void set_gid(gid_t _gid); + + VSOMEIP_EXPORT vsomeip_sec_client_t get_sec_client() const; + VSOMEIP_EXPORT void set_sec_client(const vsomeip_sec_client_t &_sec_client); + + VSOMEIP_EXPORT std::string get_env() const; + VSOMEIP_EXPORT void set_env(const std::string &_env); protected: // members std::shared_ptr< payload > payload_; uint8_t check_result_; - uid_t uid_; - gid_t gid_; + vsomeip_sec_client_t sec_client_; + std::string env_; }; } // namespace vsomeip_v3 diff --git a/implementation/message/include/payload_impl.hpp b/implementation/message/include/payload_impl.hpp index 8ea256c91..d77eaa01d 100644 --- a/implementation/message/include/payload_impl.hpp +++ b/implementation/message/include/payload_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/serializer.hpp b/implementation/message/include/serializer.hpp index ff9967927..bd626ab01 100644 --- a/implementation/message/include/serializer.hpp +++ b/implementation/message/include/serializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -40,9 +40,16 @@ class VSOMEIP_IMPORT_EXPORT serializer { virtual void show(); #endif private: +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4251) +#endif std::vector data_; std::uint32_t shrink_count_; std::uint32_t buffer_shrink_threshold_; +#ifdef _WIN32 +#pragma warning(pop) +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp index 0e33faac2..cff459653 100644 --- a/implementation/message/src/deserializer.cpp +++ b/implementation/message/src/deserializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -164,17 +164,18 @@ bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const { return true; } -message_impl * deserializer::deserialize_message() { - message_impl* deserialized_message = new message_impl; - if (0 != deserialized_message) { - if (false == deserialized_message->deserialize(this)) { - VSOMEIP_ERROR << "SOME/IP message deserialization failed!"; - delete deserialized_message; - deserialized_message = nullptr; - } +message_impl * deserializer::deserialize_message() try { + std::unique_ptr deserialized_message{new message_impl}; + if (false == deserialized_message->deserialize(this)) { + VSOMEIP_ERROR << "SOME/IP message deserialization failed!"; + deserialized_message = nullptr; } - return deserialized_message; + return deserialized_message.release(); +} +catch (const std::exception& e) { + VSOMEIP_ERROR << "SOME/IP message deserialization failed with exception: " << e.what(); + return nullptr; } void deserializer::set_data(const byte_t *_data, std::size_t _length) { @@ -189,6 +190,14 @@ void deserializer::set_data(const byte_t *_data, std::size_t _length) { } } +void +deserializer::set_data(const std::vector &_data) { + + data_ = std::move(_data); + position_ = data_.begin(); + remaining_ = data_.size(); +} + void deserializer::append_data(const byte_t *_data, std::size_t _length) { std::vector::difference_type offset = (position_ - data_.begin()); data_.insert(data_.end(), _data, _data + _length); diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp index 43295c497..c1d7da7dd 100644 --- a/implementation/message/src/message_base_impl.cpp +++ b/implementation/message/src/message_base_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/message_header_impl.cpp b/implementation/message/src/message_header_impl.cpp index 27950e7f8..40b98c32a 100644 --- a/implementation/message/src/message_header_impl.cpp +++ b/implementation/message/src/message_header_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp index 25cf584dd..c784e52a6 100644 --- a/implementation/message/src/message_impl.cpp +++ b/implementation/message/src/message_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,7 +19,9 @@ namespace vsomeip_v3 { message_impl::message_impl() : payload_(runtime::get()->create_payload()), - check_result_(0), uid_(ANY_UID), gid_(ANY_GID) { + check_result_(0) { + + sec_client_.client_type = VSOMEIP_CLIENT_INVALID; } message_impl::~message_impl() { @@ -66,19 +68,43 @@ bool message_impl::is_valid_crc() const { } uid_t message_impl::get_uid() const { - return uid_; + + uid_t its_uid(ANY_UID); + + if (sec_client_.client_type == VSOMEIP_CLIENT_UDS) { + its_uid = sec_client_.client.uds_client.user; + } + + return (its_uid); } -void message_impl::set_uid(uid_t _uid) { - uid_ = _uid; +gid_t message_impl::get_gid() const { + + gid_t its_gid(ANY_GID); + + if (sec_client_.client_type == VSOMEIP_CLIENT_UDS) { + its_gid = sec_client_.client.uds_client.group; + } + + return (its_gid); +} + +vsomeip_sec_client_t message_impl::get_sec_client() const { + + return (sec_client_); +} + +void message_impl::set_sec_client(const vsomeip_sec_client_t &_sec_client) { + + sec_client_ = _sec_client; } -uid_t message_impl::get_gid() const { - return gid_; +std::string message_impl::get_env() const { + return env_; } -void message_impl::set_gid(gid_t _gid) { - gid_ = _gid; +void message_impl::set_env(const std::string &_env) { + env_ = _env; } } // namespace vsomeip_v3 diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp index dd1a6aa3c..7617cdc1a 100644 --- a/implementation/message/src/payload_impl.cpp +++ b/implementation/message/src/payload_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp index fe5196ea3..fa94a9c02 100644 --- a/implementation/message/src/serializer.cpp +++ b/implementation/message/src/serializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/plugin/include/plugin_manager.hpp b/implementation/plugin/include/plugin_manager.hpp index 61662b8e5..d398e2457 100644 --- a/implementation/plugin/include/plugin_manager.hpp +++ b/implementation/plugin/include/plugin_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,8 +19,10 @@ class plugin_manager { VSOMEIP_EXPORT virtual ~plugin_manager() {}; VSOMEIP_EXPORT static std::shared_ptr get(); VSOMEIP_EXPORT virtual void load_plugins() = 0; - VSOMEIP_EXPORT virtual std::shared_ptr get_plugin(plugin_type_e _type, std::string _name) = 0; - + VSOMEIP_EXPORT virtual std::shared_ptr get_plugin(plugin_type_e _type, const std::string &_name) = 0; + VSOMEIP_EXPORT virtual void * load_library(const std::string &_path) = 0; + VSOMEIP_EXPORT virtual void * load_symbol(void * _handle, const std::string &_symbol) = 0; + VSOMEIP_EXPORT virtual void unload_library(void * _handle) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/plugin/include/plugin_manager_impl.hpp b/implementation/plugin/include/plugin_manager_impl.hpp index eb7d09f37..e88772e60 100644 --- a/implementation/plugin/include/plugin_manager_impl.hpp +++ b/implementation/plugin/include/plugin_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -29,7 +29,8 @@ class plugin_manager_impl : public plugin_manager { VSOMEIP_EXPORT void load_plugins(); - VSOMEIP_EXPORT std::shared_ptr get_plugin(plugin_type_e _type, std::string _name); + VSOMEIP_EXPORT std::shared_ptr get_plugin(plugin_type_e _type, + const std::string &_name); VSOMEIP_EXPORT std::shared_ptr load_plugin( const std::string& _library, plugin_type_e _type, @@ -37,12 +38,13 @@ class plugin_manager_impl : public plugin_manager { VSOMEIP_EXPORT bool unload_plugin(plugin_type_e _type); + VSOMEIP_EXPORT void * load_library(const std::string &_path); + VSOMEIP_EXPORT void * load_symbol(void * _handle, const std::string &_symbol); + VSOMEIP_EXPORT void unload_library(void * _handle); + private: void add_plugin(const std::shared_ptr &_plugin, const std::string& _name); - void * load_library(const std::string &_path); - void * load_symbol(void * _handle, const std::string &_symbol); - bool plugins_loaded_; std::mutex loader_mutex_; diff --git a/implementation/plugin/src/plugin_manager.cpp b/implementation/plugin/src/plugin_manager.cpp index f8ddaa1b5..d64cbaaea 100644 --- a/implementation/plugin/src/plugin_manager.cpp +++ b/implementation/plugin/src/plugin_manager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/plugin/src/plugin_manager_impl.cpp b/implementation/plugin/src/plugin_manager_impl.cpp index 159eea985..bfaf27281 100644 --- a/implementation/plugin/src/plugin_manager_impl.cpp +++ b/implementation/plugin/src/plugin_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,7 @@ #include #include #include +#include #include #ifdef _WIN32 @@ -110,7 +111,8 @@ void plugin_manager_impl::load_plugins() { } } -std::shared_ptr plugin_manager_impl::get_plugin(plugin_type_e _type, std::string _name) { +std::shared_ptr plugin_manager_impl::get_plugin(plugin_type_e _type, + const std::string &_name) { std::lock_guard its_lock_start_stop(plugins_mutex_); auto its_type = plugins_.find(_type); if (its_type != plugins_.end()) { @@ -180,38 +182,52 @@ void * plugin_manager_impl::load_library(const std::string &_path) { #endif } -void * plugin_manager_impl::load_symbol(void * _handle, - const std::string &_symbol) { - void * its_symbol = 0; +void * plugin_manager_impl::load_symbol(void * _handle, const std::string &_symbol_name) { + void* symbol = nullptr; + if (_handle) { #ifdef _WIN32 - HINSTANCE hDLL = (HINSTANCE)_handle; - if (hDLL != NULL) { + symbol = GetProcAddress(reinterpret_cast(_handle), _symbol_name.c_str()); +#else + symbol = dlsym(_handle, _symbol_name.c_str()); +#endif - typedef UINT(CALLBACK* LPFNDLLFUNC1)(DWORD, UINT); + if (!symbol) { + char* error_message = nullptr; - LPFNDLLFUNC1 lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, _symbol.c_str()); - if (!lpfnDllFunc1) { - FreeLibrary(hDLL); - std::cerr << "Loading symbol \"" << _symbol << "\" failed (" << GetLastError() << ")" << std::endl; - } - else { - its_symbol = lpfnDllFunc1; - } - } +#ifdef _WIN32 + DWORD error_code = GetLastError(); + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast(&error_message), + 0, + nullptr + ); #else - if (0 != _handle) { - dlerror(); // Clear previous error - its_symbol = dlsym(_handle, _symbol.c_str()); - const char *dlsym_error = dlerror(); - if (dlsym_error) { - VSOMEIP_INFO << "Cannot load symbol : " << _symbol << " : " << dlsym_error; - dlclose(_handle); + error_message = dlerror(); +#endif + + VSOMEIP_ERROR << "Cannot load symbol " << std::quoted(_symbol_name) << " because: " << error_message; + +#ifdef _WIN32 + // Required to release memory allocated by FormatMessageA() + LocalFree(error_message); +#endif } - } else { - VSOMEIP_ERROR << "Loading failed: (" << dlerror() << ")"; } + return symbol; +} + +void plugin_manager_impl::unload_library(void * _handle) { + if (_handle) { +#ifdef _WIN32 + FreeLibrary(reinterpret_cast(_handle)); +#else + dlclose(_handle); #endif - return (its_symbol); + } } } // namespace vsomeip_v3 diff --git a/implementation/protocol/include/assign_client_ack_command.hpp b/implementation/protocol/include/assign_client_ack_command.hpp new file mode 100644 index 000000000..ec112680c --- /dev/null +++ b/implementation/protocol/include/assign_client_ack_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class assign_client_ack_command + : public command { +public: + assign_client_ack_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + client_t get_assigned() const; + void set_assigned(client_t _assigned); + +private: + client_t assigned_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/assign_client_command.hpp b/implementation/protocol/include/assign_client_command.hpp new file mode 100644 index 000000000..b1932da87 --- /dev/null +++ b/implementation/protocol/include/assign_client_command.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class assign_client_command + : public command { +public: + assign_client_command(); + + // command + id_e get_id() const; + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::string get_name() const; + void set_name(const std::string &_name); + +private: + std::string name_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ diff --git a/implementation/protocol/include/command.hpp b/implementation/protocol/include/command.hpp new file mode 100644 index 000000000..a39990a1b --- /dev/null +++ b/implementation/protocol/include/command.hpp @@ -0,0 +1,46 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ + +#include // memcpy +#include + +#include + +#include "protocol.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +using commandize_t = std::uint32_t; + +class command { +public: + inline id_e get_id() const { return id_; } + inline version_t get_version() const { return version_; } + inline client_t get_client() const { return client_; } + inline void set_client(client_t _client) { client_ = _client; } + inline command_size_t get_size() const { return size_; } + + virtual void serialize(std::vector &_buffer, + error_e &_error) const; + virtual void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + id_e id_; + version_t version_; + client_t client_; + mutable command_size_t size_; + + command(id_e _id); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ diff --git a/implementation/protocol/include/deregister_application_command.hpp b/implementation/protocol/include/deregister_application_command.hpp new file mode 100644 index 000000000..9b1bcb858 --- /dev/null +++ b/implementation/protocol/include/deregister_application_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class deregister_application_command + : public simple_command { + +public: + deregister_application_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ diff --git a/implementation/protocol/include/distribute_security_policies_command.hpp b/implementation/protocol/include/distribute_security_policies_command.hpp new file mode 100644 index 000000000..2b2c6735d --- /dev/null +++ b/implementation/protocol/include/distribute_security_policies_command.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ + +#include +#include +#include +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +class payload; +struct policy; + +namespace protocol { + +class distribute_security_policies_command + : public command { +public: + distribute_security_policies_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set > get_policies() const; + + void set_payloads(const std::map > &_payloads); + +private: + std::set > policies_; + std::vector payload_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ diff --git a/implementation/protocol/include/dummy_command.hpp b/implementation/protocol/include/dummy_command.hpp new file mode 100644 index 000000000..70f4f6c1b --- /dev/null +++ b/implementation/protocol/include/dummy_command.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class dummy_command + : public command { +public: + dummy_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ diff --git a/implementation/protocol/include/expire_command.hpp b/implementation/protocol/include/expire_command.hpp new file mode 100644 index 000000000..4c47aa98a --- /dev/null +++ b/implementation/protocol/include/expire_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class expire_command + : public subscribe_command_base { + +public: + expire_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ diff --git a/implementation/protocol/include/multiple_services_command_base.hpp b/implementation/protocol/include/multiple_services_command_base.hpp new file mode 100644 index 000000000..d679b166e --- /dev/null +++ b/implementation/protocol/include/multiple_services_command_base.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class multiple_services_command_base + : public command { +public: + multiple_services_command_base(id_e _id); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set get_services() const; + void set_services(const std::set &_services); + void add_service(const service &_service); + +private: + std::set services_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/offer_service_command.hpp b/implementation/protocol/include/offer_service_command.hpp new file mode 100644 index 000000000..22e5f36ac --- /dev/null +++ b/implementation/protocol/include/offer_service_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ + +#include "service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offer_service_command + : public service_command_base { + +public: + offer_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/offered_services_request_command.hpp b/implementation/protocol/include/offered_services_request_command.hpp new file mode 100644 index 000000000..3ced94985 --- /dev/null +++ b/implementation/protocol/include/offered_services_request_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offered_services_request_command + : public command { + +public: + offered_services_request_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + offer_type_e get_offer_type() const; + void set_offer_type(offer_type_e _offer_type); + +private: + offer_type_e offer_type_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ diff --git a/implementation/protocol/include/offered_services_response_command.hpp b/implementation/protocol/include/offered_services_response_command.hpp new file mode 100644 index 000000000..79a8f2c96 --- /dev/null +++ b/implementation/protocol/include/offered_services_response_command.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ + +#include "multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offered_services_response_command + : public multiple_services_command_base { +public: + offered_services_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/include/ping_command.hpp b/implementation/protocol/include/ping_command.hpp new file mode 100644 index 000000000..369e2551a --- /dev/null +++ b/implementation/protocol/include/ping_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class ping_command + : public simple_command { + +public: + ping_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ diff --git a/implementation/protocol/include/pong_command.hpp b/implementation/protocol/include/pong_command.hpp new file mode 100644 index 000000000..1876f0d45 --- /dev/null +++ b/implementation/protocol/include/pong_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class pong_command + : public simple_command { + +public: + pong_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ diff --git a/implementation/protocol/include/protocol.hpp b/implementation/protocol/include/protocol.hpp new file mode 100644 index 000000000..08a770bee --- /dev/null +++ b/implementation/protocol/include/protocol.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ +#define VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ + +#include +#include + +namespace vsomeip_v3 { +namespace protocol { + +using version_t = std::uint16_t; +using command_size_t = std::uint32_t; + +enum class id_e : uint8_t { + ASSIGN_CLIENT_ID = 0x00, + ASSIGN_CLIENT_ACK_ID = 0x01, + REGISTER_APPLICATION_ID = 0x02, + DEREGISTER_APPLICATION_ID = 0x03, + // APPLICATION_LOST_ID = 0x04, + ROUTING_INFO_ID = 0x05, + REGISTERED_ACK_ID = 0x06, + PING_ID = 0x07, + PONG_ID = 0x08, + OFFER_SERVICE_ID = 0x10, + STOP_OFFER_SERVICE_ID = 0x11, + SUBSCRIBE_ID = 0x12, + UNSUBSCRIBE_ID = 0x13, + REQUEST_SERVICE_ID = 0x14, + RELEASE_SERVICE_ID = 0x15, + SUBSCRIBE_NACK_ID = 0x16, + SUBSCRIBE_ACK_ID = 0x17, + SEND_ID = 0x18, + NOTIFY_ID = 0x19, + NOTIFY_ONE_ID = 0x1A, + REGISTER_EVENT_ID = 0x1B, + UNREGISTER_EVENT_ID = 0x1C, + ID_RESPONSE_ID = 0x1D, + ID_REQUEST_ID = 0x1E, + OFFERED_SERVICES_REQUEST_ID = 0x1F, + OFFERED_SERVICES_RESPONSE_ID = 0x20, + UNSUBSCRIBE_ACK_ID = 0x21, + RESEND_PROVIDED_EVENTS_ID = 0x22, + UPDATE_SECURITY_POLICY_ID = 0x23, + UPDATE_SECURITY_POLICY_RESPONSE_ID = 0x24, + REMOVE_SECURITY_POLICY_ID = 0x25, + REMOVE_SECURITY_POLICY_RESPONSE_ID = 0x26, + UPDATE_SECURITY_CREDENTIALS_ID = 0x27, + DISTRIBUTE_SECURITY_POLICIES_ID = 0x28, + UPDATE_SECURITY_POLICY_INT_ID = 0x29, + EXPIRE_ID = 0x2A, + SUSPEND_ID = 0x30, + UNKNOWN_ID = 0xFF +}; + +enum class error_e : uint8_t { + ERROR_OK = 0x00, + ERROR_NOT_ENOUGH_BYTES = 0x01, + ERROR_MAX_COMMAND_SIZE_EXCEEDED = 0x02, + ERROR_MISMATCH = 0x04, + ERROR_MALFORMED = 0x08, + ERROR_NOT_ALLOWED = 0x10, + ERROR_UNKNOWN = 0xff +}; + +enum class routing_info_entry_type_e : std::uint8_t { + RIE_ADD_CLIENT = 0x00, + RIE_DELETE_CLIENT = 0x01, + RIE_ADD_SERVICE_INSTANCE = 0x02, + RIE_DELETE_SERVICE_INSTANCE = 0x04, + RIE_UNKNOWN = 0xff +}; + +using pending_id_t = std::uint16_t; + +struct service { + service_t service_; + instance_t instance_; + major_version_t major_; + minor_version_t minor_; + + service() + : service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + major_(ANY_MAJOR), + minor_(ANY_MINOR) { + } + + service(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) + : service_(_service), + instance_(_instance), + major_(_major), + minor_(_minor) { + } + + bool operator<(const service &_other) const { + + return (service_ < _other.service_ + || (service_ == _other.service_ + && instance_ < _other.instance_)); + } +}; + +static const version_t MAX_SUPPORTED_VERSION = 0; + +static const size_t TAG_SIZE = 4; +static const size_t COMMAND_HEADER_SIZE = 9; +static const size_t SEND_COMMAND_HEADER_SIZE = 15; +static const size_t ROUTING_INFO_ENTRY_HEADER_SIZE = 7; + +static const size_t COMMAND_POSITION_ID = 0; +static const size_t COMMAND_POSITION_VERSION = 1; +static const size_t COMMAND_POSITION_CLIENT = 3; +static const size_t COMMAND_POSITION_SIZE = 5; +static const size_t COMMAND_POSITION_PAYLOAD = 9; + +static inline id_e get_command(byte_t _byte) { + + id_e its_id(id_e::UNKNOWN_ID); + if (_byte <= static_cast(id_e::SUSPEND_ID)) + its_id = static_cast(_byte); + return (its_id); +} + +static inline bool operator==(const byte_t &_lhs, const id_e &_rhs) { + + return (_lhs == static_cast(_rhs)); +} + +static inline bool operator==(const id_e &_lhs, const byte_t &_rhs) { + + return (_rhs == _lhs); +} + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ diff --git a/implementation/protocol/include/register_application_command.hpp b/implementation/protocol/include/register_application_command.hpp new file mode 100644 index 000000000..ffb15ad87 --- /dev/null +++ b/implementation/protocol/include/register_application_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class register_application_command + : public command { + +public: + register_application_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + port_t get_port() const; + void set_port(port_t _port); + +private: + port_t port_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ diff --git a/implementation/protocol/include/register_event.hpp b/implementation/protocol/include/register_event.hpp new file mode 100644 index 000000000..f468c0222 --- /dev/null +++ b/implementation/protocol/include/register_event.hpp @@ -0,0 +1,67 @@ +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ + +#include +#include +#include +#include + +#include "protocol.hpp" +#include +#include + +namespace vsomeip_v3 { +namespace protocol { + +class register_event { +public: + register_event(service_t service = ANY_SERVICE, instance_t instance = ANY_INSTANCE, + event_t event = ANY_EVENT, event_type_e event_type = event_type_e::ET_UNKNOWN, + bool is_provided = false, reliability_type_e reliability = reliability_type_e::RT_UNKNOWN, + bool is_cyclic = false, uint16_t num_eventg = 0, + const std::set &eventgroups = std::set()); + void serialize(std::vector &_buffer, size_t &_offset) const; + void deserialize(const std::vector &_buffer, size_t &_offset); + + service_t get_service() const { return service_; } + void set_service(service_t _service) { service_ = _service; } + + instance_t get_instance() const { return instance_; } + void set_instance(instance_t _instance) { instance_ = _instance; } + + event_t get_event() const { return event_; } + void set_event(event_t _event) { event_ = _event; } + + event_type_e get_event_type() const { return event_type_; } + void set_event_type(event_type_e _event_type) { event_type_ = _event_type; } + + bool is_provided() const { return is_provided_; } + void set_provided(bool _is_provided) { is_provided_ = _is_provided; } + + reliability_type_e get_reliability() const { return reliability_; } + void set_reliability(reliability_type_e _reliability) { reliability_ = _reliability; } + + bool is_cyclic() const { return is_cyclic_; } + void set_cyclic(bool _cyclic) { is_cyclic_ = _cyclic; } + + uint16_t get_num_eventgroups() const { return num_eventg_; } + + std::set get_eventgroups() const { return eventgroups_; } + void set_eventgroups(const std::set &_eventgroups); + +private: + service_t service_; + instance_t instance_; + event_t event_; + event_type_e event_type_; + bool is_provided_; + reliability_type_e reliability_; + bool is_cyclic_; + uint16_t num_eventg_; + std::set eventgroups_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ diff --git a/implementation/protocol/include/register_events_command.hpp b/implementation/protocol/include/register_events_command.hpp new file mode 100644 index 000000000..23dd7faea --- /dev/null +++ b/implementation/protocol/include/register_events_command.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ + +#include + +#include + +#include "command.hpp" +#include "register_event.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class register_events_command + : public command { +public: + + register_events_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + std::size_t get_num_registrations() const; + + bool add_registration(const register_event &_register_event); + bool get_registration_at(std::size_t _position, register_event & _reg) const; + +private: + std::vector registrations_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ diff --git a/implementation/protocol/include/registered_ack_command.hpp b/implementation/protocol/include/registered_ack_command.hpp new file mode 100644 index 000000000..0ae85ba9e --- /dev/null +++ b/implementation/protocol/include/registered_ack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class registered_ack_command + : public simple_command { + +public: + registered_ack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/release_service_command.hpp b/implementation/protocol/include/release_service_command.hpp new file mode 100644 index 000000000..537fd14aa --- /dev/null +++ b/implementation/protocol/include/release_service_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class release_service_command + : public command { +public: + release_service_command(); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + +private: + service service_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/remove_security_policy_command.hpp b/implementation/protocol/include/remove_security_policy_command.hpp new file mode 100644 index 000000000..83480e45a --- /dev/null +++ b/implementation/protocol/include/remove_security_policy_command.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class remove_security_policy_command + : public command { +public: + remove_security_policy_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + + uid_t get_uid() const; + void set_uid(uid_t _uid); + + gid_t get_gid() const; + void set_gid(gid_t _gid); + +private: + uint32_t update_id_; + uid_t uid_; + gid_t gid_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ diff --git a/implementation/protocol/include/remove_security_policy_response_command.hpp b/implementation/protocol/include/remove_security_policy_response_command.hpp new file mode 100644 index 000000000..7deda2cbb --- /dev/null +++ b/implementation/protocol/include/remove_security_policy_response_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ + +#include "security_policy_response_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class remove_security_policy_response_command + : public security_policy_response_command_base { + +public: + remove_security_policy_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/include/request_service_command.hpp b/implementation/protocol/include/request_service_command.hpp new file mode 100644 index 000000000..945247eac --- /dev/null +++ b/implementation/protocol/include/request_service_command.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ + +#include "multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class request_service_command + : public multiple_services_command_base { +public: + request_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/resend_provided_events_command.hpp b/implementation/protocol/include/resend_provided_events_command.hpp new file mode 100644 index 000000000..1fc493c09 --- /dev/null +++ b/implementation/protocol/include/resend_provided_events_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class resend_provided_events_command + : public command { +public: + resend_provided_events_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + pending_remote_offer_id_t get_remote_offer_id() const; + void set_remote_offer_id(pending_remote_offer_id_t _remote_offer_id); + +private: + pending_remote_offer_id_t remote_offer_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ diff --git a/implementation/protocol/include/routing_info_command.hpp b/implementation/protocol/include/routing_info_command.hpp new file mode 100644 index 000000000..2cb0ab745 --- /dev/null +++ b/implementation/protocol/include/routing_info_command.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ + +#include "command.hpp" +#include "routing_info_entry.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class routing_info_command + : public command { +public: + routing_info_command(); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + const std::vector &get_entries() const; + void set_entries(std::vector &&_entries); + void add_entry(const routing_info_entry &_entry); + +private: + std::vector entries_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ diff --git a/implementation/protocol/include/routing_info_entry.hpp b/implementation/protocol/include/routing_info_entry.hpp new file mode 100644 index 000000000..b27190b14 --- /dev/null +++ b/implementation/protocol/include/routing_info_entry.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ +#define VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ + +#include + +#include + +#include "protocol.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class routing_info_entry { +public: + routing_info_entry(); + routing_info_entry(const routing_info_entry &_source); + + void serialize(std::vector &_buffer, size_t &_index, + error_e &_error) const; + void deserialize(const std::vector &_buffer, size_t &_index, + error_e &_error); + + routing_info_entry_type_e get_type() const; + void set_type(routing_info_entry_type_e _type); + + size_t get_size() const; + + client_t get_client() const; + void set_client(client_t _client); + + boost::asio::ip::address get_address() const; + void set_address(const boost::asio::ip::address &_address); + + port_t get_port() const; + void set_port(port_t _port); + + const std::vector &get_services() const; + void add_service(const service &_service); + +private: + routing_info_entry_type_e type_; + + client_t client_; + + boost::asio::ip::address address_; + port_t port_; + + std::vector services_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ diff --git a/implementation/protocol/include/security_policy_response_command_base.hpp b/implementation/protocol/include/security_policy_response_command_base.hpp new file mode 100644 index 000000000..799f70391 --- /dev/null +++ b/implementation/protocol/include/security_policy_response_command_base.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class security_policy_response_command_base + : public command { +public: + security_policy_response_command_base(id_e _id); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + +private: + uint32_t update_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/send_command.hpp b/implementation/protocol/include/send_command.hpp new file mode 100644 index 000000000..cb10b450f --- /dev/null +++ b/implementation/protocol/include/send_command.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SEND_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SEND_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class send_command + : public command { +public: + send_command(id_e _id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + bool is_reliable() const; + void set_reliable(bool _is_reliable); + + uint8_t get_status() const; + void set_status(uint8_t _status); + + client_t get_target() const; + void set_target(client_t _target); + + // TODO: Optimize this as the vector might be huge! + std::vector get_message() const; + void set_message(const std::vector &_message); + +private: + + instance_t instance_; + bool is_reliable_; + uint8_t status_; // TODO: DO WE REALLY NEED THIS? + client_t target_; + std::vector message_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_BASIC_COMMAND_HPP_ diff --git a/implementation/protocol/include/service_command_base.hpp b/implementation/protocol/include/service_command_base.hpp new file mode 100644 index 000000000..05b488d77 --- /dev/null +++ b/implementation/protocol/include/service_command_base.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class service_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + major_version_t get_major() const; + void set_major(major_version_t _major); + + minor_version_t get_minor() const; + void set_minor(minor_version_t _minor); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + service_command_base(id_e _id); + +private: + service service_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/simple_command.hpp b/implementation/protocol/include/simple_command.hpp new file mode 100644 index 000000000..09ae8fd70 --- /dev/null +++ b/implementation/protocol/include/simple_command.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class simple_command + : public command { +public: + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + simple_command(id_e _id); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ diff --git a/implementation/protocol/include/stop_offer_service_command.hpp b/implementation/protocol/include/stop_offer_service_command.hpp new file mode 100644 index 000000000..a9a51d296 --- /dev/null +++ b/implementation/protocol/include/stop_offer_service_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ + +#include "service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class stop_offer_service_command + : public service_command_base { + +public: + stop_offer_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_ack_command.hpp b/implementation/protocol/include/subscribe_ack_command.hpp new file mode 100644 index 000000000..b3f4c762a --- /dev/null +++ b/implementation/protocol/include/subscribe_ack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ + +#include "subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_ack_command + : public subscribe_ack_command_base { + +public: + subscribe_ack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_ack_command_base.hpp b/implementation/protocol/include/subscribe_ack_command_base.hpp new file mode 100644 index 000000000..3a738b9a1 --- /dev/null +++ b/implementation/protocol/include/subscribe_ack_command_base.hpp @@ -0,0 +1,57 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_ack_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + client_t get_subscriber() const; + void set_subscriber(client_t _subscriber); + + event_t get_event() const; + void set_event(event_t _event); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + subscribe_ack_command_base(id_e _id); + + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + client_t subscriber_; + event_t event_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/subscribe_command.hpp b/implementation/protocol/include/subscribe_command.hpp new file mode 100644 index 000000000..d55256224 --- /dev/null +++ b/implementation/protocol/include/subscribe_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_command + : public subscribe_command_base { + +public: + subscribe_command(); + + std::shared_ptr get_filter() const; + void set_filter(const std::shared_ptr &_filter); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +private: + std::shared_ptr filter_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_command_base.hpp b/implementation/protocol/include/subscribe_command_base.hpp new file mode 100644 index 000000000..a16c2fe19 --- /dev/null +++ b/implementation/protocol/include/subscribe_command_base.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ + +#include + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + major_version_t get_major() const; + void set_major(major_version_t _major); + + event_t get_event() const; + void set_event(event_t _event); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + subscribe_command_base(id_e _id); + + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + major_version_t major_; + event_t event_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/subscribe_nack_command.hpp b/implementation/protocol/include/subscribe_nack_command.hpp new file mode 100644 index 000000000..5b79ce519 --- /dev/null +++ b/implementation/protocol/include/subscribe_nack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ + +#include "subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_nack_command + : public subscribe_ack_command_base { + +public: + subscribe_nack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/suspend_command.hpp b/implementation/protocol/include/suspend_command.hpp new file mode 100644 index 000000000..414b36f14 --- /dev/null +++ b/implementation/protocol/include/suspend_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUSPEND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUSPEND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class suspend_command + : public simple_command { + +public: + suspend_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUSPEND_COMMAND_HPP_ diff --git a/implementation/protocol/include/unregister_event_command.hpp b/implementation/protocol/include/unregister_event_command.hpp new file mode 100644 index 000000000..9779946e2 --- /dev/null +++ b/implementation/protocol/include/unregister_event_command.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNREGISTER_EVENT_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNREGISTER_EVENT_COMMAND_HPP_ + +#include + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unregister_event_command + : public command { +public: + unregister_event_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + event_t get_event() const; + void set_event(event_t _event); + + bool is_provided() const; + void set_provided(bool _is_provided); + +private: + service_t service_; + instance_t instance_; + event_t event_; + bool is_provided_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_COMMAND_HPP_ diff --git a/implementation/protocol/include/unsubscribe_ack_command.hpp b/implementation/protocol/include/unsubscribe_ack_command.hpp new file mode 100644 index 000000000..7afaa1d5e --- /dev/null +++ b/implementation/protocol/include/unsubscribe_ack_command.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unsubscribe_ack_command + : public command { + +public: + unsubscribe_ack_command(); + + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +private: + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/unsubscribe_command.hpp b/implementation/protocol/include/unsubscribe_command.hpp new file mode 100644 index 000000000..e0a05ce36 --- /dev/null +++ b/implementation/protocol/include/unsubscribe_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unsubscribe_command + : public subscribe_command_base { + +public: + unsubscribe_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_credentials_command.hpp b/implementation/protocol/include/update_security_credentials_command.hpp new file mode 100644 index 000000000..37d9c34fc --- /dev/null +++ b/implementation/protocol/include/update_security_credentials_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class update_security_credentials_command + : public command { +public: + update_security_credentials_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set > get_credentials() const; + void set_credentials( + const std::set > &_credentials); + +private: + std::set > credentials_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_policy_command.hpp b/implementation/protocol/include/update_security_policy_command.hpp new file mode 100644 index 000000000..9a42d649d --- /dev/null +++ b/implementation/protocol/include/update_security_policy_command.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class update_security_policy_command + : public command { +public: + update_security_policy_command(bool _is_internal = false); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + + std::shared_ptr get_policy() const; + void set_policy(const std::shared_ptr &_policy); + +private: + uint32_t update_id_; + std::shared_ptr policy_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_policy_response_command.hpp b/implementation/protocol/include/update_security_policy_response_command.hpp new file mode 100644 index 000000000..002b00127 --- /dev/null +++ b/implementation/protocol/include/update_security_policy_response_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ + +#include "security_policy_response_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class update_security_policy_response_command + : public security_policy_response_command_base { + +public: + update_security_policy_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/src/assign_client_ack_command.cpp b/implementation/protocol/src/assign_client_ack_command.cpp new file mode 100644 index 000000000..b5d19ea74 --- /dev/null +++ b/implementation/protocol/src/assign_client_ack_command.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/assign_client_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +assign_client_ack_command::assign_client_ack_command() + : command(id_e::ASSIGN_CLIENT_ACK_ID) { + +} + +void +assign_client_ack_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(assigned_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(assigned_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &assigned_, + sizeof(assigned_)); +} + +void +assign_client_ack_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(assigned_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&assigned_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(assigned_)); +} + +client_t +assign_client_ack_command::get_assigned() const { + + return (assigned_); +} + +void +assign_client_ack_command::set_assigned(client_t _assigned) { + + assigned_ = _assigned; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/assign_client_command.cpp b/implementation/protocol/src/assign_client_command.cpp new file mode 100644 index 000000000..245ea92bb --- /dev/null +++ b/implementation/protocol/src/assign_client_command.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include "../include/assign_client_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +assign_client_command::assign_client_command() + : command(id_e::ASSIGN_CLIENT_ID) { + +} + +void +assign_client_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + name_.length()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(name_.length()); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], name_.data(), name_.length()); +} + +void +assign_client_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload? + if (size_ == 0) + return; + + // name + name_.assign(&_buffer[COMMAND_POSITION_PAYLOAD], + &_buffer[_buffer.size()-1]); +} + +std::string +assign_client_command::get_name() const { + + return (name_); +} + +void +assign_client_command::set_name(const std::string &_name) { + + name_ = _name; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/command.cpp b/implementation/protocol/src/command.cpp new file mode 100644 index 000000000..fe338b06a --- /dev/null +++ b/implementation/protocol/src/command.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +command::command(id_e _id) + : id_(_id), + version_(MAX_SUPPORTED_VERSION), + client_(0), + size_(0) { +} + +void +command::serialize(std::vector &_buffer, + error_e &_error) const { + + // buffer space reservation is done within the code of + // the derived classes that call this method + + _buffer[0] = static_cast(id_); + std::memcpy(&_buffer[COMMAND_POSITION_VERSION], &version_, + sizeof(version_)); + std::memcpy(&_buffer[COMMAND_POSITION_CLIENT], &client_, + sizeof(client_)); + std::memcpy(&_buffer[COMMAND_POSITION_SIZE], &size_, + sizeof(size_)); + + _error = error_e::ERROR_OK; +} + +void +command::deserialize(const std::vector &_buffer, + error_e &_error) { + + // buffer size check (size >= header size) is + // done within the code of the derived classes + // that call this method + + // If the id_ is set to "UNKNOWN", read it. + // Otherwise check it. + if (id_ == id_e::UNKNOWN_ID) { + + id_ = static_cast(_buffer[0]); + } else if (_buffer[0] != static_cast(id_)) { + + _error = error_e::ERROR_MISMATCH; + return; + } + + std::memcpy(&version_, &_buffer[COMMAND_POSITION_VERSION], + sizeof(version_)); + std::memcpy(&client_, &_buffer[COMMAND_POSITION_CLIENT], + sizeof(client_)); + std::memcpy(&size_, &_buffer[COMMAND_POSITION_SIZE], + sizeof(size_)); + + _error = error_e::ERROR_OK; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/deregister_application_command.cpp b/implementation/protocol/src/deregister_application_command.cpp new file mode 100644 index 000000000..5cd6f8d7b --- /dev/null +++ b/implementation/protocol/src/deregister_application_command.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/deregister_application_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +deregister_application_command::deregister_application_command() + : simple_command(id_e::DEREGISTER_APPLICATION_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/distribute_security_policies_command.cpp b/implementation/protocol/src/distribute_security_policies_command.cpp new file mode 100644 index 000000000..c93b53091 --- /dev/null +++ b/implementation/protocol/src/distribute_security_policies_command.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/distribute_security_policies_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +distribute_security_policies_command::distribute_security_policies_command() + : command(id_e::DISTRIBUTE_SECURITY_POLICIES_ID) { +} + +void +distribute_security_policies_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + std::min(payload_.size(), size_t(std::numeric_limits::max()))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize (add) payload + size_t its_offset(COMMAND_HEADER_SIZE); + if (payload_.empty()) { // No policy data (--> set_payloads was not called) + std::memset(&_buffer[its_offset], 0, sizeof(uint32_t)); + } else { + std::memcpy(&_buffer[its_offset], payload_.data(), payload_.size()); + } +} + +void +distribute_security_policies_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(uint32_t) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + uint32_t its_policies_count; + std::memcpy(&its_policies_count, &_buffer[its_offset], + sizeof(its_policies_count)); + its_offset += sizeof(its_policies_count); + + for (uint32_t i = 0; i < its_policies_count; i++) { + + uint32_t its_policy_size; + std::memcpy(&its_policy_size, &_buffer[its_offset], + sizeof(its_policy_size)); + its_offset += sizeof(its_policy_size); + + const byte_t *its_policy_data = &_buffer[its_offset]; + + // set offset to the next policy + its_offset += its_policy_size; + + auto its_policy = std::make_shared(); + if (its_policy_size == 0 + || !its_policy->deserialize(its_policy_data, its_policy_size)) { + + _error = error_e::ERROR_UNKNOWN; + policies_.clear(); + return; + } + + policies_.insert(its_policy); + } +} + +std::set > +distribute_security_policies_command::get_policies() const { + + return (policies_); +} + +void +distribute_security_policies_command::set_payloads( + const std::map > &_payloads) { + + uint32_t its_count(uint32_t(_payloads.size())); + for (uint32_t i = 0; i < sizeof(its_count); ++i) { + payload_.push_back( + reinterpret_cast(&its_count)[i]); + } + + for (const auto &its_uid_gid : _payloads) { + // policy payload length including gid and uid + std::uint32_t its_length(uint32_t(its_uid_gid.second->get_length())); + for (uint32_t i = 0; i < sizeof(its_length); ++i) { + payload_.push_back( + reinterpret_cast(&its_length)[i]); + } + // payload + payload_.insert(payload_.end(), its_uid_gid.second->get_data(), + its_uid_gid.second->get_data() + its_uid_gid.second->get_length()); + } +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/dummy_command.cpp b/implementation/protocol/src/dummy_command.cpp new file mode 100644 index 000000000..0ecc18f17 --- /dev/null +++ b/implementation/protocol/src/dummy_command.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/dummy_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +dummy_command::dummy_command() + : command(id_e::UNKNOWN_ID) { + +} + +void +dummy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + (void)_buffer; + _error = error_e::ERROR_NOT_ALLOWED; +} + +void +dummy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/expire_command.cpp b/implementation/protocol/src/expire_command.cpp new file mode 100644 index 000000000..06119016e --- /dev/null +++ b/implementation/protocol/src/expire_command.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/expire_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +expire_command::expire_command() + : subscribe_command_base(id_e::EXPIRE_ID) { +} + +void +expire_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // payload + subscribe_command_base::serialize(_buffer, _error); +} + +void +expire_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + subscribe_command_base::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/multiple_services_command_base.cpp b/implementation/protocol/src/multiple_services_command_base.cpp new file mode 100644 index 000000000..47c8ab23a --- /dev/null +++ b/implementation/protocol/src/multiple_services_command_base.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +multiple_services_command_base::multiple_services_command_base(id_e _id) + : command(_id) { + +} + +void +multiple_services_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + (services_.size() + * (sizeof(service::service_) + sizeof(service::instance_) + + sizeof(service::major_) + sizeof(service::minor_)))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + for (const auto &s : services_) { + std::memcpy(&_buffer[its_offset], &s.service_, sizeof(s.service_)); + its_offset += sizeof(s.service_); + std::memcpy(&_buffer[its_offset], &s.instance_, sizeof(s.instance_)); + its_offset += sizeof(s.instance_); + _buffer[its_offset] = s.major_; + its_offset += sizeof(s.major_); + std::memcpy(&_buffer[its_offset], &s.minor_, sizeof(s.minor_)); + its_offset += sizeof(s.minor_); + } +} + +void +multiple_services_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + size_t its_count = (_buffer.size() - its_offset) / + (sizeof(service::service_) + sizeof(service::instance_) + + sizeof(service::major_) + sizeof(service::minor_)); + + for (size_t i = 0; i < its_count; i++) { + service its_service; + + std::memcpy(&its_service.service_, &_buffer[its_offset], + sizeof(its_service.service_)); + its_offset += sizeof(its_service.service_); + std::memcpy(&its_service.instance_, &_buffer[its_offset], + sizeof(its_service.instance_)); + its_offset += sizeof(its_service.instance_); + std::memcpy(&its_service.major_, &_buffer[its_offset], + sizeof(its_service.major_)); + its_offset += sizeof(its_service.major_); + std::memcpy(&its_service.minor_, &_buffer[its_offset], + sizeof(its_service.minor_)); + its_offset += sizeof(its_service.minor_); + + services_.insert(its_service); + } +} + +std::set +multiple_services_command_base::get_services() const { + + return (services_); +} + +void +multiple_services_command_base::set_services(const std::set &_services) { + + services_ = _services; +} + +void +multiple_services_command_base::add_service(const service &_service) { + + services_.insert(_service); +} + + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offer_service_command.cpp b/implementation/protocol/src/offer_service_command.cpp new file mode 100644 index 000000000..286a6f74d --- /dev/null +++ b/implementation/protocol/src/offer_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/offer_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offer_service_command::offer_service_command() + : service_command_base(id_e::OFFER_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offered_services_request_command.cpp b/implementation/protocol/src/offered_services_request_command.cpp new file mode 100644 index 000000000..3a0aa956b --- /dev/null +++ b/implementation/protocol/src/offered_services_request_command.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/offered_services_request_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offered_services_request_command::offered_services_request_command() + : command(id_e::OFFERED_SERVICES_REQUEST_ID) { +} + +void +offered_services_request_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(offer_type_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(offer_type_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &offer_type_, + sizeof(offer_type_)); +} + +void +offered_services_request_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(offer_type_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&offer_type_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(offer_type_)); +} + +offer_type_e +offered_services_request_command::get_offer_type() const { + + return (offer_type_); +} + +void +offered_services_request_command::set_offer_type(offer_type_e _offer_type) { + + offer_type_ = _offer_type; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offered_services_response_command.cpp b/implementation/protocol/src/offered_services_response_command.cpp new file mode 100644 index 000000000..bc8df95a3 --- /dev/null +++ b/implementation/protocol/src/offered_services_response_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/offered_services_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offered_services_response_command::offered_services_response_command() + : multiple_services_command_base(id_e::OFFERED_SERVICES_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/ping_command.cpp b/implementation/protocol/src/ping_command.cpp new file mode 100644 index 000000000..fab227b55 --- /dev/null +++ b/implementation/protocol/src/ping_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/ping_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +ping_command::ping_command() + : simple_command(id_e::PING_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/pong_command.cpp b/implementation/protocol/src/pong_command.cpp new file mode 100644 index 000000000..8be1e90c6 --- /dev/null +++ b/implementation/protocol/src/pong_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/pong_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +pong_command::pong_command() + : simple_command(id_e::PONG_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/register_application_command.cpp b/implementation/protocol/src/register_application_command.cpp new file mode 100644 index 000000000..d8babc7f9 --- /dev/null +++ b/implementation/protocol/src/register_application_command.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/register_application_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +register_application_command::register_application_command() + : command(id_e::REGISTER_APPLICATION_ID), + port_(ILLEGAL_PORT) { + +} + +void +register_application_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(port_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(port_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &port_, + sizeof(port_)); + +} + +void +register_application_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(port_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&port_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(port_)); +} + +port_t +register_application_command::get_port() const { + + return (port_); +} + +void +register_application_command::set_port(port_t _port) { + + port_ = _port; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/register_event.cpp b/implementation/protocol/src/register_event.cpp new file mode 100644 index 000000000..5be91b6a7 --- /dev/null +++ b/implementation/protocol/src/register_event.cpp @@ -0,0 +1,82 @@ +#include "../include/register_event.hpp" +#include + +namespace vsomeip_v3 { +namespace protocol { + +register_event::register_event(service_t service, instance_t instance, + event_t event, event_type_e event_type, + bool is_provided, reliability_type_e reliability, + bool is_cyclic, uint16_t num_eventg, + const std::set &eventgroups): + service_(service), instance_(instance), event_(event), + event_type_(event_type), is_provided_(is_provided), + reliability_(reliability), is_cyclic_(is_cyclic), + num_eventg_(num_eventg), eventgroups_(eventgroups) { +} + +void +register_event::serialize(std::vector &_buffer, size_t &_offset) const { + + std::memcpy(&_buffer[_offset], &service_, sizeof(service_)); + _offset += sizeof(service_); + std::memcpy(&_buffer[_offset], &instance_, sizeof(instance_)); + _offset += sizeof(instance_); + std::memcpy(&_buffer[_offset], &event_, sizeof(event_)); + _offset += sizeof(event_); + _buffer[_offset] = static_cast(event_type_); + _offset += sizeof(event_type_); + _buffer[_offset] = static_cast(is_provided_); + _offset += sizeof(is_provided_); + _buffer[_offset] = static_cast(reliability_); + _offset += sizeof(reliability_); + _buffer[_offset] = static_cast(is_cyclic_); + _offset += sizeof(is_cyclic_); + std::memcpy(&_buffer[_offset], &num_eventg_, sizeof(num_eventg_)); + _offset += sizeof(num_eventg_); + + for (const auto g : eventgroups_) { + std::memcpy(&_buffer[_offset], &g, sizeof(g)); + _offset += sizeof(g); + } +} + +void +register_event::deserialize(const std::vector &_buffer, size_t &_offset) { + + std::memcpy(&service_, &_buffer[_offset], sizeof(service_)); + _offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[_offset], sizeof(instance_)); + _offset += sizeof(instance_); + std::memcpy(&event_, &_buffer[_offset], sizeof(event_)); + _offset += sizeof(event_); + event_type_ = static_cast(_buffer[_offset]); + _offset += sizeof(event_type_); + is_provided_ = static_cast(_buffer[_offset]); + _offset += sizeof(is_provided_); + reliability_ = static_cast(_buffer[_offset]); + _offset += sizeof(reliability_); + is_cyclic_ = static_cast(_buffer[_offset]); + _offset += sizeof(is_cyclic_); + std::memcpy(&num_eventg_, &_buffer[_offset], sizeof(num_eventg_)); + _offset += sizeof(num_eventg_); + + eventgroups_.clear(); + for (size_t i = 0; i < num_eventg_; i++) { + eventgroup_t its_g; + std::memcpy(&its_g, &_buffer[_offset], sizeof(its_g)); + _offset += sizeof(its_g); + + eventgroups_.insert(its_g); + } +} + +void +register_event::set_eventgroups(const std::set &_eventgroups) { + + eventgroups_ = _eventgroups; + num_eventg_ = (uint16_t)eventgroups_.size(); +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/register_events_command.cpp b/implementation/protocol/src/register_events_command.cpp new file mode 100644 index 000000000..830e22312 --- /dev/null +++ b/implementation/protocol/src/register_events_command.cpp @@ -0,0 +1,110 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/register_events_command.hpp" +#include + +namespace vsomeip_v3 { +namespace protocol { + +register_events_command::register_events_command() + : command(id_e::REGISTER_EVENT_ID) { +} + +bool +register_events_command::add_registration(const register_event &_register_event) { + + size_t its_size(size_ + COMMAND_HEADER_SIZE + + sizeof(_register_event.get_service()) + sizeof(_register_event.get_instance()) + + sizeof(_register_event.get_event()) + sizeof(_register_event.get_event_type()) + + sizeof(_register_event.is_provided()) + sizeof(_register_event.get_reliability()) + + sizeof(_register_event.is_cyclic()) + sizeof(_register_event.get_num_eventgroups()) + + (_register_event.get_num_eventgroups() * sizeof(eventgroup_t) )); + if (its_size > std::numeric_limits::max()) { + return false; + } else { + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + registrations_.push_back(_register_event); + } + return true; +} + +void +register_events_command::serialize(std::vector &_buffer, error_e &_error) const { + + if (size_ + COMMAND_HEADER_SIZE> std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(size_+COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + for(auto ® : registrations_) { + reg.serialize(_buffer, its_offset); + } +} + +void +register_events_command::deserialize(const std::vector &_buffer, error_e &_error) { + registrations_.clear(); + + if(_buffer.size() < COMMAND_HEADER_SIZE) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + size_t its_offset(COMMAND_HEADER_SIZE); + + while(its_offset < _buffer.size()) { + size_t its_size(its_offset+ sizeof(service_t) + sizeof(instance_t) + + sizeof(event_t) + sizeof(event_type_e) + + sizeof(bool) + sizeof(bool) + sizeof(bool) + sizeof(uint16_t) + + sizeof(eventgroup_t)); // at least one is needed + if (its_size > _buffer.size()) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + register_event event_command; + event_command.deserialize(_buffer, its_offset); + registrations_.push_back(event_command); + } +} + +std::size_t +register_events_command::get_num_registrations() const { + + return registrations_.size(); +} + +bool +register_events_command::get_registration_at(std::size_t _position, register_event & _reg) const { + + if(_position < registrations_.size()) { + _reg = registrations_[_position]; + return true; + } + return false; +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/registered_ack_command.cpp b/implementation/protocol/src/registered_ack_command.cpp new file mode 100644 index 000000000..a9df5d3f7 --- /dev/null +++ b/implementation/protocol/src/registered_ack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/registered_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +registered_ack_command::registered_ack_command() + : simple_command(id_e::REGISTERED_ACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/release_service_command.cpp b/implementation/protocol/src/release_service_command.cpp new file mode 100644 index 000000000..41475ec10 --- /dev/null +++ b/implementation/protocol/src/release_service_command.cpp @@ -0,0 +1,101 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/release_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +release_service_command::release_service_command() + : command(id_e::RELEASE_SERVICE_ID) { + +} + +void +release_service_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service::service_) + sizeof(service::instance_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_.service_, sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&_buffer[its_offset], &service_.instance_, sizeof(service_.instance_)); +} + +void +release_service_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service::service_) + sizeof(service::instance_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_.service_, &_buffer[its_offset], + sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&service_.instance_, &_buffer[its_offset], + sizeof(service_.instance_)); +} + +service_t +release_service_command::get_service() const { + + return (service_.service_); +} + +void +release_service_command::set_service(service_t _service) { + + service_.service_ = _service; +} + +instance_t +release_service_command::get_instance() const { + + return (service_.instance_); +} + +void +release_service_command::set_instance(instance_t _instance) { + + service_.instance_ = _instance; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/remove_security_policy_command.cpp b/implementation/protocol/src/remove_security_policy_command.cpp new file mode 100644 index 000000000..acf8aeda9 --- /dev/null +++ b/implementation/protocol/src/remove_security_policy_command.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/remove_security_policy_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +remove_security_policy_command::remove_security_policy_command() + : command(id_e::REMOVE_SECURITY_POLICY_ID) { +} + +void +remove_security_policy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_) + + sizeof(uid_) + sizeof(gid_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&_buffer[its_offset], &uid_, sizeof(uid_)); + its_offset += sizeof(uid_); + std::memcpy(&_buffer[its_offset], &gid_, sizeof(gid_)); +} + +void +remove_security_policy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) + + sizeof(uid_) + sizeof(gid_t) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&update_id_, &_buffer[its_offset], sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&uid_, &_buffer[its_offset], sizeof(uid_)); + its_offset += sizeof(uid_); + std::memcpy(&gid_, &_buffer[its_offset], sizeof(gid_)); +} + +uint32_t +remove_security_policy_command::get_update_id() const { + + return (update_id_); +} + +void +remove_security_policy_command::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + + +uid_t +remove_security_policy_command::get_uid() const { + + return (uid_); +} + +void +remove_security_policy_command::set_uid(uid_t _uid) { + + uid_ = _uid; +} + +gid_t +remove_security_policy_command::get_gid() const { + + return (gid_); +} + +void +remove_security_policy_command::set_gid(gid_t _gid) { + + gid_ = _gid; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/remove_security_policy_response_command.cpp b/implementation/protocol/src/remove_security_policy_response_command.cpp new file mode 100644 index 000000000..ce8ab0b28 --- /dev/null +++ b/implementation/protocol/src/remove_security_policy_response_command.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/remove_security_policy_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +remove_security_policy_response_command::remove_security_policy_response_command() + : security_policy_response_command_base( + id_e::REMOVE_SECURITY_POLICY_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/request_service_command.cpp b/implementation/protocol/src/request_service_command.cpp new file mode 100644 index 000000000..c98f8eb22 --- /dev/null +++ b/implementation/protocol/src/request_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/request_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +request_service_command::request_service_command() + : multiple_services_command_base(id_e::REQUEST_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/resend_provided_events_command.cpp b/implementation/protocol/src/resend_provided_events_command.cpp new file mode 100644 index 000000000..929a43457 --- /dev/null +++ b/implementation/protocol/src/resend_provided_events_command.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/resend_provided_events_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +resend_provided_events_command::resend_provided_events_command() + : command(id_e::RESEND_PROVIDED_EVENTS_ID) { + +} + +void +resend_provided_events_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(remote_offer_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(remote_offer_id_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &remote_offer_id_, + sizeof(remote_offer_id_)); +} + +void +resend_provided_events_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(remote_offer_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&remote_offer_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(remote_offer_id_)); +} + +pending_remote_offer_id_t +resend_provided_events_command::get_remote_offer_id() const { + + return (remote_offer_id_); +} + +void +resend_provided_events_command::set_remote_offer_id( + pending_remote_offer_id_t _remote_offer_id) { + + remote_offer_id_ = _remote_offer_id; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/routing_info_command.cpp b/implementation/protocol/src/routing_info_command.cpp new file mode 100644 index 000000000..ae2747f60 --- /dev/null +++ b/implementation/protocol/src/routing_info_command.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/routing_info_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +routing_info_command::routing_info_command() + : command(id_e::ROUTING_INFO_ID) { + +} + +void +routing_info_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE); + for (const auto &e : entries_) + its_size += e.get_size(); + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t _index(COMMAND_HEADER_SIZE); + for (const auto &e : entries_) { + e.serialize(_buffer, _index, _error); + if (_error != error_e::ERROR_OK) { + _buffer.clear(); + return; + } + } +} + +void +routing_info_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + + // deserialize payload + size_t its_index(COMMAND_HEADER_SIZE); + while (its_index < _buffer.size()) { + + routing_info_entry its_entry; + its_entry.deserialize(_buffer, its_index, _error); + + if (_error == error_e::ERROR_OK) + entries_.emplace_back(its_entry); + else + break; + } +} + +// specific +const std::vector & +routing_info_command::get_entries() const { + + return (entries_); +} + +void +routing_info_command::set_entries(std::vector &&_entries) { + + entries_ = std::move(_entries); +} + +void +routing_info_command::add_entry(const routing_info_entry &_entry) { + + entries_.push_back(_entry); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/routing_info_entry.cpp b/implementation/protocol/src/routing_info_entry.cpp new file mode 100644 index 000000000..1edb23b77 --- /dev/null +++ b/implementation/protocol/src/routing_info_entry.cpp @@ -0,0 +1,304 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include +#include + +#include "../include/routing_info_entry.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +routing_info_entry::routing_info_entry() + : type_(routing_info_entry_type_e::RIE_UNKNOWN), + port_(0) { + +} + +routing_info_entry::routing_info_entry(const routing_info_entry &_source) + : type_(_source.type_), + client_(_source.client_), + address_(_source.address_), + port_(_source.port_), + services_(_source.services_) { + +} + +void +routing_info_entry::serialize(std::vector &_buffer, + size_t &_index, error_e &_error) const { + + _buffer[_index] = static_cast(type_); + _index += sizeof(type_); + + // Size is overall size - size field - command type + size_t its_size = get_size() - sizeof(uint32_t) - 1; + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + uint32_t its_size32(static_cast(its_size)); + std::memcpy(&_buffer[_index], &its_size32, sizeof(its_size32)); + _index += sizeof(its_size32); + + uint32_t its_client_size(sizeof(client_)); + if (!address_.is_unspecified()) { + if (address_.is_v4()) { + its_client_size += uint32_t(sizeof(boost::asio::ip::address_v4::bytes_type) + + sizeof(port_)); + } else { + its_client_size += uint32_t(sizeof(boost::asio::ip::address_v6::bytes_type) + + sizeof(port_)); + } + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + std::memcpy(&_buffer[_index], &its_client_size, sizeof(its_client_size)); + _index += sizeof(its_client_size); + } + + std::memcpy(&_buffer[_index], &client_, sizeof(client_)); + _index += sizeof(client_); + + if (!address_.is_unspecified()) { + + if (address_.is_v4()) { + std::memcpy(&_buffer[_index], address_.to_v4().to_bytes().data(), + sizeof(boost::asio::ip::address_v4::bytes_type)); + _index += sizeof(boost::asio::ip::address_v4::bytes_type); + } else { + std::memcpy(&_buffer[_index], address_.to_v6().to_bytes().data(), + sizeof(boost::asio::ip::address_v6::bytes_type)); + _index += sizeof(boost::asio::ip::address_v6::bytes_type); + } + std::memcpy(&_buffer[_index], &port_, sizeof(port_)); + _index += sizeof(port_); + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + its_size = (services_.size() * + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + its_size32 = static_cast(its_size); + std::memcpy(&_buffer[_index], &its_size32, sizeof(its_size32)); + _index += sizeof(its_size32); + + for (const auto &s : services_) { + + std::memcpy(&_buffer[_index], &s.service_, sizeof(s.service_)); + _index += sizeof(s.service_); + std::memcpy(&_buffer[_index], &s.instance_, sizeof(s.instance_)); + _index += sizeof(s.instance_); + std::memcpy(&_buffer[_index], &s.major_, sizeof(s.major_)); + _index += sizeof(s.major_); + std::memcpy(&_buffer[_index], &s.minor_, sizeof(s.minor_)); + _index += sizeof(s.minor_); + } + } +} + +void +routing_info_entry::deserialize(const std::vector &_buffer, + size_t &_index, error_e &_error) { + + uint32_t its_size; + uint32_t its_client_size; + + if (_buffer.size() < _index + sizeof(type_) + sizeof(its_size) + + sizeof(client_)) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + type_ = static_cast(_buffer[_index++]); + if (type_ == routing_info_entry_type_e::RIE_UNKNOWN) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + std::memcpy(&its_size, &_buffer[_index], sizeof(its_size)); + _index += sizeof(its_size); + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + std::memcpy(&its_client_size, &_buffer[_index], sizeof(its_client_size)); + _index += sizeof(its_client_size); + } else { + its_client_size = its_size; + } + + std::memcpy(&client_, &_buffer[_index], sizeof(client_)); + _index += sizeof(client_); + + if (its_client_size > sizeof(client_)) { + + uint32_t its_address_size = its_client_size + - uint32_t(sizeof(client_t) + sizeof(port_)); + + if (its_address_size == sizeof(boost::asio::ip::address_v4::bytes_type)) { + + boost::asio::ip::address_v4::bytes_type its_array; + std::memcpy(&its_array, &_buffer[_index], its_array.size()); + address_ = boost::asio::ip::address_v4(its_array); + _index += its_array.size(); + + } else if (its_address_size == sizeof(boost::asio::ip::address_v6::bytes_type)) { + + boost::asio::ip::address_v6::bytes_type its_array; + std::memcpy(&its_array, &_buffer[_index], its_array.size()); + address_ = boost::asio::ip::address_v6(its_array); + _index += its_array.size(); + + } else { + + _error = error_e::ERROR_MALFORMED; + return; + } + + std::memcpy(&port_, &_buffer[_index], sizeof(port_)); + _index += sizeof(port_); + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + if (_buffer.size() < _index + sizeof(its_size)) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + std::memcpy(&its_size, &_buffer[_index], sizeof(its_size)); + _index += sizeof(its_size); + + if (_buffer.size() < _index + its_size) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + size_t its_n = (its_size / + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + + for (size_t i = 0; i < its_n; i++) { + + service its_service; + std::memcpy(&its_service.service_, &_buffer[_index], sizeof(its_service.service_)); + _index += sizeof(its_service.service_); + std::memcpy(&its_service.instance_, &_buffer[_index], sizeof(its_service.instance_)); + _index += sizeof(its_service.instance_); + its_service.major_ = static_cast(_buffer[_index]); + _index += sizeof(its_service.major_); + std::memcpy(&its_service.minor_, &_buffer[_index], sizeof(its_service.minor_)); + _index += sizeof(its_service.minor_); + + services_.emplace_back(its_service); + } + } +} + +routing_info_entry_type_e +routing_info_entry::get_type() const { + + return (type_); +} + +void +routing_info_entry::set_type(routing_info_entry_type_e _type) { + + type_ = _type; +} + +size_t +routing_info_entry::get_size() const { + + size_t its_size(ROUTING_INFO_ENTRY_HEADER_SIZE); + + if (!address_.is_unspecified()) { + if (address_.is_v4()) { + its_size += (sizeof(boost::asio::ip::address_v4::bytes_type) + + sizeof(port_)); + } else { + its_size += (sizeof(boost::asio::ip::address_v6::bytes_type) + + sizeof(port_)); + } + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + its_size += sizeof(uint32_t); // size of the client info + its_size += sizeof(uint32_t); // size of the services array + its_size += (services_.size() * + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + } + + return (its_size); +} + +client_t +routing_info_entry::get_client() const { + + return (client_); +} + +void +routing_info_entry::set_client(client_t _client) { + + client_ = _client; +} + +boost::asio::ip::address +routing_info_entry::get_address() const { + + return (address_); +} + +void +routing_info_entry::set_address(const boost::asio::ip::address &_address) { + + address_ = _address; +} + +port_t +routing_info_entry::get_port() const { + + return (port_); +} + +void +routing_info_entry::set_port(port_t _port) { + + port_ = _port; +} + +const std::vector & +routing_info_entry::get_services() const { + + return (services_); +} + +void +routing_info_entry::add_service(const service &_service) { + + services_.push_back(_service); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/security_policy_response_command_base.cpp b/implementation/protocol/src/security_policy_response_command_base.cpp new file mode 100644 index 000000000..2a4837a16 --- /dev/null +++ b/implementation/protocol/src/security_policy_response_command_base.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/security_policy_response_command_base.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +security_policy_response_command_base::security_policy_response_command_base( + id_e _id) + : command(_id) { +} + +void +security_policy_response_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); +} + +void +security_policy_response_command_base::deserialize( + const std::vector &_buffer, error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&update_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(update_id_)); +} + +uint32_t +security_policy_response_command_base::get_update_id() const { + + return (update_id_); +} + +void +security_policy_response_command_base::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/send_command.cpp b/implementation/protocol/src/send_command.cpp new file mode 100644 index 000000000..7959744fa --- /dev/null +++ b/implementation/protocol/src/send_command.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/send_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +send_command::send_command(id_e _id) + : command(_id) { +} + +instance_t +send_command::get_instance() const { + + return instance_; +} + +void +send_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +bool +send_command::is_reliable() const { + + return is_reliable_; +} + +void +send_command::set_reliable(bool _is_reliable) { + + is_reliable_ = _is_reliable; +} + +uint8_t +send_command::get_status() const { + + return status_; +} + +void +send_command::set_status(uint8_t _status) { + + status_ = _status; +} + +client_t +send_command::get_target() const { + + return target_; +} + +void +send_command::set_target(client_t _target) { + + target_ = _target; +} + +std::vector +send_command::get_message() const { + + return message_; +} + +void +send_command::set_message(const std::vector &_message) { + + message_ = std::move(_message); +} + +void +send_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(instance_) + + sizeof(is_reliable_) + sizeof(status_) + + sizeof(target_) + message_.size()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + _buffer[its_offset] = static_cast(is_reliable_); + its_offset += sizeof(is_reliable_); + _buffer[its_offset] = static_cast(status_); + its_offset += sizeof(status_); + std::memcpy(&_buffer[its_offset], &target_, sizeof(target_)); + its_offset += sizeof(target_); + std::memcpy(&_buffer[its_offset], &message_[0], message_.size()); +} + +void +send_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(instance_) + + sizeof(is_reliable_) + sizeof(status_) + + sizeof(target_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + is_reliable_ = static_cast(_buffer[its_offset]); + its_offset += sizeof(is_reliable_); + status_ = static_cast(_buffer[its_offset]); + its_offset += sizeof(status_); + std::memcpy(&target_, &_buffer[its_offset], sizeof(target_)); + its_offset += sizeof(target_); + message_.resize(_buffer.size() - its_offset); + std::memcpy(&message_[0], &_buffer[its_offset], message_.size()); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/service_command_base.cpp b/implementation/protocol/src/service_command_base.cpp new file mode 100644 index 000000000..ae270f2e0 --- /dev/null +++ b/implementation/protocol/src/service_command_base.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +service_command_base::service_command_base(id_e _id) + : command(_id) { +} + +service_t +service_command_base::get_service() const { + + return service_.service_; +} + +void +service_command_base::set_service(service_t _service) { + + service_.service_ = _service; +} + +instance_t +service_command_base::get_instance() const { + + return service_.instance_; +} + +void +service_command_base::set_instance(instance_t _instance) { + + service_.instance_ = _instance; +} + +major_version_t +service_command_base::get_major() const { + + return service_.major_; +} + +void +service_command_base::set_major(major_version_t _major) { + + service_.major_ = _major; +} + +minor_version_t +service_command_base::get_minor() const { + + return service_.minor_; +} + +void +service_command_base::set_minor(minor_version_t _minor) { + + service_.minor_ = _minor; +} + +void +service_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_.service_) + sizeof(service_.instance_) + + sizeof(service_.major_) + sizeof(service_.minor_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_.service_, sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&_buffer[its_offset], &service_.instance_, sizeof(service_.instance_)); + its_offset += sizeof(service_.instance_); + _buffer[its_offset] = service_.major_; + its_offset += sizeof(service_.major_); + std::memcpy(&_buffer[its_offset], &service_.minor_, sizeof(service_.minor_)); +} + +void +service_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_.service_) + sizeof(service_.instance_) + + sizeof(service_.major_) + sizeof(service_.minor_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_.service_, &_buffer[its_offset], sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&service_.instance_, &_buffer[its_offset], sizeof(service_.instance_)); + its_offset += sizeof(service_.instance_); + service_.major_ = _buffer[its_offset]; + its_offset += sizeof(service_.major_); + std::memcpy(&service_.minor_, &_buffer[its_offset], sizeof(service_.minor_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/simple_command.cpp b/implementation/protocol/src/simple_command.cpp new file mode 100644 index 000000000..90760127a --- /dev/null +++ b/implementation/protocol/src/simple_command.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +simple_command::simple_command(id_e _id) + : command(_id) { + +} + +void +simple_command::serialize(std::vector &_buffer, + error_e &_error) const { + + // no size check as we know this is small enough + + // resize buffer + _buffer.resize(COMMAND_HEADER_SIZE); + + // set size + size_ = 0; + + // serialize header + command::serialize(_buffer, _error); +} + +void +simple_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/stop_offer_service_command.cpp b/implementation/protocol/src/stop_offer_service_command.cpp new file mode 100644 index 000000000..c12a20d57 --- /dev/null +++ b/implementation/protocol/src/stop_offer_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/stop_offer_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +stop_offer_service_command::stop_offer_service_command() + : service_command_base(id_e::STOP_OFFER_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_ack_command.cpp b/implementation/protocol/src/subscribe_ack_command.cpp new file mode 100644 index 000000000..12fe1cd49 --- /dev/null +++ b/implementation/protocol/src/subscribe_ack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/subscribe_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_ack_command::subscribe_ack_command() + : subscribe_ack_command_base(id_e::SUBSCRIBE_ACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_ack_command_base.cpp b/implementation/protocol/src/subscribe_ack_command_base.cpp new file mode 100644 index 000000000..2a8897232 --- /dev/null +++ b/implementation/protocol/src/subscribe_ack_command_base.cpp @@ -0,0 +1,174 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_ack_command_base::subscribe_ack_command_base(id_e _id) + : command(_id), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + subscriber_(0), + event_(ANY_EVENT), + pending_id_(0) { +} + +service_t +subscribe_ack_command_base::get_service() const { + + return service_; +} + +void +subscribe_ack_command_base::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +subscribe_ack_command_base::get_instance() const { + + return instance_; +} + +void +subscribe_ack_command_base::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +subscribe_ack_command_base::get_eventgroup() const { + + return eventgroup_; +} + +void +subscribe_ack_command_base::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +client_t +subscribe_ack_command_base::get_subscriber() const { + + return subscriber_; +} + +void +subscribe_ack_command_base::set_subscriber(client_t _subscriber) { + + subscriber_ = _subscriber; +} + +event_t +subscribe_ack_command_base::get_event() const { + + return event_; +} + +void +subscribe_ack_command_base::set_event(event_t _event) { + + event_ = _event; +} + +pending_id_t +subscribe_ack_command_base::get_pending_id() const { + + return pending_id_; +} + +void +subscribe_ack_command_base::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +subscribe_ack_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(subscriber_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &subscriber_, sizeof(subscriber_)); + its_offset += sizeof(subscriber_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +subscribe_ack_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(subscriber_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&subscriber_, &_buffer[its_offset], sizeof(subscriber_)); + its_offset += sizeof(subscriber_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_command.cpp b/implementation/protocol/src/subscribe_command.cpp new file mode 100644 index 000000000..89f19afd0 --- /dev/null +++ b/implementation/protocol/src/subscribe_command.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_command::subscribe_command() + : subscribe_command_base(id_e::SUBSCRIBE_ID) { +} + +std::shared_ptr +subscribe_command::get_filter() const { + + return filter_; +} + +void +subscribe_command::set_filter( + const std::shared_ptr &_filter) { + + filter_ = _filter; +} + +void +subscribe_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + size_t its_offset(its_size); + + if (filter_) { + its_size += sizeof(filter_->on_change_) + + sizeof(filter_->on_change_resets_interval_) + + sizeof(filter_->interval_) + + (filter_->ignore_.size() * (sizeof(size_t) + sizeof(byte_t))); + } + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + subscribe_command_base::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + if (filter_) { + + _buffer[its_offset] = static_cast(filter_->on_change_); + its_offset += sizeof(filter_->on_change_); + _buffer[its_offset] = static_cast(filter_->on_change_resets_interval_); + its_offset += sizeof(filter_->on_change_resets_interval_); + std::memcpy(&_buffer[its_offset], &filter_->interval_, sizeof(filter_->interval_)); + its_offset += sizeof(filter_->interval_); + for (const auto &its_ignore : filter_->ignore_) { + std::memcpy(&_buffer[its_offset], &its_ignore.first, sizeof(size_t)); + its_offset += sizeof(size_t); + _buffer[its_offset] = its_ignore.second; + its_offset += sizeof(byte_t); + } + } +} + +void +subscribe_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize subscription + subscribe_command_base::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize filter + size_t its_offset(its_size); + if (_buffer.size() - its_offset + >= sizeof(bool) + sizeof(bool) + sizeof(int64_t)) { + + filter_ = std::make_shared(); + std::memcpy(&filter_->on_change_, &_buffer[its_offset], sizeof(filter_->on_change_)); + its_offset += sizeof(filter_->on_change_); + std::memcpy(&filter_->on_change_resets_interval_, &_buffer[its_offset], sizeof(filter_->on_change_resets_interval_)); + its_offset += sizeof(filter_->on_change_resets_interval_); + std::memcpy(&filter_->interval_, &_buffer[its_offset], sizeof(filter_->interval_)); + its_offset += sizeof(filter_->interval_); + + while (_buffer.size() - its_offset + >= sizeof(size_t) + sizeof(byte_t)) { + + size_t its_key; + byte_t its_value; + + std::memcpy(&its_key, &_buffer[its_offset], sizeof(its_key)); + if (filter_->ignore_.find(its_key) != filter_->ignore_.end()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + its_offset += sizeof(its_key); + its_value = _buffer[its_offset]; + its_offset += sizeof(its_value); + + filter_->ignore_.emplace(std::make_pair(its_key, its_value)); + } + } +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_command_base.cpp b/implementation/protocol/src/subscribe_command_base.cpp new file mode 100644 index 000000000..cd5644a53 --- /dev/null +++ b/implementation/protocol/src/subscribe_command_base.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_command_base::subscribe_command_base(id_e _id) + : command(_id), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + major_(ANY_MAJOR), + event_(ANY_EVENT), + pending_id_(0) { +} + +service_t +subscribe_command_base::get_service() const { + + return service_; +} + +void +subscribe_command_base::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +subscribe_command_base::get_instance() const { + + return instance_; +} + +void +subscribe_command_base::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +subscribe_command_base::get_eventgroup() const { + + return eventgroup_; +} + +void +subscribe_command_base::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +major_version_t +subscribe_command_base::get_major() const { + + return major_; +} + +void +subscribe_command_base::set_major(major_version_t _major) { + + major_ = _major; +} + +event_t +subscribe_command_base::get_event() const { + + return event_; +} + +void +subscribe_command_base::set_event(event_t _event) { + + event_ = _event; +} + +pending_id_t +subscribe_command_base::get_pending_id() const { + + return pending_id_; +} + +void +subscribe_command_base::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +subscribe_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(instance_); + _buffer[its_offset] = major_; + its_offset += sizeof(major_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +subscribe_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + major_ = _buffer[its_offset]; + its_offset += sizeof(major_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_nack_command.cpp b/implementation/protocol/src/subscribe_nack_command.cpp new file mode 100644 index 000000000..b009dadbf --- /dev/null +++ b/implementation/protocol/src/subscribe_nack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/subscribe_nack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_nack_command::subscribe_nack_command() + : subscribe_ack_command_base(id_e::SUBSCRIBE_NACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/suspend_command.cpp b/implementation/protocol/src/suspend_command.cpp new file mode 100644 index 000000000..4f780f08e --- /dev/null +++ b/implementation/protocol/src/suspend_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/suspend_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +suspend_command::suspend_command() + : simple_command(id_e::SUSPEND_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/unregister_event_command.cpp b/implementation/protocol/src/unregister_event_command.cpp new file mode 100644 index 000000000..ff9813c31 --- /dev/null +++ b/implementation/protocol/src/unregister_event_command.cpp @@ -0,0 +1,135 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/unregister_event_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unregister_event_command::unregister_event_command() + : command(id_e::UNREGISTER_EVENT_ID), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + event_(ANY_EVENT), + is_provided_(false) { +} + +service_t +unregister_event_command::get_service() const { + + return service_; +} + +void +unregister_event_command::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +unregister_event_command::get_instance() const { + + return instance_; +} + +void +unregister_event_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +event_t +unregister_event_command::get_event() const { + + return event_; +} + +void +unregister_event_command::set_event(event_t _event) { + + event_ = _event; +} + + +bool +unregister_event_command::is_provided() const { + + return is_provided_; +} + +void +unregister_event_command::set_provided(bool _is_provided) { + + is_provided_ = _is_provided; +} + +void +unregister_event_command::serialize(std::vector &_buffer, error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(event_) + sizeof(is_provided_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + _buffer[its_offset] = static_cast(is_provided_); +} + +void +unregister_event_command::deserialize(const std::vector &_buffer, error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(event_) + sizeof(is_provided_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + is_provided_ = static_cast(_buffer[its_offset]); +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/unsubscribe_ack_command.cpp b/implementation/protocol/src/unsubscribe_ack_command.cpp new file mode 100644 index 000000000..ab7138d1f --- /dev/null +++ b/implementation/protocol/src/unsubscribe_ack_command.cpp @@ -0,0 +1,139 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/unsubscribe_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unsubscribe_ack_command::unsubscribe_ack_command() + : command(id_e::UNSUBSCRIBE_ACK_ID), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + pending_id_(0) { +} + +service_t +unsubscribe_ack_command::get_service() const { + + return service_; +} + +void +unsubscribe_ack_command::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +unsubscribe_ack_command::get_instance() const { + + return instance_; +} + +void +unsubscribe_ack_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +unsubscribe_ack_command::get_eventgroup() const { + + return eventgroup_; +} + +void +unsubscribe_ack_command::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +pending_id_t +unsubscribe_ack_command::get_pending_id() const { + + return pending_id_; +} + +void +unsubscribe_ack_command::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +unsubscribe_ack_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +unsubscribe_ack_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/unsubscribe_command.cpp b/implementation/protocol/src/unsubscribe_command.cpp new file mode 100644 index 000000000..247b301cc --- /dev/null +++ b/implementation/protocol/src/unsubscribe_command.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/unsubscribe_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unsubscribe_command::unsubscribe_command() + : subscribe_command_base(id_e::UNSUBSCRIBE_ID) { +} + +void +unsubscribe_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // payload + subscribe_command_base::serialize(_buffer, _error); +} + +void +unsubscribe_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + subscribe_command_base::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_credentials_command.cpp b/implementation/protocol/src/update_security_credentials_command.cpp new file mode 100644 index 000000000..3e69653c5 --- /dev/null +++ b/implementation/protocol/src/update_security_credentials_command.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/update_security_credentials_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_credentials_command::update_security_credentials_command() + : command(id_e::UPDATE_SECURITY_CREDENTIALS_ID) { +} + +void +update_security_credentials_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + (credentials_.size() * (sizeof(uid_t) + sizeof(gid_t)))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + for (const auto &c : credentials_) { + std::memcpy(&_buffer[its_offset], &c.first, sizeof(c.first)); + its_offset += sizeof(c.first); + std::memcpy(&_buffer[its_offset], &c.second, sizeof(c.second)); + its_offset += sizeof(c.second); + } +} + +void +update_security_credentials_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + if (COMMAND_HEADER_SIZE + size_ > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + size_t its_count(size_ / (sizeof(uid_t) + sizeof(gid_t))); + size_t its_offset(COMMAND_HEADER_SIZE); + + uid_t its_uid; + gid_t its_gid; + for (size_t i = 0; i < its_count; i++) { + std::memcpy(&its_uid, &_buffer[its_offset], sizeof(its_uid)); + its_offset += sizeof(its_uid); + std::memcpy(&its_gid, &_buffer[its_offset], sizeof(its_gid)); + its_offset += sizeof(its_gid); + + credentials_.emplace(std::make_pair(its_uid, its_gid)); + } +} + + +std::set > +update_security_credentials_command::get_credentials() const { + + return (credentials_); +} + +void +update_security_credentials_command::set_credentials( + const std::set > &_credentials) { + + credentials_ = _credentials; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_policy_command.cpp b/implementation/protocol/src/update_security_policy_command.cpp new file mode 100644 index 000000000..8ff79e2c8 --- /dev/null +++ b/implementation/protocol/src/update_security_policy_command.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/update_security_policy_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_policy_command::update_security_policy_command( + bool _is_internal) + : command(_is_internal ? + id_e::UPDATE_SECURITY_POLICY_INT_ID : + id_e::UPDATE_SECURITY_POLICY_ID) { +} + +void +update_security_policy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + std::vector its_policy_data; + if (policy_) { + if (policy_->serialize(its_policy_data)) { + _error = error_e::ERROR_UNKNOWN; + return; + } + } + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_) + + its_policy_data.size()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&_buffer[its_offset], + &its_policy_data[0], its_policy_data.size()); +} + +void +update_security_policy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&update_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(update_id_)); + policy_ = std::make_shared(); + const byte_t *its_policy_data + = &_buffer[COMMAND_HEADER_SIZE + sizeof(update_id_)]; + uint32_t its_policy_size + = uint32_t(_buffer.size() - COMMAND_HEADER_SIZE - sizeof(update_id_)); + + if (its_policy_size == 0 + || !policy_->deserialize(its_policy_data, its_policy_size)) { + + _error = error_e::ERROR_UNKNOWN; + policy_.reset(); + return; + } +} + +uint32_t +update_security_policy_command::get_update_id() const { + + return (update_id_); +} + +void +update_security_policy_command::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + +std::shared_ptr +update_security_policy_command::get_policy() const { + + return (policy_); +} + +void +update_security_policy_command::set_policy( + const std::shared_ptr &_policy) { + + policy_ = _policy; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_policy_response_command.cpp b/implementation/protocol/src/update_security_policy_response_command.cpp new file mode 100644 index 000000000..91573f0a7 --- /dev/null +++ b/implementation/protocol/src/update_security_policy_response_command.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/update_security_policy_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_policy_response_command::update_security_policy_response_command() + : security_policy_response_command_base( + id_e::UPDATE_SECURITY_POLICY_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index b22b6ed84..97adb893c 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -35,6 +34,8 @@ class message; class payload; class routing_manager; +struct debounce_filter_t; + class event : public std::enable_shared_from_this { public: @@ -52,16 +53,19 @@ class event event_t get_event() const; void set_event(event_t _event); - const std::shared_ptr get_payload() const; + std::shared_ptr get_payload() const; void set_payload(const std::shared_ptr &_payload, const client_t _client, bool _force); void set_payload(const std::shared_ptr &_payload, const client_t _client, - const std::shared_ptr& _target, bool _force); + const std::shared_ptr& _target); + + bool prepare_update_payload(const std::shared_ptr &_payload, + bool _force); + void update_payload(); - bool set_payload_dont_notify(const std::shared_ptr &_payload); bool set_payload_notify_pending(const std::shared_ptr &_payload); void set_payload(const std::shared_ptr &_payload, bool _force); @@ -90,20 +94,25 @@ class event void set_epsilon_change_function( const epsilon_change_func_t &_epsilon_change_func); - const std::set get_eventgroups() const; + std::set get_eventgroups() const; std::set get_eventgroups(client_t _client) const; void add_eventgroup(eventgroup_t _eventgroup); void set_eventgroups(const std::set &_eventgroups); void notify_one(client_t _client, const std::shared_ptr &_target); - void notify_one(client_t _client); + void notify_one(client_t _client, bool _force); - bool add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _force); + bool add_subscriber(eventgroup_t _eventgroup, + const std::shared_ptr &_filter, + client_t _client, bool _force); void remove_subscriber(eventgroup_t _eventgroup, client_t _client); bool has_subscriber(eventgroup_t _eventgroup, client_t _client); std::set get_subscribers(); + std::set get_filtered_subscribers(bool _force); + std::set update_and_get_filtered_subscribers( + const std::shared_ptr &_payload, bool _force); VSOMEIP_EXPORT std::set get_subscribers(eventgroup_t _eventgroup); void clear_subscribers(); @@ -122,30 +131,34 @@ class event void remove_pending(const std::shared_ptr &_target); + void set_session(); + private: void update_cbk(boost::system::error_code const &_error); - void notify(); + void notify(bool _force); void notify(client_t _client, const std::shared_ptr &_target); void start_cycle(); void stop_cycle(); - bool compare(const std::shared_ptr &_lhs, + bool has_changed(const std::shared_ptr &_lhs, const std::shared_ptr &_rhs) const; - bool set_payload_helper(const std::shared_ptr &_payload, - bool _force); - void reset_payload(const std::shared_ptr &_payload); - - void notify_one_unlocked(client_t _client); + void notify_one_unlocked(client_t _client, bool _force); void notify_one_unlocked(client_t _client, const std::shared_ptr &_target); + bool prepare_update_payload_unlocked( + const std::shared_ptr &_payload, bool _force); + void update_payload_unlocked(); + private: routing_manager *routing_; mutable std::mutex mutex_; - std::shared_ptr message_; + + std::shared_ptr current_; + std::shared_ptr update_; std::atomic type_; @@ -172,6 +185,11 @@ class event std::atomic reliability_; std::set > pending_; + + std::mutex filters_mutex_; + std::map filters_; + std::mutex last_forwarded_mutex_; + std::map last_forwarded_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 8ec1ac6a1..1a5a1b976 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -67,7 +67,7 @@ class eventgroupinfo { uint16_t _port); VSOMEIP_EXPORT bool is_sending_multicast() const; - VSOMEIP_EXPORT const std::set > get_events() const; + VSOMEIP_EXPORT std::set > get_events() const; VSOMEIP_EXPORT void add_event(const std::shared_ptr& _event); VSOMEIP_EXPORT void remove_event(const std::shared_ptr& _event); VSOMEIP_EXPORT reliability_type_e get_reliability() const; diff --git a/implementation/routing/include/function_types.hpp b/implementation/routing/include/function_types.hpp index 3f89c0868..f74ff37c2 100644 --- a/implementation/routing/include/function_types.hpp +++ b/implementation/routing/include/function_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,9 +10,8 @@ namespace vsomeip_v3 { class remote_subscription; -typedef std::function< - void (const std::shared_ptr &_subscription) -> remote_subscription_callback_t; +using remote_subscription_callback_t = + std::function &_subscription)>; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp index ff94d5b1d..f5bf2a210 100644 --- a/implementation/routing/include/remote_subscription.hpp +++ b/implementation/routing/include/remote_subscription.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -100,7 +100,6 @@ class remote_subscription { std::weak_ptr eventgroupinfo_; - major_version_t major_; ttl_t ttl_; std::uint16_t reserved_; std::uint8_t counter_; diff --git a/implementation/routing/include/routing_host.hpp b/implementation/routing/include/routing_host.hpp index 337e4a736..1decea3b6 100644 --- a/implementation/routing/include/routing_host.hpp +++ b/implementation/routing/include/routing_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,6 +11,7 @@ #include #include +#include #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" @@ -28,15 +29,19 @@ class routing_host { virtual void on_message(const byte_t *_data, length_t _length, endpoint *_receiver, - const boost::asio::ip::address &_destination = - boost::asio::ip::address(), + bool _is_multicast = false, client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, + const vsomeip_sec_client_t *_sec_client = nullptr, const boost::asio::ip::address &_remote_address = boost::asio::ip::address(), std::uint16_t _remote_port = 0) = 0; virtual client_t get_client() const = 0; + virtual void add_known_client(client_t _client, const std::string &_client_host) = 0; + + virtual void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index fa0e675e5..6fa769375 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,11 +10,19 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include #include #include +#include + #include "types.hpp" namespace vsomeip_v3 { @@ -30,10 +38,12 @@ class routing_manager { virtual ~routing_manager() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual client_t get_client() const = 0; - virtual void set_client(const client_t &_client) = 0; - virtual session_t get_session() = 0; +// virtual void set_client(const client_t &_client) = 0; + virtual session_t get_session(bool _is_request) = 0; + + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; virtual void init() = 0; virtual void start() = 0; @@ -54,24 +64,29 @@ class routing_manager { virtual void release_service(client_t _client, service_t _service, instance_t _instance) = 0; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) = 0; - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0; + virtual void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event) = 0; - virtual bool send(client_t _client, std::shared_ptr _message) = 0; + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force) = 0; virtual bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false) = 0; + const vsomeip_sec_client_t *_sec_client = nullptr, + uint8_t _status_check = 0, + bool _sent_from_remote = false, + bool _force = true) = 0; virtual bool send_to(const client_t _client, const std::shared_ptr &_target, - std::shared_ptr) = 0; + std::shared_ptr _message) = 0; virtual bool send_to(const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, instance_t _instance) = 0; diff --git a/implementation/routing/include/routing_manager_adapter.hpp b/implementation/routing/include/routing_manager_adapter.hpp index a2195ee14..26154b092 100644 --- a/implementation/routing/include/routing_manager_adapter.hpp +++ b/implementation/routing/include/routing_manager_adapter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp index 270f4c40a..e4f9073d1 100644 --- a/implementation/routing/include/routing_manager_base.hpp +++ b/implementation/routing/include/routing_manager_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,16 +12,19 @@ #include #include +#include -#include "routing_host.hpp" -#include "routing_manager.hpp" -#include "routing_manager_host.hpp" #include "types.hpp" -#include "serviceinfo.hpp" #include "event.hpp" +#include "serviceinfo.hpp" +#include "routing_host.hpp" #include "eventgroupinfo.hpp" +#include "routing_manager.hpp" +#include "routing_manager_host.hpp" + #include "../../message/include/serializer.hpp" #include "../../message/include/deserializer.hpp" +#include "../../protocol/include/protocol.hpp" #include "../../configuration/include/configuration.hpp" #include "../../endpoints/include/endpoint_manager_base.hpp" @@ -43,10 +46,19 @@ class routing_manager_base : public routing_manager, routing_manager_base(routing_manager_host *_host); virtual ~routing_manager_base() = default; - virtual boost::asio::io_service & get_io(); + virtual boost::asio::io_context &get_io(); virtual client_t get_client() const; + + virtual std::string get_client_host() const; + virtual void set_client_host(const std::string &_client_host); virtual void set_client(const client_t &_client); - virtual session_t get_session(); + virtual session_t get_session(bool _is_request); + + virtual const vsomeip_sec_client_t *get_sec_client() const; + + virtual std::string get_env(client_t _client) const = 0; + + virtual bool is_routing_manager() const; virtual void init() = 0; void init(const std::shared_ptr& _endpoint_manager); @@ -83,11 +95,14 @@ class routing_manager_base : public routing_manager, virtual std::set> find_events(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, + virtual void subscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event); + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, + virtual void unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); @@ -102,23 +117,22 @@ class routing_manager_base : public routing_manager, #endif ); - virtual bool send(client_t _client, std::shared_ptr _message); + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force); virtual bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false) = 0; + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force) = 0; // routing host -> will be implemented by routing_manager_impl/_proxy/ virtual void on_message(const byte_t *_data, length_t _length, - endpoint *_receiver, const boost::asio::ip::address &_destination - = boost::asio::ip::address(), client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - const boost::asio::ip::address &_remote_address = boost::asio::ip::address(), + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port = 0) = 0; - virtual void set_routing_state(routing_state_e _routing_state) = 0; virtual routing_state_e get_routing_state(); @@ -138,6 +152,17 @@ class routing_manager_base : public routing_manager, std::shared_ptr find_event(service_t _service, instance_t _instance, event_t _event) const; + // address data for vsomeip routing via TCP + bool get_guest(client_t _client, boost::asio::ip::address &_address, + port_t &_port) const; + void add_guest(client_t _client, const boost::asio::ip::address &_address, + port_t _port); + void remove_guest(client_t _client); + + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); + virtual void on_connect(const std::shared_ptr& _endpoint) = 0; virtual void on_disconnect(const std::shared_ptr& _endpoint) = 0; protected: @@ -150,10 +175,12 @@ class routing_manager_base : public routing_manager, services_t get_services_remote() const; bool is_available(service_t _service, instance_t _instance, major_version_t _major); - void remove_local(client_t _client, bool _remove_uid); + void remove_local(client_t _client, bool _remove_sec_client); void remove_local(client_t _client, - const std::set>& _subscribed_eventgroups, - bool _remove_uid); + const std::set< + std::tuple + > &_subscribed_eventgroups, + bool _remove_sec_client); std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; @@ -163,15 +190,16 @@ class routing_manager_base : public routing_manager, bool send_local_notification(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable = false, uint8_t _status_check = 0); + bool _reliable, uint8_t _status_check, bool _force); bool send_local( std::shared_ptr &_target, client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _command, uint8_t _status_check = 0) const; + bool _reliable, protocol::id_e _command, uint8_t _status_check) const; bool insert_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _event, client_t _client, + eventgroup_t _eventgroup, event_t _event, + const std::shared_ptr &_filter, client_t _client, std::set *_already_subscribed_events); std::shared_ptr get_serializer(); @@ -182,9 +210,10 @@ class routing_manager_base : public routing_manager, void send_pending_subscriptions(service_t _service, instance_t _instance, major_version_t _major); - virtual void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) = 0; void remove_pending_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); @@ -209,9 +238,11 @@ class routing_manager_base : public routing_manager, bool is_response_allowed(client_t _sender, service_t _service, instance_t _instance, method_t _method); - bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, + bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); - void unsubscribe_all(service_t _service, instance_t _instance); + + void add_known_client(client_t _client, const std::string &_client_host); #ifdef VSOMEIP_ENABLE_COMPAT void set_incoming_subscription_state(client_t _client, service_t _service, instance_t _instance, @@ -227,12 +258,12 @@ class routing_manager_base : public routing_manager, private: virtual bool create_placeholder_event_and_subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client) = 0; + event_t _event, const std::shared_ptr &_filter, + client_t _client) = 0; protected: routing_manager_host *host_; - boost::asio::io_service &io_; - std::atomic client_; + boost::asio::io_context &io_; std::shared_ptr configuration_; @@ -245,8 +276,9 @@ class routing_manager_base : public routing_manager, std::condition_variable deserializer_condition_; mutable std::mutex local_services_mutex_; - typedef std::map>> local_services_map_t; + using local_services_map_t = + std::map>>; local_services_map_t local_services_; std::map > > local_services_history_; @@ -264,9 +296,6 @@ class routing_manager_base : public routing_manager, std::mutex event_registration_mutex_; - std::mutex routing_state_mutex_; - routing_state_e routing_state_; - #ifdef USE_DLT std::shared_ptr tc_; #endif @@ -277,8 +306,8 @@ class routing_manager_base : public routing_manager, eventgroup_t eventgroup_; major_version_t major_; event_t event_; - uid_t uid_; - gid_t gid_; + std::shared_ptr filter_; + vsomeip_sec_client_t sec_client_; bool operator<(const subscription_data_t &_other) const { return (service_ < _other.service_ @@ -300,13 +329,26 @@ class routing_manager_base : public routing_manager, std::shared_ptr ep_mgr_; - std::uint32_t own_uid_; - std::uint32_t own_gid_; + mutable std::mutex known_clients_mutex_; + std::map known_clients_; + + mutable std::mutex env_mutex_; + std::string env_; + + std::mutex routing_state_mutex_; + routing_state_e routing_state_; private: services_t services_; mutable std::mutex services_mutex_; + mutable std::mutex guests_mutex_; + std::map + > guests_; + + std::mutex add_known_client_mutex_; + #ifdef VSOMEIP_ENABLE_COMPAT std::map #include #include #include -#include #include -#include "routing_manager_base.hpp" -#include "types.hpp" #include #include +#include "routing_manager_base.hpp" +#include "types.hpp" +#include "../../protocol/include/protocol.hpp" + namespace vsomeip_v3 { class configuration; class event; +#ifdef __linux__ +class netlink_connector; +#endif class routing_manager_host; -class routing_manager_proxy: public routing_manager_base { +namespace protocol { + class offered_services_response_command; + class update_security_credentials_command; +} + +class routing_manager_client + : public routing_manager_base { public: - routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging, + routing_manager_client(routing_manager_host *_host, bool _client_side_logging, const std::set > & _client_side_logging_filter); - virtual ~routing_manager_proxy(); + virtual ~routing_manager_client(); void init(); void start(); void stop(); std::shared_ptr get_configuration() const; + std::string get_env(client_t _client) const; + std::string get_env_unlocked(client_t _client) const; bool offer_service(client_t _client, service_t _service, instance_t _instance, @@ -52,20 +64,20 @@ class routing_manager_proxy: public routing_manager_base { void release_service(client_t _client, service_t _service, instance_t _instance); - void subscribe(client_t _client, uid_t _uid, gid_t _gid, + void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event); + event_t _event, const std::shared_ptr &_filter); - void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, + void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false); + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force); bool send_to(const client_t _client, const std::shared_ptr &_target, @@ -91,9 +103,8 @@ class routing_manager_proxy: public routing_manager_base { void on_connect(const std::shared_ptr& _endpoint); void on_disconnect(const std::shared_ptr& _endpoint); void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); @@ -103,7 +114,7 @@ class routing_manager_proxy: public routing_manager_base { const std::shared_ptr &_endpoint); void handle_client_error(client_t _client); - void on_offered_services_info(const byte_t *_data, uint32_t _size); + void on_offered_services_info(protocol::offered_services_response_command &_command); void send_get_offered_services_info(client_t _client, offer_type_e _offer_type); @@ -112,23 +123,30 @@ class routing_manager_proxy: public routing_manager_base { void register_application(); void deregister_application(); - void reconnect(const std::unordered_set &_clients); + void reconnect(const std::map &_clients); void send_pong() const; + void send_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); + void send_release_service(client_t _client, service_t _service, instance_t _instance); + + void send_pending_event_registrations(client_t _client); + void send_register_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, const std::set &_eventgroups, const event_type_e _type, reliability_type_e _reliability, - bool _is_provided); - void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event); + bool _is_provided, bool _is_cyclic); + + void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); void send_subscribe_nack(client_t _subscriber, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, @@ -176,12 +194,13 @@ class routing_manager_proxy: public routing_manager_base { bool is_client_known(client_t _client); bool create_placeholder_event_and_subscribe( - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _notifier, client_t _client); + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _notifier, const std::shared_ptr &_filter, + client_t _client); void request_debounce_timeout_cbk(boost::system::error_code const &_error); - void send_request_services(std::set& _requests); + void send_request_services(const std::set &_requests); void send_unsubscribe_ack(service_t _service, instance_t _instance, eventgroup_t _eventgroup, remote_subscription_id_t _id); @@ -189,14 +208,23 @@ class routing_manager_proxy: public routing_manager_base { void resend_provided_event_registrations(); void send_resend_provided_event_response(pending_remote_offer_id_t _id); +#ifndef VSOMEIP_DISABLE_SECURITY void send_update_security_policy_response(pending_security_update_id_t _update_id); void send_remove_security_policy_response(pending_security_update_id_t _update_id); - void on_update_security_credentials(const byte_t *_data, uint32_t _size); + void on_update_security_credentials(const protocol::update_security_credentials_command &_command); +#endif void on_client_assign_ack(const client_t &_client); + port_t get_routing_port(); + void on_suspend(); +#if defined(__linux__) || defined(ANDROID) + void on_net_state_change(bool _is_interface, const std::string &_name, bool _is_available); +#endif + private: + enum class inner_state_type_e : std::uint8_t { ST_REGISTERED = 0x0, ST_DEREGISTERED = 0x1, @@ -212,12 +240,9 @@ class routing_manager_proxy: public routing_manager_base { std::shared_ptr sender_; // --> stub std::shared_ptr receiver_; // --> from everybody - std::mutex known_clients_mutex_; - std::unordered_set known_clients_; - - std::set pending_offers_; - std::set requests_; - std::set requests_to_debounce_; + std::set pending_offers_; + std::set requests_; + std::set requests_to_debounce_; struct event_data_t { service_t service_; @@ -226,19 +251,20 @@ class routing_manager_proxy: public routing_manager_base { event_type_e type_; reliability_type_e reliability_; bool is_provided_; + bool is_cyclic_; std::set eventgroups_; bool operator<(const event_data_t &_other) const { return std::tie(service_, instance_, notifier_, - type_, reliability_, is_provided_, eventgroups_) + type_, reliability_, is_provided_, is_cyclic_, eventgroups_) < std::tie(_other.service_, _other.instance_, _other.notifier_, _other.type_, _other.reliability_, - _other.is_provided_, _other.eventgroups_); + _other.is_provided_, _other.is_cyclic_, _other.eventgroups_); } }; std::set pending_event_registrations_; - std::map> pending_incoming_subscripitons_; + std::map> pending_incoming_subscriptions_; std::recursive_mutex incoming_subscriptions_mutex_; std::mutex state_mutex_; @@ -260,8 +286,13 @@ class routing_manager_proxy: public routing_manager_base { const std::set > client_side_logging_filter_; std::mutex stop_mutex_; + +#if defined(__linux__) || defined(ANDROID) + std::shared_ptr local_link_connector_; + bool is_local_link_available_; +#endif }; } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP_ +#endif // VSOMEIP_V3_ROUTING_MANAGER_CLIENT_HPP_ diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp index 69133e265..18a74afca 100644 --- a/implementation/routing/include/routing_manager_host.hpp +++ b/implementation/routing/include/routing_manager_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,9 +8,15 @@ #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include namespace vsomeip_v3 { @@ -24,22 +30,30 @@ class routing_manager_host { virtual client_t get_client() const = 0; virtual void set_client(const client_t &_client) = 0; - virtual session_t get_session() = 0; + virtual session_t get_session(bool _is_request) = 0; + + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; + virtual const std::string & get_name() const = 0; virtual std::shared_ptr get_configuration() const = 0; - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor = DEFAULT_MINOR) = 0; + availability_state_e _state, + major_version_t _major = DEFAULT_MAJOR, + minor_version_t _minor = DEFAULT_MINOR) = 0; virtual void on_state(state_type_e _state) = 0; virtual void on_message(std::shared_ptr &&_message) = 0; virtual void on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed, - std::function _accepted_cb) = 0; + eventgroup_t _eventgroup, + client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, + const std::function &_accepted_cb) = 0; virtual void on_subscription_status(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error) = 0; virtual void send(std::shared_ptr _message) = 0; - virtual void on_offered_services_info(std::vector> &_services) = 0; + virtual void on_offered_services_info( + std::vector> &_services) = 0; virtual bool is_routing() const = 0; }; diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 3fd6eed52..3c105c278 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -36,7 +35,6 @@ class deserializer; class eventgroupinfo; class routing_manager_host; class routing_manager_stub; -class servicegroup; class serializer; class service_endpoint; @@ -55,8 +53,13 @@ class routing_manager_impl: public routing_manager_base, routing_manager_impl(routing_manager_host *_host); ~routing_manager_impl(); - boost::asio::io_service & get_io(); + boost::asio::io_context &get_io(); client_t get_client() const; + const vsomeip_sec_client_t *get_sec_client() const; + std::string get_client_host() const; + void set_client_host(const std::string &_client_host); + + bool is_routing_manager() const; void init(); void start(); @@ -77,21 +80,23 @@ class routing_manager_impl: public routing_manager_base, void release_service(client_t _client, service_t _service, instance_t _instance); - void subscribe(client_t _client, uid_t _uid, gid_t _gid, + void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event); + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); - void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, + void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); - bool send(client_t _client, std::shared_ptr _message); + bool send(client_t _client, std::shared_ptr _message, + bool _force); bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false); + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force); bool send_to(const client_t _client, const std::shared_ptr &_target, @@ -120,7 +125,7 @@ class routing_manager_impl: public routing_manager_base, event_t _notifier, const std::set &_eventgroups, event_type_e _type, reliability_type_e _reliability, - bool _is_provided); + bool _is_provided, bool _is_cyclic); void unregister_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _event, @@ -140,7 +145,7 @@ class routing_manager_impl: public routing_manager_base, void on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _id, bool _simulated); + remote_subscription_id_t _id); // interface to stub @@ -161,7 +166,7 @@ class routing_manager_impl: public routing_manager_base, major_version_t _major, minor_version_t _minor); void on_availability(service_t _service, instance_t _instance, - bool _is_available, + availability_state_e _state, major_version_t _major, minor_version_t _minor); void on_pong(client_t _client); @@ -178,13 +183,13 @@ class routing_manager_impl: public routing_manager_base, void on_disconnect(const std::shared_ptr& _endpoint); void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, credentials_t _credentials, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); + bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); bool on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size, bool _reliable, - client_t _bound_client, credentials_t _credentials, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _check_status = 0, bool _is_from_remote = false); void on_notification(client_t _client, service_t _service, @@ -199,8 +204,6 @@ class routing_manager_impl: public routing_manager_base, bool _magic_cookies_enabled); // interface "service_discovery_host" - typedef std::map > servicegroups_t; - const servicegroups_t & get_servicegroups() const; std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; services_t get_offered_services() const; @@ -285,15 +288,27 @@ class routing_manager_impl: public routing_manager_base, void on_resend_provided_events_response(pending_remote_offer_id_t _id); client_t find_local_client(service_t _service, instance_t _instance); std::set find_local_clients(service_t _service, instance_t _instance); - bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, + bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); +#ifndef VSOMEIP_DISABLE_SECURITY bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler); bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, const security_update_handler_t &_handler); +#endif + + void add_known_client(client_t _client, const std::string &_client_host); + + void register_message_acceptance_handler( + const message_acceptance_handler_t &_handler); + + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); private: bool offer_service(client_t _client, @@ -307,12 +322,12 @@ class routing_manager_impl: public routing_manager_base, bool _must_queue); bool deliver_message(const byte_t *_data, length_t _size, - instance_t _instance, bool _reliable, client_t _bound_client, - credentials_t _credentials, + instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false); bool deliver_notification(service_t _service, instance_t _instance, - const byte_t *_data, length_t _length, bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _length, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false); @@ -351,38 +366,49 @@ class routing_manager_impl: public routing_manager_base, bool handle_local_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major,minor_version_t _minor); - void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event); + void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); void on_net_interface_or_route_state_changed(bool _is_interface, - std::string _if, + const std::string &_if, bool _available); void start_ip_routing(); - void requested_service_add(client_t _client, service_t _service, + void add_requested_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); - void requested_service_remove(client_t _client, service_t _service, - instance_t _instance); - - void call_sd_endpoint_connected(const boost::system::error_code& _error, - service_t _service, instance_t _instance, - const std::shared_ptr& _endpoint, - std::shared_ptr _timer); + void remove_requested_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + std::vector> get_requested_services(client_t _client); + std::set get_requesters(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + std::set get_requesters_unlocked(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + bool has_requester_unlocked(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + + void call_sd_endpoint_connected(const boost::system::error_code &_error, + service_t _service, instance_t _instance, + const std::shared_ptr &_endpoint, + std::shared_ptr _timer); - bool create_placeholder_event_and_subscribe(service_t _service, - instance_t _instance, - eventgroup_t _eventgroup, - event_t _event, - client_t _client); + bool create_placeholder_event_and_subscribe( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, const std::shared_ptr &_filter, + client_t _client); void handle_subscription_state(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); - void memory_log_timer_cbk(boost::system::error_code const & _error); - void status_log_timer_cbk(boost::system::error_code const & _error); + void memory_log_timer_cbk(boost::system::error_code const &_error); + void status_log_timer_cbk(boost::system::error_code const &_error); void send_subscription(const client_t _offering_client, const service_t _service, const instance_t _instance, @@ -416,25 +442,48 @@ class routing_manager_impl: public routing_manager_base, bool is_last_stop_callback(const uint32_t _callback_id); + std::string get_env(client_t _client) const; + std::string get_env_unlocked(client_t _client) const; + bool insert_event_statistics(service_t _service, instance_t _instance, method_t _method, length_t _length); void statistics_log_timer_cbk(boost::system::error_code const & _error); + bool get_guest(client_t _client, boost::asio::ip::address &_address, + port_t &_port) const; + void add_guest(client_t _client, const boost::asio::ip::address &_address, + port_t _port); + void remove_guest(client_t _client); + void send_suspend() const; + void clear_local_services(); + + bool is_acl_message_allowed(endpoint *_receiver, + service_t _service, instance_t _instance, + const boost::asio::ip::address &_remote_address) const; + private: std::shared_ptr stub_; std::shared_ptr discovery_; std::mutex requested_services_mutex_; - std::map>>>> requested_services_; + std::map > + > + > + > requested_services_; std::mutex remote_subscribers_mutex_; - std::map>>>> remote_subscribers_; + std::map > + > + > + > remote_subscribers_; std::shared_ptr sd_info_; @@ -446,7 +495,7 @@ class routing_manager_impl: public routing_manager_base, bool routing_running_; std::mutex pending_sd_offers_mutex_; std::vector> pending_sd_offers_; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) std::shared_ptr netlink_connector_; #endif @@ -503,6 +552,8 @@ class routing_manager_impl: public routing_manager_base, // synchronize update_remote_subscription() and send_(un)subscription() std::mutex update_remote_subscription_mutex_; + + message_acceptance_handler_t message_acceptance_handler_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index aa5796ef2..4209eec1f 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,22 +16,34 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include #include - -#include "../../endpoints/include/endpoint_host.hpp" -#include "../include/routing_host.hpp" +#include #include "types.hpp" +#include "../include/routing_host.hpp" +#include "../../endpoints/include/endpoint_host.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../protocol/include/routing_info_entry.hpp" namespace vsomeip_v3 { class configuration; -struct policy; +#if defined(__linux__) || defined(ANDROID) +class netlink_connector; +#endif // __linux__ || ANDROID class routing_manager_stub_host; +struct debounce_filter_t; +struct policy; + class routing_manager_stub: public routing_host, public std::enable_shared_from_this { public: @@ -44,10 +56,9 @@ class routing_manager_stub: public routing_host, void start(); void stop(); - void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + void on_message(const byte_t *_data, length_t _size, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); @@ -56,9 +67,11 @@ class routing_manager_stub: public routing_host, void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); - bool send_subscribe(const std::shared_ptr& _target, - client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event, + bool send_subscribe( + const std::shared_ptr &_target, client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter, remote_subscription_id_t _id); bool send_unsubscribe(const std::shared_ptr& _target, @@ -85,16 +98,18 @@ class routing_manager_stub: public routing_host, bool send_ping(client_t _client); bool is_registered(client_t _client) const; client_t get_client() const; - void handle_credentials(const client_t _client, std::set& _requests); - void handle_requests(const client_t _client, std::set& _requests); + void handle_credentials(const client_t _client, std::set &_requests); + void handle_requests(const client_t _client, std::set &_requests); - void update_registration(client_t _client, registration_type_e _type); + void update_registration(client_t _client, registration_type_e _type, + const boost::asio::ip::address &_address, port_t _port); void print_endpoint_status() const; bool send_provided_event_resend_request(client_t _client, pending_remote_offer_id_t _id); +#ifndef VSOMEIP_DISABLE_SECURITY bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, @@ -119,23 +134,29 @@ class routing_manager_stub: public routing_host, bool add_requester_policies(uid_t _uid, gid_t _gid, const std::set > &_policies); void remove_requester_policies(uid_t _uid, gid_t _gid); +#endif // !VSOMEIP_DISABLE_SECURITY + + void add_known_client(client_t _client, const std::string &_client_host); void send_suspend() const; + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); + private: void broadcast(const std::vector &_command) const; void on_register_application(client_t _client); void on_deregister_application(client_t _client); + void on_offered_service_request(client_t _client, offer_type_e _offer_type); + void distribute_credentials(client_t _hoster, service_t _service, instance_t _instance); - void inform_provider(client_t _hoster, service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry); void inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, - minor_version_t _minor, routing_info_entry_e _entry, + minor_version_t _minor, protocol::routing_info_entry_type_e _entry, bool _inform_service); void broadcast_ping() const; @@ -151,27 +172,35 @@ class routing_manager_stub: public routing_host, (void)_routing_state; }; - bool is_already_connected(client_t _source, client_t _sink); - void create_client_routing_info(const client_t _target); - void insert_client_routing_info(client_t _target, routing_info_entry_e _entry, - client_t _client, service_t _service = ANY_SERVICE, - instance_t _instance = ANY_INSTANCE, - major_version_t _major = ANY_MAJOR, - minor_version_t _minor = ANY_MINOR); - void send_client_routing_info(const client_t _target); - - void create_offered_services_info(const client_t _target); - void insert_offered_services_info(client_t _target, - routing_info_entry_e _entry, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor); - void send_offered_services_info(const client_t _target); - - void create_client_credentials_info(const client_t _target); - void insert_client_credentials_info(client_t _target, std::set> _credentials); - void send_client_credentials_info(const client_t _target); + inline bool is_connected(client_t _source, client_t _sink) const { + + auto find_source = connection_matrix_.find(_source); + if (find_source != connection_matrix_.end()) + return (find_source->second.find(_sink) + != find_source->second.end()); + + return (false); + } + inline void add_connection(client_t _source, client_t _sink) { + + connection_matrix_[_source].insert(_sink); + } + inline void remove_connection(client_t _source, client_t _sink) { + + auto find_source = connection_matrix_.find(_source); + if (find_source != connection_matrix_.end()) + find_source->second.erase(_sink); + } + inline void remove_source(client_t _source) { + + connection_matrix_.erase(_source); + } + + void send_client_routing_info(const client_t _target, + protocol::routing_info_entry &_entry); + void send_client_routing_info(const client_t _target, + std::vector &&_entries); + void send_client_credentials(client_t _target, std::set> &_credentials); void on_client_id_timer_expired(boost::system::error_code const &_error); @@ -199,13 +228,17 @@ class routing_manager_stub: public routing_host, void add_pending_security_update_handler( pending_security_update_id_t _id, - security_update_handler_t _handler); + const security_update_handler_t &_handler); void add_pending_security_update_timer( pending_security_update_id_t _id); +#if defined(__linux__) || defined(ANDROID) + void on_net_state_change(bool _is_interface, const std::string &_name, bool _is_available); +#endif + private: routing_manager_stub_host *host_; - boost::asio::io_service &io_; + boost::asio::io_context &io_; std::mutex watchdog_timer_mutex_; boost::asio::steady_timer watchdog_timer_; @@ -213,7 +246,8 @@ class routing_manager_stub: public routing_host, std::set used_client_ids_; std::mutex used_client_ids_mutex_; - std::shared_ptr endpoint_; + std::shared_ptr root_; // Routing manager endpoint + std::shared_ptr local_receiver_; std::mutex local_receiver_mutex_; @@ -229,8 +263,8 @@ class routing_manager_stub: public routing_host, std::condition_variable client_registration_condition_; std::map> pending_client_registrations_; + std::map > internal_client_ports_; const std::uint32_t max_local_message_size_; - static const std::vector its_ping_; const std::chrono::milliseconds configured_watchdog_timeout_; boost::asio::steady_timer pinged_clients_timer_; std::mutex pinged_clients_mutex_; @@ -239,10 +273,6 @@ class routing_manager_stub: public routing_host, std::map > > > service_requests_; std::map> connection_matrix_; - std::map> client_routing_info_; - std::map> offered_services_info_; - std::map> client_credentials_info_; - std::mutex pending_security_updates_mutex_; pending_security_update_id_t pending_security_update_id_; std::map> pending_security_updates_; @@ -262,6 +292,14 @@ class routing_manager_stub: public routing_host, std::set > > > requester_policies_; + + +#if defined(__linux__) || defined(ANDROID) + // netlink connector for internal network + // (replacement for Unix Domain Sockets if configured) + std::shared_ptr local_link_connector_; + bool is_local_link_available_; +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp index 6ad0ab15b..c55dd86bd 100644 --- a/implementation/routing/include/routing_manager_stub_host.hpp +++ b/implementation/routing/include/routing_manager_stub_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,9 +6,16 @@ #ifndef VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ #define VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include + #include "types.hpp" namespace vsomeip_v3 { @@ -28,57 +35,59 @@ class routing_manager_stub_host { instance_t _instance, major_version_t _major, minor_version_t _minor, bool _must_queue = true) = 0; - virtual void request_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) = 0; + virtual void request_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor) = 0; - virtual void release_service(client_t _client, - service_t _service, instance_t _instance) = 0; + virtual void release_service(client_t _client, service_t _service, + instance_t _instance) = 0; - virtual void register_shadow_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, - event_type_e _type, reliability_type_e _reliability, - bool _is_provided) = 0; + virtual void register_shadow_event(client_t _client, service_t _service, + instance_t _instance, event_t _notifier, + const std::set &_eventgroups, event_type_e _type, + reliability_type_e _reliability, bool _is_provided, + bool _is_cyclic) = 0; virtual void unregister_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _event, bool _is_provided) = 0; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, event_t _event, + const std::shared_ptr &_filter) = 0; virtual void on_subscribe_nack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _subscription_id, bool _simulated) = 0; + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _subscription_id) = 0; virtual void on_subscribe_ack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _subscription_id) = 0; + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _subscription_id) = 0; - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0; + virtual void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) = 0; virtual void on_unsubscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, remote_subscription_id_t _unsubscription_id) = 0; virtual bool on_message(service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _size, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false) = 0; - virtual void on_notification(client_t _client, - service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, bool _notify_one = false) = 0; + virtual void on_notification(client_t _client, service_t _service, + instance_t _instance, const byte_t *_data, length_t _size, + bool _notify_one = false) = 0; virtual void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) = 0; virtual void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) = 0; + availability_state_e _state, major_version_t _major, + minor_version_t _minor) = 0; virtual std::shared_ptr find_local(client_t _client) = 0; @@ -86,8 +95,9 @@ class routing_manager_stub_host { client_t _client) = 0; virtual void remove_local(client_t _client, bool _remove_local) = 0; - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context& get_io() = 0; virtual client_t get_client() const = 0; + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; virtual void on_pong(client_t _client) = 0; @@ -95,14 +105,32 @@ class routing_manager_stub_host { virtual std::shared_ptr get_endpoint_manager() const = 0; - virtual void on_resend_provided_events_response(pending_remote_offer_id_t _id) = 0; + virtual void on_resend_provided_events_response( + pending_remote_offer_id_t _id) = 0; + + virtual client_t find_local_client(service_t _service, + instance_t _instance) = 0; + + virtual std::set find_local_clients(service_t _service, + instance_t _instance) = 0; + + virtual bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, + client_t _client, service_t _service, instance_t _instance, + eventgroup_t _eventgroup) = 0; + + virtual void add_known_client(client_t _client, + const std::string &_client_host) = 0; - virtual client_t find_local_client(service_t _service, instance_t _instance) = 0; + virtual void set_client_host(const std::string &_client_host) = 0; - virtual std::set find_local_clients(service_t _service, instance_t _instance) = 0; + virtual bool get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const = 0; + virtual void add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) = 0; + virtual void remove_guest(client_t _client) = 0; - virtual bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0; + virtual void clear_local_services() = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp index a405cf057..5ea4c185c 100644 --- a/implementation/routing/include/serviceinfo.hpp +++ b/implementation/routing/include/serviceinfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,7 +18,6 @@ namespace vsomeip_v3 { class endpoint; -class servicegroup; class serviceinfo { public: @@ -28,9 +27,6 @@ class serviceinfo { VSOMEIP_EXPORT serviceinfo(const serviceinfo& _other); VSOMEIP_EXPORT ~serviceinfo(); - VSOMEIP_EXPORT servicegroup * get_group() const; - VSOMEIP_EXPORT void set_group(servicegroup *_group); - VSOMEIP_EXPORT service_t get_service() const; VSOMEIP_EXPORT instance_t get_instance() const; @@ -57,8 +53,6 @@ class serviceinfo { VSOMEIP_EXPORT void set_is_in_mainphase(bool _in_mainphase); private: - servicegroup *group_; - service_t service_; instance_t instance_; diff --git a/implementation/routing/include/types.hpp b/implementation/routing/include/types.hpp index c301b33c4..d59015cb9 100644 --- a/implementation/routing/include/types.hpp +++ b/implementation/routing/include/types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,18 +18,13 @@ namespace vsomeip_v3 { class serviceinfo; class endpoint_definition; - -typedef std::map > > services_t; +using services_t = std::map>>; class eventgroupinfo; -typedef std::map > > > eventgroups_t; +using eventgroups_t = + std::map>>>; enum class registration_type_e : std::uint8_t { REGISTER = 0x1, @@ -47,8 +42,7 @@ enum class remote_subscription_state_e : std::uint8_t { SUBSCRIPTION_UNKNOWN = 0xFF }; -typedef std::uint16_t remote_subscription_id_t; -typedef std::uint32_t pending_remote_offer_id_t; +using remote_subscription_id_t = std::uint16_t; struct msg_statistic_t { uint32_t counter_; diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index b63022c10..e4eed17d0 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -1,10 +1,12 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include #include #include +#include #include #include @@ -21,72 +23,104 @@ namespace vsomeip_v3 { -event::event(routing_manager *_routing, bool _is_shadow) : - routing_(_routing), - message_(runtime::get()->create_notification()), - type_(event_type_e::ET_EVENT), - cycle_timer_(_routing->get_io()), - cycle_(std::chrono::milliseconds::zero()), - change_resets_cycle_(false), - is_updating_on_change_(true), - is_set_(false), - is_provided_(false), - is_shadow_(_is_shadow), - is_cache_placeholder_(false), - epsilon_change_func_(std::bind(&event::compare, this, +event::event(routing_manager *_routing, bool _is_shadow) + : routing_(_routing), + current_(runtime::get()->create_notification()), + update_(runtime::get()->create_notification()), + type_(event_type_e::ET_EVENT), + cycle_timer_(_routing->get_io()), + cycle_(std::chrono::milliseconds::zero()), + change_resets_cycle_(false), + is_updating_on_change_(true), + is_set_(false), + is_provided_(false), + is_shadow_(_is_shadow), + is_cache_placeholder_(false), + epsilon_change_func_(std::bind(&event::has_changed, this, std::placeholders::_1, std::placeholders::_2)), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN) { + } -service_t event::get_service() const { - return (message_->get_service()); +service_t +event::get_service() const { + + return (current_->get_service()); } -void event::set_service(service_t _service) { - message_->set_service(_service); +void +event::set_service(service_t _service) { + + current_->set_service(_service); + update_->set_service(_service); } -instance_t event::get_instance() const { - return (message_->get_instance()); +instance_t +event::get_instance() const { + + return (current_->get_instance()); } -void event::set_instance(instance_t _instance) { - message_->set_instance(_instance); +void +event::set_instance(instance_t _instance) { + + current_->set_instance(_instance); + update_->set_instance(_instance); } -major_version_t event::get_version() const { - return message_->get_interface_version(); +major_version_t +event::get_version() const { + + return current_->get_interface_version(); } -void event::set_version(major_version_t _major) { - message_->set_interface_version(_major); +void +event::set_version(major_version_t _major) { + + current_->set_interface_version(_major); + update_->set_interface_version(_major); } -event_t event::get_event() const { - return (message_->get_method()); +event_t +event::get_event() const { + + return (current_->get_method()); } -void event::set_event(event_t _event) { - message_->set_method(_event); +void +event::set_event(event_t _event) { + + current_->set_method(_event); + update_->set_method(_event); } -event_type_e event::get_type() const { +event_type_e +event::get_type() const { + return (type_); } -void event::set_type(const event_type_e _type) { +void +event::set_type(const event_type_e _type) { + type_ = _type; } -bool event::is_field() const { +bool +event::is_field() const { + return (type_ == event_type_e::ET_FIELD); } -bool event::is_provided() const { +bool +event::is_provided() const { + return (is_provided_); } -void event::set_provided(bool _is_provided) { +void +event::set_provided(bool _is_provided) { + is_provided_ = _is_provided; } @@ -94,122 +128,138 @@ bool event::is_set() const { return is_set_; } -const std::shared_ptr event::get_payload() const { +std::shared_ptr +event::get_payload() const { + std::lock_guard its_lock(mutex_); - return (message_->get_payload()); + return (current_->get_payload()); } -bool event::set_payload_dont_notify(const std::shared_ptr &_payload) { +void +event::update_payload() { + std::lock_guard its_lock(mutex_); - if (is_cache_placeholder_) { - reset_payload(_payload); - is_set_ = true; - } else { - if (set_payload_helper(_payload, false)) { - reset_payload(_payload); - } else { - return false; - } - } - return true; + update_payload_unlocked(); +} + +void +event::update_payload_unlocked() { + + current_->set_payload(update_->get_payload()); } -void event::set_payload(const std::shared_ptr &_payload, bool _force) { +void +event::set_payload(const std::shared_ptr &_payload, bool _force) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - if (change_resets_cycle_) - stop_cycle(); + if (is_provided_ && prepare_update_payload_unlocked(_payload, _force)) { + if (is_updating_on_change_) { + if (change_resets_cycle_) + stop_cycle(); - notify(); + notify(_force); - if (change_resets_cycle_) - start_cycle(); - } + if (change_resets_cycle_) + start_cycle(); + + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << " as it isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -void event::set_payload(const std::shared_ptr &_payload, client_t _client, +void +event::set_payload(const std::shared_ptr &_payload, client_t _client, bool _force) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - notify_one_unlocked(_client); - } + if (is_provided_ && prepare_update_payload_unlocked(_payload, _force)) { + if (is_updating_on_change_) { + notify_one_unlocked(_client, _force); + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << ". It isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -void event::set_payload(const std::shared_ptr &_payload, +void +event::set_payload(const std::shared_ptr &_payload, const client_t _client, - const std::shared_ptr& _target, - bool _force) { + const std::shared_ptr &_target) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - notify_one_unlocked(_client, _target); - } + if (is_provided_ && prepare_update_payload_unlocked(_payload, false)) { + if (is_updating_on_change_) { + notify_one_unlocked(_client, _target); + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << ". It isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -bool event::set_payload_notify_pending(const std::shared_ptr &_payload) { +bool +event::set_payload_notify_pending(const std::shared_ptr &_payload) { + std::lock_guard its_lock(mutex_); - if (!is_set_ && is_provided_) { - reset_payload(_payload); + if (is_provided_ && !is_set_) { + + update_->set_payload(_payload); + is_set_ = true; // Send pending initial events. for (const auto &its_target : pending_) { - message_->set_session(routing_->get_session()); + set_session(); routing_->send_to(VSOMEIP_ROUTING_CLIENT, - its_target, message_); + its_target, update_); } pending_.clear(); - return true; + update_payload_unlocked(); + + return (true); } - return false; + return (false); } -void event::unset_payload(bool _force) { +void +event::unset_payload(bool _force) { + std::lock_guard its_lock(mutex_); if (_force) { is_set_ = false; stop_cycle(); - message_->set_payload(std::make_shared()); + current_->set_payload(std::make_shared()); } else { if (is_provided_) { is_set_ = false; stop_cycle(); - message_->set_payload(std::make_shared()); + current_->set_payload(std::make_shared()); } } } -void event::set_update_cycle(std::chrono::milliseconds &_cycle) { +void +event::set_update_cycle(std::chrono::milliseconds &_cycle) { + if (is_provided_) { std::lock_guard its_lock(mutex_); stop_cycle(); @@ -218,24 +268,33 @@ void event::set_update_cycle(std::chrono::milliseconds &_cycle) { } } -void event::set_change_resets_cycle(bool _change_resets_cycle) { +void +event::set_change_resets_cycle(bool _change_resets_cycle) { + change_resets_cycle_ = _change_resets_cycle; } -void event::set_update_on_change(bool _is_active) { +void +event::set_update_on_change(bool _is_active) { + if (is_provided_) { is_updating_on_change_ = _is_active; } } -void event::set_epsilon_change_function(const epsilon_change_func_t &_epsilon_change_func) { +void +event::set_epsilon_change_function( + const epsilon_change_func_t &_epsilon_change_func) { + + std::lock_guard its_lock(mutex_); if (_epsilon_change_func) { - std::lock_guard its_lock(mutex_); epsilon_change_func_ = _epsilon_change_func; } } -const std::set event::get_eventgroups() const { +std::set +event::get_eventgroups() const { + std::set its_eventgroups; { std::lock_guard its_lock(eventgroups_mutex_); @@ -246,7 +305,9 @@ const std::set event::get_eventgroups() const { return its_eventgroups; } -std::set event::get_eventgroups(client_t _client) const { +std::set +event::get_eventgroups(client_t _client) const { + std::set its_eventgroups; std::lock_guard its_lock(eventgroups_mutex_); @@ -257,23 +318,29 @@ std::set event::get_eventgroups(client_t _client) const { return its_eventgroups; } -void event::add_eventgroup(eventgroup_t _eventgroup) { +void +event::add_eventgroup(eventgroup_t _eventgroup) { + std::lock_guard its_lock(eventgroups_mutex_); if (eventgroups_.find(_eventgroup) == eventgroups_.end()) eventgroups_[_eventgroup] = std::set(); } -void event::set_eventgroups(const std::set &_eventgroups) { +void +event::set_eventgroups(const std::set &_eventgroups) { + std::lock_guard its_lock(eventgroups_mutex_); for (auto e : _eventgroups) eventgroups_[e] = std::set(); } -void event::update_cbk(boost::system::error_code const &_error) { +void +event::update_cbk(boost::system::error_code const &_error) { + if (!_error) { std::lock_guard its_lock(mutex_); cycle_timer_.expires_from_now(cycle_); - notify(); + notify(true); auto its_handler = std::bind(&event::update_cbk, shared_from_this(), std::placeholders::_1); @@ -281,10 +348,12 @@ void event::update_cbk(boost::system::error_code const &_error) { } } -void event::notify() { +void +event::notify(bool _force) { + if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send(VSOMEIP_ROUTING_CLIENT, message_); + set_session(); + routing_->send(VSOMEIP_ROUTING_CLIENT, update_, _force); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -294,8 +363,10 @@ void event::notify() { } } -void event::notify_one(client_t _client, +void +event::notify_one(client_t _client, const std::shared_ptr &_target) { + if (_target) { std::lock_guard its_lock(mutex_); notify_one_unlocked(_client, _target); @@ -308,12 +379,14 @@ void event::notify_one(client_t _client, } } -void event::notify_one_unlocked(client_t _client, +void +event::notify_one_unlocked(client_t _client, const std::shared_ptr &_target) { + if (_target) { if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send_to(_client, _target, message_); + set_session(); + routing_->send_to(_client, _target, update_); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -331,15 +404,23 @@ void event::notify_one_unlocked(client_t _client, } } -void event::notify_one(client_t _client) { +void +event::notify_one(client_t _client, bool _force) { + std::lock_guard its_lock(mutex_); - notify_one_unlocked(_client); + notify_one_unlocked(_client, _force); } -void event::notify_one_unlocked(client_t _client) { +void +event::notify_one_unlocked(client_t _client, bool _force) { + if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send(_client, message_); + set_session(); + { + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + last_forwarded_[_client] = std::chrono::steady_clock::now(); + } + routing_->send(_client, update_, _force); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -350,28 +431,46 @@ void event::notify_one_unlocked(client_t _client) { } } -bool event::set_payload_helper(const std::shared_ptr &_payload, bool _force) { - std::shared_ptr its_payload = message_->get_payload(); - bool is_change(type_ != event_type_e::ET_FIELD); - if (!is_change) { - is_change = _force || epsilon_change_func_(its_payload, _payload); - } - return is_change; +bool +event::prepare_update_payload(const std::shared_ptr &_payload, + bool _force) { + + std::lock_guard its_lock(mutex_); + return (prepare_update_payload_unlocked(_payload, _force)); } -void event::reset_payload(const std::shared_ptr &_payload) { - std::shared_ptr its_new_payload +bool +event::prepare_update_payload_unlocked( + const std::shared_ptr &_payload, bool _force) { + + // Copy payload to avoid manipulation from the outside + std::shared_ptr its_payload = runtime::get()->create_payload( - _payload->get_data(), _payload->get_length()); - message_->set_payload(its_new_payload); + _payload->get_data(), _payload->get_length()); + + bool is_change = has_changed(current_->get_payload(), its_payload); + if (!_force + && type_ == event_type_e::ET_FIELD + && cycle_ == std::chrono::milliseconds::zero() + && !is_change) { + + return (false); + } + + if (is_change) + update_->set_payload(its_payload); if (!is_set_) start_cycle(); is_set_ = true; + + return (true); } -void event::add_ref(client_t _client, bool _is_provided) { +void +event::add_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client == refs_.end()) { @@ -386,7 +485,9 @@ void event::add_ref(client_t _client, bool _is_provided) { } } -void event::remove_ref(client_t _client, bool _is_provided) { +void +event::remove_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client != refs_.end()) { @@ -403,24 +504,126 @@ void event::remove_ref(client_t _client, bool _is_provided) { } } -bool event::has_ref() { +bool +event::has_ref() { + std::lock_guard its_lock(refs_mutex_); return refs_.size() != 0; } -bool event::add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _force) { +bool +event::add_subscriber(eventgroup_t _eventgroup, + const std::shared_ptr &_filter, + client_t _client, bool _force) { + std::lock_guard its_lock(eventgroups_mutex_); bool ret = false; if (_force // remote events managed by rm_impl || is_provided_ // events provided by rm_proxies || is_shadow_ // local events managed by rm_impl || is_cache_placeholder_) { + + if (_filter) { + VSOMEIP_WARNING << "Using client [" + << std::hex << std::setw(4) << std::setfill('0') + << _client + << "] specific filter configuration for SOME/IP event " + << get_service() << "." << get_instance() << "." << get_event() << "."; + std::stringstream its_filter_parameters; + its_filter_parameters << "(on_change=" + << std::boolalpha << _filter->on_change_ + << ", interval=" << std::dec << _filter->interval_ + << ", on_change_resets_interval=" + << std::boolalpha << _filter->on_change_resets_interval_ + << ", ignore=[ "; + for (auto i : _filter->ignore_) + its_filter_parameters << "(" << std::dec << i.first << ", " + << std::hex << std::setw(2) << std::setfill('0') + << (int)i.second << ") "; + its_filter_parameters << "])"; + VSOMEIP_INFO << "Filter parameters: " + << its_filter_parameters.str(); + + filters_[_client] = [_filter, _client, this]( + const std::shared_ptr &_old, + const std::shared_ptr &_new) { + + bool is_changed(false), is_elapsed(false); + + // Check whether we should forward because of changed data + if (_filter->on_change_) { + length_t its_min_length, its_max_length; + + if (_old->get_length() < _new->get_length()) { + its_min_length = _old->get_length(); + its_max_length = _new->get_length(); + } else { + its_min_length = _new->get_length(); + its_max_length = _old->get_length(); + } + + // Check whether all additional bytes (if any) are excluded + for (length_t i = its_min_length; i < its_max_length; i++) { + auto j = _filter->ignore_.find(i); + // A change is detected when an additional byte is not + // excluded at all or if its exclusion does not cover all + // bits + if (j == _filter->ignore_.end() || j->second != 0xFF) { + is_changed = true; + break; + } + } + + if (!is_changed) { + const byte_t *its_old = _old->get_data(); + const byte_t *its_new = _new->get_data(); + for (length_t i = 0; i < its_min_length; i++) { + auto j = _filter->ignore_.find(i); + if (j == _filter->ignore_.end()) { + if (its_old[i] != its_new[i]) { + is_changed = true; + break; + } + } else if (j->second != 0xFF) { + if ((its_old[i] & ~(j->second)) != (its_new[i] & ~(j->second))) { + is_changed = true; + break; + } + } + } + } + } + + if (_filter->interval_ > -1) { + // Check whether we should forward because of the elapsed time since + // we did last time + std::chrono::steady_clock::time_point its_current + = std::chrono::steady_clock::now(); + + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + is_elapsed = (last_forwarded_.find(_client) == last_forwarded_.end()); + if (!is_elapsed) { + std::int64_t elapsed = std::chrono::duration_cast( + its_current - last_forwarded_[_client]).count(); + is_elapsed = (elapsed >= _filter->interval_); + } + + if (is_elapsed || (is_changed && _filter->on_change_resets_interval_)) + last_forwarded_[_client] = its_current; + } + + return (is_changed || is_elapsed); + }; + } else { + filters_.erase(_client); + } + ret = eventgroups_[_eventgroup].insert(_client).second; + } else { VSOMEIP_WARNING << __func__ << ": Didnt' insert client " - << std::hex << std::setw(4) << std::setfill('0') - << _client - << " to eventgroup " + << std::hex << std::setw(4) << std::setfill('0') << _client + << " to eventgroup 0x" << std::hex << std::setw(4) << std::setfill('0') << get_service() << "." << get_instance() << "." << _eventgroup; @@ -428,14 +631,21 @@ bool event::add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _for return ret; } -void event::remove_subscriber(eventgroup_t _eventgroup, client_t _client) { +void +event::remove_subscriber(eventgroup_t _eventgroup, client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); auto find_eventgroup = eventgroups_.find(_eventgroup); if (find_eventgroup != eventgroups_.end()) find_eventgroup->second.erase(_client); + + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + last_forwarded_.erase(_client); } -bool event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { +bool +event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); auto find_eventgroup = eventgroups_.find(_eventgroup); if (find_eventgroup != eventgroups_.end()) { @@ -449,7 +659,9 @@ bool event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { return false; } -std::set event::get_subscribers() { +std::set +event::get_subscribers() { + std::set its_subscribers; std::lock_guard its_lock(eventgroups_mutex_); for (const auto &e : eventgroups_) @@ -457,13 +669,79 @@ std::set event::get_subscribers() { return its_subscribers; } -void event::clear_subscribers() { +std::set +event::get_filtered_subscribers(bool _force) { + + std::set its_subscribers(get_subscribers()); + std::set its_filtered_subscribers; + + std::shared_ptr its_payload, its_payload_update; + { + its_payload = current_->get_payload(); + its_payload_update = update_->get_payload(); + } + + if (filters_.empty()) { + + bool must_forward = (type_ != event_type_e::ET_FIELD + || _force + || epsilon_change_func_(its_payload, its_payload_update)); + + if (must_forward) + return (its_subscribers); + + } else { + byte_t is_allowed(0xff); + + std::lock_guard its_lock(filters_mutex_); + for (const auto s : its_subscribers) { + + auto its_specific = filters_.find(s); + if (its_specific != filters_.end()) { + if (its_specific->second(its_payload, its_payload_update)) + its_filtered_subscribers.insert(s); + } else { + if (is_allowed == 0xff) { + is_allowed = (type_ != event_type_e::ET_FIELD + || _force + || epsilon_change_func_(its_payload, its_payload_update) + ? 0x01 : 0x00); + } + + if (is_allowed == 0x01) + its_filtered_subscribers.insert(s); + } + } + } + + return (its_filtered_subscribers); +} + +std::set +event::update_and_get_filtered_subscribers( + const std::shared_ptr &_payload, bool _is_from_remote) { + + std::lock_guard its_lock(mutex_); + + (void)prepare_update_payload_unlocked(_payload, true); + auto its_subscribers = get_filtered_subscribers(!_is_from_remote); + if (_is_from_remote) + update_payload_unlocked(); + + return (its_subscribers); +} + +void +event::clear_subscribers() { + std::lock_guard its_lock(eventgroups_mutex_); for (auto &e : eventgroups_) e.second.clear(); } -bool event::has_ref(client_t _client, bool _is_provided) { +bool +event::has_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client != refs_.end()) { @@ -477,24 +755,35 @@ bool event::has_ref(client_t _client, bool _is_provided) { return false; } -bool event::is_shadow() const { +bool +event::is_shadow() const { + return is_shadow_; } -void event::set_shadow(bool _shadow) { +void +event::set_shadow(bool _shadow) { + is_shadow_ = _shadow; } -bool event::is_cache_placeholder() const { +bool +event::is_cache_placeholder() const { + return is_cache_placeholder_; } -void event::set_cache_placeholder(bool _is_cache_place_holder) { +void +event::set_cache_placeholder(bool _is_cache_place_holder) { + is_cache_placeholder_ = _is_cache_place_holder; } -void event::start_cycle() { - if (std::chrono::milliseconds::zero() != cycle_) { +void +event::start_cycle() { + + if (!is_shadow_ + && std::chrono::milliseconds::zero() != cycle_) { cycle_timer_.expires_from_now(cycle_); auto its_handler = std::bind(&event::update_cbk, shared_from_this(), @@ -503,15 +792,20 @@ void event::start_cycle() { } } -void event::stop_cycle() { - if (std::chrono::milliseconds::zero() != cycle_) { +void +event::stop_cycle() { + + if (!is_shadow_ + && std::chrono::milliseconds::zero() != cycle_) { boost::system::error_code ec; cycle_timer_.cancel(ec); } } -bool event::compare(const std::shared_ptr &_lhs, +bool +event::has_changed(const std::shared_ptr &_lhs, const std::shared_ptr &_rhs) const { + bool is_change = (_lhs->get_length() != _rhs->get_length()); if (!is_change) { std::size_t its_pos = 0; @@ -522,10 +816,12 @@ bool event::compare(const std::shared_ptr &_lhs, its_pos++; } } - return is_change; + return (is_change); } -std::set event::get_subscribers(eventgroup_t _eventgroup) { +std::set +event::get_subscribers(eventgroup_t _eventgroup) { + std::set its_subscribers; std::lock_guard its_lock(eventgroups_mutex_); auto found_eventgroup = eventgroups_.find(_eventgroup); @@ -535,7 +831,9 @@ std::set event::get_subscribers(eventgroup_t _eventgroup) { return its_subscribers; } -bool event::is_subscribed(client_t _client) { +bool +event::is_subscribed(client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); for (const auto &egp : eventgroups_) { if (egp.second.find(_client) != egp.second.end()) { @@ -547,18 +845,27 @@ bool event::is_subscribed(client_t _client) { reliability_type_e event::get_reliability() const { + return reliability_; } void event::set_reliability(const reliability_type_e _reliability) { + reliability_ = _reliability; } void event::remove_pending(const std::shared_ptr &_target) { + std::lock_guard its_lock(mutex_); pending_.erase(_target); } +void +event::set_session() { + + update_->set_session(routing_->get_session(false)); +} + } // namespace vsomeip_v3 diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp index 50bbdb6a0..c41f55b6b 100644 --- a/implementation/routing/src/eventgroupinfo.cpp +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -119,12 +119,18 @@ void eventgroupinfo::set_multicast(const boost::asio::ip::address &_address, port_ = _port; } -const std::set > eventgroupinfo::get_events() const { +std::set > eventgroupinfo::get_events() const { std::lock_guard its_lock(events_mutex_); return events_; } void eventgroupinfo::add_event(const std::shared_ptr& _event) { + + if (_event == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return; + } + std::lock_guard its_lock(events_mutex_); events_.insert(_event); @@ -158,6 +164,12 @@ void eventgroupinfo::add_event(const std::shared_ptr& _event) { } void eventgroupinfo::remove_event(const std::shared_ptr& _event) { + + if (_event == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return; + } + std::lock_guard its_lock(events_mutex_); events_.erase(_event); } @@ -217,13 +229,19 @@ eventgroupinfo::update_remote_subscription( const bool _is_subscribe) { bool its_result(false); + + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return (its_result); + } + std::shared_ptr its_subscriber; std::set > its_events; { std::lock_guard its_lock(subscriptions_mutex_); - for (const auto& its_item : subscriptions_) { + for (const auto &its_item : subscriptions_) { if (its_item.second->equals(_subscription)) { // update existing subscription _changed = its_item.second->update( @@ -231,16 +249,17 @@ eventgroupinfo::update_remote_subscription( _id = its_item.second->get_id(); // Copy acknowledgment states from existing subscription - for (const auto& its_client : _subscription->get_clients()) { - const auto its_state = its_item.second->get_client_state(its_client); - if (_is_subscribe && - its_state == remote_subscription_state_e::SUBSCRIPTION_UNKNOWN) { - _subscription->set_client_state(its_client, - remote_subscription_state_e::SUBSCRIPTION_PENDING); + for (const auto its_client : _subscription->get_clients()) { + auto its_state = its_item.second->get_client_state(its_client); + if (_is_subscribe + && its_state == remote_subscription_state_e::SUBSCRIPTION_UNKNOWN) { + // We met the current subscription object during its + // unsubscribe process. Therefore, trigger a resubscription. + its_state = remote_subscription_state_e::SUBSCRIPTION_PENDING; _changed.insert(its_client); - } else { - _subscription->set_client_state(its_client, its_state); } + + _subscription->set_client_state(its_client, its_state); } if (_is_subscribe) { @@ -295,6 +314,11 @@ eventgroupinfo::is_remote_subscription_limit_reached( const std::shared_ptr &_subscription) { bool limit_reached(false); + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return (limit_reached); + } + if (subscriptions_.size() <= max_remote_subscribers_) { return false; } @@ -321,6 +345,11 @@ eventgroupinfo::is_remote_subscription_limit_reached( remote_subscription_id_t eventgroupinfo::add_remote_subscription( const std::shared_ptr &_subscription) { + + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return id_; + } std::lock_guard its_lock(subscriptions_mutex_); update_id(); @@ -419,7 +448,6 @@ void eventgroupinfo::send_initial_events( const std::shared_ptr &_reliable, const std::shared_ptr &_unreliable) const { - std::set > its_reliable_events, its_unreliable_events; // Build sets of reliable/unreliable events first to avoid having to @@ -465,11 +493,23 @@ eventgroupinfo::send_initial_events( } // Send events - for (const auto &its_event : its_reliable_events) - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + if (!its_reliable_events.empty()) { + if (_reliable != nullptr) { + for (const auto &its_event : its_reliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + } else { + VSOMEIP_ERROR << __func__ << ": Received ptr (_reliable) is null"; + } + } - for (const auto &its_event : its_unreliable_events) - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); + if (!its_unreliable_events.empty()) { + if (_unreliable != nullptr) { + for (const auto &its_event : its_unreliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); + } else { + VSOMEIP_ERROR << __func__ << ": Received ptr (_unreliable) is null"; + } + } } uint8_t eventgroupinfo::get_max_remote_subscribers() const { diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp index cb04d93ff..3c9510849 100644 --- a/implementation/routing/src/remote_subscription.cpp +++ b/implementation/routing/src/remote_subscription.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -13,7 +13,6 @@ remote_subscription::remote_subscription() : id_(PENDING_SUBSCRIPTION_ID), is_initial_(true), force_initial_events_(false), - major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), reserved_(0), counter_(0), diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index c787a9e24..49dcffb54 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,8 +9,8 @@ #include #include "../include/routing_manager_base.hpp" -#include "../../endpoints/include/local_client_endpoint_impl.hpp" -#include "../../endpoints/include/local_server_endpoint_impl.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" @@ -23,9 +23,7 @@ namespace vsomeip_v3 { routing_manager_base::routing_manager_base(routing_manager_host *_host) : host_(_host), io_(host_->get_io()), - client_(host_->get_client()), - configuration_(host_->get_configuration()), - routing_state_(routing_state_e::RS_UNKNOWN) + configuration_(host_->get_configuration()) #ifdef USE_DLT , tc_(trace::connector_impl::get()) #endif @@ -41,29 +39,52 @@ routing_manager_base::routing_manager_base(routing_manager_host *_host) : std::make_shared(its_buffer_shrink_threshold)); } - own_uid_ = ANY_UID; - own_gid_ = ANY_GID; -#ifndef _WIN32 - own_uid_ = getuid(); - own_gid_ = getgid(); -#endif - + if (!configuration_->is_local_routing()) { + auto its_routing_address = configuration_->get_routing_host_address(); + auto its_routing_port = configuration_->get_routing_host_port(); + if (!its_routing_address.is_unspecified() && !its_routing_address.is_multicast()) { + add_guest(VSOMEIP_ROUTING_CLIENT, its_routing_address, its_routing_port); + } + } } -boost::asio::io_service & routing_manager_base::get_io() { +boost::asio::io_context &routing_manager_base::get_io() { + return (io_); } client_t routing_manager_base::get_client() const { - return client_; + + return (host_->get_client()); } void routing_manager_base::set_client(const client_t &_client) { - client_ = _client; + + host_->set_client(_client); } -session_t routing_manager_base::get_session() { - return host_->get_session(); +session_t routing_manager_base::get_session(bool _is_request) { + return host_->get_session(_is_request); +} + +const vsomeip_sec_client_t *routing_manager_base::get_sec_client() const { + + return (host_->get_sec_client()); +} + +std::string routing_manager_base::get_client_host() const { + std::lock_guard its_env_lock(env_mutex_); + return env_; +} + +void routing_manager_base::set_client_host(const std::string &_client_host) { + + std::lock_guard its_env_lock(env_mutex_); + env_ = _client_host; +} + +bool routing_manager_base::is_routing_manager() const { + return false; } void routing_manager_base::init(const std::shared_ptr& _endpoint_manager) { @@ -218,25 +239,7 @@ void routing_manager_base::register_event(client_t _client, if (its_event) { if (!its_event->is_cache_placeholder()) { if (_type == its_event->get_type() - || its_event->get_type() == event_type_e::ET_UNKNOWN -#ifdef VSOMEIP_ENABLE_COMPAT - || (its_event->get_type() == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) - || (its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT - && _type == event_type_e::ET_EVENT && _is_provided) -#endif - ) { -#ifdef VSOMEIP_ENABLE_COMPAT - if (its_event->get_type() == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) { - its_event->set_type(_type); - VSOMEIP_INFO << "Event type changed to selective (" - << std::hex << std::setw(4) << std::setfill('0') << _client << ") [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _notifier << "]"; - } -#endif + || its_event->get_type() == event_type_e::ET_UNKNOWN) { if (_is_provided) { its_event->set_provided(true); its_event->set_reliability(determine_event_reliability()); @@ -319,8 +322,8 @@ void routing_manager_base::register_event(client_t _client, } if (_is_shadow && !_epsilon_change_func) { - std::shared_ptr its_debounce - = configuration_->get_debounce(_service, _instance, _notifier); + std::shared_ptr its_debounce + = configuration_->get_debounce(host_->get_name(), _service, _instance, _notifier); if (its_debounce) { VSOMEIP_WARNING << "Using debounce configuration for " << " SOME/IP event " @@ -344,6 +347,9 @@ void routing_manager_base::register_event(client_t _client, _epsilon_change_func = [its_debounce]( const std::shared_ptr &_old, const std::shared_ptr &_new) { + + static std::chrono::steady_clock::time_point its_last_forwarded + = std::chrono::steady_clock::time_point::max(); bool is_changed(false), is_elapsed(false); // Check whether we should forward because of changed data @@ -362,8 +368,8 @@ void routing_manager_base::register_event(client_t _client, for (length_t i = its_min_length; i < its_max_length; i++) { auto j = its_debounce->ignore_.find(i); // A change is detected when an additional byte is not - // excluded at all or if its exclusion does not cover - // all its bits. + // excluded at all or if its exclusion does not cover all + // bits if (j == its_debounce->ignore_.end() || j->second != 0xFF) { is_changed = true; break; @@ -396,12 +402,12 @@ void routing_manager_base::register_event(client_t _client, std::chrono::steady_clock::time_point its_current = std::chrono::steady_clock::now(); - long elapsed = std::chrono::duration_cast( - its_current - its_debounce->last_forwarded_).count(); - is_elapsed = (its_debounce->last_forwarded_ == (std::chrono::steady_clock::time_point::max)() + std::int64_t elapsed = std::chrono::duration_cast( + its_current - its_last_forwarded).count(); + is_elapsed = (its_last_forwarded == std::chrono::steady_clock::time_point::max() || elapsed >= its_debounce->interval_); if (is_elapsed || (is_changed && its_debounce->on_change_resets_interval_)) - its_debounce->last_forwarded_ = its_current; + its_last_forwarded = its_current; } return (is_changed || is_elapsed); }; @@ -440,14 +446,13 @@ void routing_manager_base::register_event(client_t _client, std::set its_any_event_subscribers = its_any_event->get_subscribers(eventgroup); for (const client_t subscriber : its_any_event_subscribers) { - its_event->add_subscriber(eventgroup, subscriber, true); + its_event->add_subscriber(eventgroup, nullptr, subscriber, true); } } } } } - - if (!its_event->is_cache_placeholder()) { + if(!_is_cache_placeholder) { its_event->add_ref(_client, _is_provided); } @@ -547,8 +552,8 @@ std::vector routing_manager_base::find_events( bool routing_manager_base::is_response_allowed(client_t _sender, service_t _service, instance_t _instance, method_t _method) { - const auto its_security(security::get()); - if (!its_security->is_enabled()) { + if (!configuration_->is_security_enabled() + || !configuration_->is_local_routing()) { return true; } @@ -575,7 +580,7 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv // service is now offered by another client // or service is not offered at all std::string security_mode_text = "!"; - if (!its_security->is_audit()) { + if (!configuration_->is_security_audit()) { security_mode_text = ", but will be allowed due to audit mode is active!"; } @@ -586,23 +591,20 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv << _service << "/" << _instance << "/" << _method << security_mode_text; - return !its_security->is_audit(); + return !configuration_->is_security_audit(); } -bool routing_manager_base::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, +bool routing_manager_base::is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) { - const auto its_security(security::get()); - const uid_t its_uid(std::get<0>(_credentials)); - const gid_t its_gid(std::get<1>(_credentials)); - bool is_allowed(true); auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { for (const auto& e : its_eventgroup->get_events()) { - if (!its_security->is_client_allowed(its_uid, its_gid, - _client, _service, _instance, e->get_event())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, _service, _instance, e->get_event())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client << " : routing_manager_base::is_subscribe_to_any_event_allowed: " << "subscribes to service/instance/event " @@ -617,26 +619,64 @@ bool routing_manager_base::is_subscribe_to_any_event_allowed(credentials_t _cred return is_allowed; } -void routing_manager_base::subscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) { +void routing_manager_base::add_known_client(client_t _client, const std::string &_client_host) { +#if !defined(VSOMEIP_DISABLE_SECURITY) && (defined(__linux__) || defined(ANDROID)) + std::lock_guard lazy_lock(add_known_client_mutex_); + if (configuration_->is_security_enabled()) { + //Ignore if we have already loaded the policy extension + policy_manager_impl::policy_loaded_e policy_loaded + = policy_manager_impl::get()->is_policy_extension_loaded(_client_host); + + if (policy_loaded == policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED) + { + if (configuration_->lazy_load_security(_client_host)) { + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << _client_host + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } + } else if (policy_loaded == policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT) { + if (configuration_->lazy_load_security(_client_host)) + { + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << _client_host + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } else if (configuration_->lazy_load_security(get_client_host())) { //necessary for lazy loading from inside android container + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << get_client_host() + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } + } + } +#endif + std::lock_guard its_lock(known_clients_mutex_); + known_clients_[_client] = _client_host; +} + +void routing_manager_base::subscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + (void)_major; + (void)_sec_client; - (void) _major; - (void)_uid; - (void)_gid; std::set its_already_subscribed_events; bool inserted = insert_subscription(_service, _instance, _eventgroup, - _event, _client, &its_already_subscribed_events); + _event, _filter, _client, &its_already_subscribed_events); if (inserted) { notify_one_current_value(_client, _service, _instance, _eventgroup, _event, its_already_subscribed_events); } } -void routing_manager_base::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup,event_t _event) { - (void)_uid; - (void)_gid; +void routing_manager_base::unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) { + + (void)_sec_client; + if (_event != ANY_EVENT) { auto its_event = find_event(_service, _instance, _event); if (its_event) { @@ -653,24 +693,10 @@ void routing_manager_base::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } } -void -routing_manager_base::unsubscribe_all( - service_t _service, instance_t _instance) { - - std::lock_guard its_guard(events_mutex_); - auto find_service = events_.find(_service); - if (find_service != events_.end()) { - auto find_instance = find_service->second.find(_instance); - if (find_instance != find_service->second.end()) { - for (auto &e : find_instance->second) - e.second->clear_subscribers(); - } - } -} - void routing_manager_base::notify(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, bool _force) { + std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { its_event->set_payload(_payload, _force); @@ -843,7 +869,7 @@ void routing_manager_base::notify_one_current_value( if (_event != ANY_EVENT) { std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event && its_event->is_field()) - its_event->notify_one(_client); + its_event->notify_one(_client, false); } else { auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { @@ -852,7 +878,7 @@ void routing_manager_base::notify_one_current_value( if (e->is_field() && _events_to_exclude.find(e->get_event()) == _events_to_exclude.end()) { - e->notify_one(_client); + e->notify_one(_client, false); } } } @@ -860,7 +886,8 @@ void routing_manager_base::notify_one_current_value( } bool routing_manager_base::send(client_t _client, - std::shared_ptr _message) { + std::shared_ptr _message, bool _force) { + bool is_sent(false); if (utility::is_request(_message->get_message_type())) { _message->set_client(_client); @@ -870,7 +897,8 @@ bool routing_manager_base::send(client_t _client, if (its_serializer->serialize(_message.get())) { is_sent = send(_client, its_serializer->get_data(), its_serializer->get_size(), _message->get_instance(), - _message->is_reliable(), get_client(), std::make_pair(ANY_UID, ANY_GID), 0, false); + _message->is_reliable(), get_client(), get_sec_client(), + 0, false, _force); its_serializer->reset(); put_serializer(its_serializer); } else { @@ -1024,18 +1052,20 @@ void routing_manager_base::remove_local(client_t _client, bool _remove_uid) { void routing_manager_base::remove_local(client_t _client, const std::set>& _subscribed_eventgroups, - bool _remove_uid) { + bool _remove_sec_client) { - std::pair its_uid_gid(ANY_UID, ANY_GID); - security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid); + vsomeip_sec_client_t its_sec_client; + policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); - if (_remove_uid) { - security::get()->remove_client_to_uid_gid_mapping(_client); + if (_remove_sec_client) { + policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); } for (auto its_subscription : _subscribed_eventgroups) { host_->on_subscription(std::get<0>(its_subscription), std::get<1>(its_subscription), - std::get<2>(its_subscription), _client, its_uid_gid.first, its_uid_gid.second, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - routing_manager_base::unsubscribe(_client, its_uid_gid.first, its_uid_gid.second, std::get<0>(its_subscription), + std::get<2>(its_subscription), _client, + &its_sec_client, get_env(_client), + false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); + routing_manager_base::unsubscribe(_client, &its_sec_client, std::get<0>(its_subscription), std::get<1>(its_subscription), std::get<2>(its_subscription), ANY_EVENT); } ep_mgr_->remove_local(_client); @@ -1047,7 +1077,7 @@ void routing_manager_base::remove_local(client_t _client, for (auto& i : s.second) { if (std::get<2>(i.second) == _client) { its_services.insert({ s.first, i.first }); - host_->on_availability(s.first, i.first, false, + host_->on_availability(s.first, i.first, availability_state_e::AS_UNAVAILABLE, std::get<0>(i.second), std::get<1>(i.second)); } } @@ -1074,9 +1104,7 @@ void routing_manager_base::remove_local(client_t _client, for (auto& sic : its_clients) { local_services_history_[std::get<0>(sic)][std::get<1>(sic)].erase(std::get<2>(sic)); if (local_services_history_[std::get<0>(sic)][std::get<1>(sic)].size() == 0) { - local_services_history_[std::get<0>(sic)].erase(std::get<1>(sic)); - if (local_services_history_[std::get<0>(sic)].size() == 0) - local_services_history_.erase(std::get<0>(sic)); + local_services_history_.erase(std::get<0>(sic)); } } } @@ -1161,7 +1189,7 @@ void routing_manager_base::remove_eventgroup_info(service_t _service, bool routing_manager_base::send_local_notification(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _status_check) { + bool _reliable, uint8_t _status_check, bool _force) { #ifdef USE_DLT bool has_local(false); #endif @@ -1173,7 +1201,7 @@ bool routing_manager_base::send_local_notification(client_t _client, std::shared_ptr its_event = find_event(its_service, _instance, its_method); if (its_event && !its_event->is_shadow()) { - for (auto its_client : its_event->get_subscribers()) { + for (auto its_client : its_event->get_filtered_subscribers(_force)) { // local if (its_client == VSOMEIP_ROUTING_CLIENT) { @@ -1189,60 +1217,57 @@ bool routing_manager_base::send_local_notification(client_t _client, std::shared_ptr its_local_target = ep_mgr_->find_local(its_client); if (its_local_target) { send_local(its_local_target, _client, _data, _size, - _instance, _reliable, VSOMEIP_SEND, _status_check); + _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } #ifdef USE_DLT // Trace the message if a local client but will _not_ be forwarded to the routing manager if (has_local && !has_remote) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(nullptr, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif return has_remote; } bool routing_manager_base::send_local( - std::shared_ptr& _target, client_t _client, + std::shared_ptr &_target, client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _command, uint8_t _status_check) const { - const std::size_t its_complete_size = VSOMEIP_SEND_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE + _size; - const client_t sender = get_client(); - - std::vector its_command_header(VSOMEIP_SEND_COMMAND_SIZE); - its_command_header[VSOMEIP_COMMAND_TYPE_POS] = _command; - std::memcpy(&its_command_header[VSOMEIP_COMMAND_CLIENT_POS], - &sender, sizeof(client_t)); - std::memcpy(&its_command_header[VSOMEIP_COMMAND_SIZE_POS_MIN], - &its_complete_size, sizeof(_size)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - &_instance, sizeof(instance_t)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - &_reliable, sizeof(bool)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - &_status_check, sizeof(uint8_t)); - // Add target client, only relevant for selective notifications - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN], - &_client, sizeof(client_t)); - - return _target->send(its_command_header, _data, _size); + bool _reliable, protocol::id_e _command, uint8_t _status_check) const { + + bool has_sent(false); + + protocol::send_command its_command(_command); + its_command.set_client(get_client()); + its_command.set_instance(_instance); + its_command.set_reliable(_reliable); + its_command.set_status(_status_check); + its_command.set_target(_client); + its_command.set_message(std::vector(_data, _data + _size)); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + + return (has_sent); } bool routing_manager_base::insert_subscription( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client, std::set *_already_subscribed_events) { + event_t _event, const std::shared_ptr &_filter, + client_t _client, std::set *_already_subscribed_events) { + bool is_inserted(false); if (_event != ANY_EVENT) { // subscribe to specific event std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, + is_inserted = its_event->add_subscriber(_eventgroup, _filter, _client, host_->is_routing()); } else { VSOMEIP_WARNING << "routing_manager_base::insert_subscription(" @@ -1255,7 +1280,7 @@ bool routing_manager_base::insert_subscription( << "unoffered) event. Creating placeholder event holding " << "subscription until event is requested/offered."; is_inserted = create_placeholder_event_and_subscribe(_service, - _instance, _eventgroup, _event, _client); + _instance, _eventgroup, _event, _filter, _client); } } else { // subscribe to all events of the eventgroup std::shared_ptr its_eventgroup @@ -1273,7 +1298,7 @@ bool routing_manager_base::insert_subscription( // eventgroups _already_subscribed_events->insert(e->get_event()); } - is_inserted = e->add_subscriber(_eventgroup, _client, + is_inserted = e->add_subscriber(_eventgroup, _filter, _client, host_->is_routing()) || is_inserted; } } @@ -1291,7 +1316,7 @@ bool routing_manager_base::insert_subscription( << "unoffered) eventgroup. Creating placeholder event holding " << "subscription until event is requested/offered."; is_inserted = create_placeholder_event_and_subscribe(_service, - _instance, _eventgroup, _event, _client); + _instance, _eventgroup, _event, _filter, _client); } } return is_inserted; @@ -1305,7 +1330,8 @@ std::shared_ptr routing_manager_base::get_serializer() { << std::hex << std::setw(4) << std::setfill('0') << get_client() << " has no available serializer. Waiting..."; - serializer_condition_.wait(its_lock); + + serializer_condition_.wait(its_lock, [this] { return !serializers_.empty(); }); VSOMEIP_INFO << __func__ << ": Client " << std::hex << std::setw(4) << std::setfill('0') << get_client() @@ -1332,7 +1358,8 @@ std::shared_ptr routing_manager_base::get_deserializer() { while (deserializers_.empty()) { VSOMEIP_INFO << std::hex << "client " << get_client() << "routing_manager_base::get_deserializer ~> all in use!"; - deserializer_condition_.wait(its_lock); + + deserializer_condition_.wait(its_lock, [this] { return !deserializers_.empty(); }); VSOMEIP_INFO << std::hex << "client " << get_client() << "routing_manager_base::get_deserializer ~> wait finished!"; } @@ -1356,8 +1383,8 @@ void routing_manager_base::send_pending_subscriptions(service_t _service, for (auto &ps : pending_subscriptions_) { if (ps.service_ == _service && ps.instance_ == _instance && ps.major_ == _major) { - send_subscribe(client_, ps.service_, ps.instance_, - ps.eventgroup_, ps.major_, ps.event_); + send_subscribe(get_client(), ps.service_, ps.instance_, + ps.eventgroup_, ps.major_, ps.event_, ps.filter_); } } } @@ -1421,6 +1448,47 @@ routing_manager_base::get_subscriptions(const client_t _client) { return result; } +bool +routing_manager_base::get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const { + + std::lock_guard its_lock(guests_mutex_); + auto find_guest = guests_.find(_client); + if (find_guest == guests_.end()) + return (false); + + _address = find_guest->second.first; + _port = find_guest->second.second; + + return (true); +} + +void +routing_manager_base::add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) { + + std::lock_guard its_lock(guests_mutex_); + guests_[_client] = std::make_pair(_address, _port); +} + +void +routing_manager_base::remove_guest(client_t _client) { + + std::lock_guard its_lock(guests_mutex_); + guests_.erase(_client); +} + +void +routing_manager_base::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + (void)_local_port; + (void)_remote_address; + (void)_remote_port; + // dummy method to implement routing_host interface +} + routing_state_e routing_manager_base::get_routing_state() { return routing_state_; diff --git a/implementation/routing/src/routing_manager_client.cpp b/implementation/routing/src/routing_manager_client.cpp new file mode 100644 index 000000000..378ab5d69 --- /dev/null +++ b/implementation/routing/src/routing_manager_client.cpp @@ -0,0 +1,2890 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#if defined(__linux__) || defined(ANDROID) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../include/event.hpp" +#include "../include/routing_manager_host.hpp" +#include "../include/routing_manager_client.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../endpoints/include/netlink_connector.hpp" +#include "../../message/include/deserializer.hpp" +#include "../../message/include/message_impl.hpp" +#include "../../message/include/serializer.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../protocol/include/deregister_application_command.hpp" +#include "../../protocol/include/distribute_security_policies_command.hpp" +#include "../../protocol/include/dummy_command.hpp" +#include "../../protocol/include/expire_command.hpp" +#include "../../protocol/include/offer_service_command.hpp" +#include "../../protocol/include/offered_services_request_command.hpp" +#include "../../protocol/include/offered_services_response_command.hpp" +#include "../../protocol/include/ping_command.hpp" +#include "../../protocol/include/pong_command.hpp" +#include "../../protocol/include/register_application_command.hpp" +#include "../../protocol/include/register_events_command.hpp" +#include "../../protocol/include/registered_ack_command.hpp" +#include "../../protocol/include/release_service_command.hpp" +#include "../../protocol/include/remove_security_policy_command.hpp" +#include "../../protocol/include/remove_security_policy_response_command.hpp" +#include "../../protocol/include/request_service_command.hpp" +#include "../../protocol/include/resend_provided_events_command.hpp" +#include "../../protocol/include/routing_info_command.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../protocol/include/stop_offer_service_command.hpp" +#include "../../protocol/include/subscribe_ack_command.hpp" +#include "../../protocol/include/subscribe_command.hpp" +#include "../../protocol/include/subscribe_nack_command.hpp" +#include "../../protocol/include/unregister_event_command.hpp" +#include "../../protocol/include/unsubscribe_ack_command.hpp" +#include "../../protocol/include/unsubscribe_command.hpp" +#include "../../protocol/include/update_security_credentials_command.hpp" +#include "../../protocol/include/update_security_policy_command.hpp" +#include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../service_discovery/include/runtime.hpp" +#include "../../security/include/policy.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../security/include/security.hpp" +#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/utility.hpp" +#ifdef USE_DLT +#include "../../tracing/include/connector_impl.hpp" +#endif + +namespace vsomeip_v3 { + +routing_manager_client::routing_manager_client(routing_manager_host *_host, + bool _client_side_logging, + const std::set > & _client_side_logging_filter) : + routing_manager_base(_host), + is_connected_(false), + is_started_(false), + state_(inner_state_type_e::ST_DEREGISTERED), + sender_(nullptr), + receiver_(nullptr), + register_application_timer_(io_), + request_debounce_timer_ (io_), + request_debounce_timer_running_(false), + client_side_logging_(_client_side_logging), + client_side_logging_filter_(_client_side_logging_filter) +#if defined(__linux__) || defined(ANDROID) + , is_local_link_available_(false) +#endif // defined(__linux__) || defined(ANDROID) +{ + + char its_hostname[1024]; + if (gethostname(its_hostname, sizeof(its_hostname)) == 0) { + set_client_host(its_hostname); + } +} + +routing_manager_client::~routing_manager_client() { +} + +void routing_manager_client::init() { + routing_manager_base::init(std::make_shared(this, io_, configuration_)); + { + std::lock_guard its_lock(sender_mutex_); + if (configuration_->is_local_routing()) { + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + } else { +#if defined(__linux__) || defined(ANDROID) + auto its_guest_address = configuration_->get_routing_guest_address(); + auto its_host_address = configuration_->get_routing_host_address(); + local_link_connector_ = std::make_shared( + io_, its_guest_address, boost::asio::ip::address(), + (its_guest_address != its_host_address)); + // if the guest is in the same node as the routing manager + // it should not require LINK to be UP to communicate + + if (local_link_connector_) { + local_link_connector_->register_net_if_changes_handler( + std::bind(&routing_manager_client::on_net_state_change, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } +#else + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); +#endif + } + } +} + +void routing_manager_client::start() { + +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + is_started_ = true; + { + std::lock_guard its_lock(sender_mutex_); + if (!sender_) { + // application has been stopped and started again + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + } + if (sender_) { + sender_->start(); + } + } +#if defined(__linux__) || defined(ANDROID) + } else { + if (local_link_connector_) + local_link_connector_->start(); +#endif // __linux__ || ANDROID + } +} + +void routing_manager_client::stop() { + std::unique_lock its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERING) { + register_application_timer_.cancel(); + } + + const std::chrono::milliseconds its_timeout(configuration_->get_shutdown_timeout()); + while (state_ == inner_state_type_e::ST_REGISTERING) { + std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); + if (status == std::cv_status::timeout) { + VSOMEIP_WARNING << std::hex << get_client() << " registering timeout on stop"; + break; + } + } + + if (state_ == inner_state_type_e::ST_REGISTERED) { + deregister_application(); + // Waiting de-register acknowledge to synchronize shutdown + while (state_ == inner_state_type_e::ST_REGISTERED) { + std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); + if (status == std::cv_status::timeout) { + VSOMEIP_WARNING << std::hex << get_client() << " couldn't deregister application - timeout"; + break; + } + } + } + is_started_ = false; + its_lock.unlock(); + +#if defined(__linux__) || defined(ANDROID) + if (local_link_connector_) + local_link_connector_->stop(); +#endif + + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_.cancel(); + } + + if (receiver_) { + receiver_->stop(); + } + receiver_ = nullptr; + + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->stop(); + } + // delete the sender + sender_ = nullptr; + } + + for (const auto client : ep_mgr_->get_connected_clients()) { + if (client != VSOMEIP_ROUTING_CLIENT) { + remove_local(client, true); + } + } + + if (configuration_->is_local_routing()) { + std::stringstream its_client; + its_client << utility::get_base_path(configuration_->get_network()) + << std::hex << get_client(); + #ifdef _WIN32 + ::_unlink(its_client.str().c_str()); + #else + + if (-1 == ::unlink(its_client.str().c_str())) { + VSOMEIP_ERROR<< "routing_manager_proxy::stop unlink failed (" + << its_client.str() << "): "<< std::strerror(errno); + } + #endif + } +} + +#if defined(__linux__) || defined(ANDROID) +void +routing_manager_client::on_net_state_change( + bool _is_interface, const std::string &_name, bool _is_available) { + + VSOMEIP_INFO << __func__ + << ": " << std::boolalpha << _is_interface << " " + << _name << " " + << std::boolalpha << _is_available; + + if (_is_interface) { + if (_is_available) { + if (!is_local_link_available_) { + + is_local_link_available_ = true; + + if (!receiver_) + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + receiver_->start(); + is_started_ = true; + + if (!sender_) + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + sender_->start(); + } + } else { + if (is_local_link_available_) { + is_started_ = false; + + state_ = inner_state_type_e::ST_DEREGISTERED; + on_disconnect(sender_); + + sender_->stop(); + + receiver_->stop(); + + { + std::lock_guard its_lock(local_services_mutex_); + local_services_.clear(); + } + + is_local_link_available_ = false; + } + } + } +} +#endif // __linux__ || ANDROID + +std::shared_ptr routing_manager_client::get_configuration() const { + return host_->get_configuration(); +} + +std::string routing_manager_client::get_env(client_t _client) const { + + std::lock_guard its_known_clients_lock(known_clients_mutex_); + return get_env_unlocked(_client); +} + +std::string routing_manager_client::get_env_unlocked(client_t _client) const { + + auto find_client = known_clients_.find(_client); + if (find_client != known_clients_.end()) { + return (find_client->second); + } + return ""; +} + +bool routing_manager_client::offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + if (!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) { + VSOMEIP_WARNING << "routing_manager_client::offer_service," + << "routing_manager_base::offer_service returned false"; + } + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + send_offer_service(_client, _service, _instance, _major, _minor); + } + protocol::service offer(_service, _instance, _major, _minor ); + pending_offers_.insert(offer); + } + return true; +} + +void routing_manager_client::send_offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + (void)_client; + + protocol::offer_service_command its_offer; + its_offer.set_client(get_client()); + its_offer.set_service(_service); + its_offer.set_instance(_instance); + its_offer.set_major(_major); + its_offer.set_minor(_minor); + + std::vector its_buffer; + protocol::error_e its_error; + its_offer.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": offer_service serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + +} + +void routing_manager_client::stop_offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + (void)_client; + + { + // Hold the mutex to ensure no placeholder event is created inbetween. + std::lock_guard its_lock(stop_mutex_); + + routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor); + clear_remote_subscriber_count(_service, _instance); + + // Note: The last argument does not matter here as a proxy + // does not manage endpoints to the external network. + clear_service_info(_service, _instance, false); + } + + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::stop_offer_service_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_major(_major); + its_command.set_minor(_minor); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": stop offer serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + } + auto it = pending_offers_.begin(); + while (it != pending_offers_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + break; + } + it++; + } + if (it != pending_offers_.end()) pending_offers_.erase(it); + } +} + +void routing_manager_client::request_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + routing_manager_base::request_service(_client, + _service, _instance, _major, _minor); + { + std::lock_guard its_lock(state_mutex_); + size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name()); + protocol::service request = { _service, _instance, _major, _minor }; + if (!request_debouncing_time) { + if (state_ == inner_state_type_e::ST_REGISTERED) { + std::set requests; + requests.insert(request); + send_request_services(requests); + } + requests_.insert(request); + } else { + requests_to_debounce_.insert(request); + std::lock_guard its_lock(request_timer_mutex_); + if (!request_debounce_timer_running_) { + request_debounce_timer_running_ = true; + request_debounce_timer_.expires_from_now(std::chrono::milliseconds(request_debouncing_time)); + request_debounce_timer_.async_wait( + std::bind( + &routing_manager_client::request_debounce_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } + } +} + +void routing_manager_client::release_service(client_t _client, + service_t _service, instance_t _instance) { + routing_manager_base::release_service(_client, _service, _instance); + { + std::lock_guard its_lock(state_mutex_); + remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); + + bool pending(false); + auto it = requests_to_debounce_.begin(); + while (it != requests_to_debounce_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + pending = true; + } + it++; + } + if (it != requests_to_debounce_.end()) requests_to_debounce_.erase(it); + + if (!pending && state_ == inner_state_type_e::ST_REGISTERED) { + send_release_service(_client, _service, _instance); + } + + { + auto it = requests_.begin(); + while (it != requests_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + break; + } + it++; + } + if (it != requests_.end()) requests_.erase(it); + } + } +} + + +void routing_manager_client::register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, const event_type_e _type, + reliability_type_e _reliability, + std::chrono::milliseconds _cycle, bool _change_resets_cycle, + bool _update_on_change, epsilon_change_func_t _epsilon_change_func, + bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) { + + (void)_is_shadow; + (void)_is_cache_placeholder; + + bool is_cyclic(_cycle != std::chrono::milliseconds::zero()); + + const event_data_t registration = { + _service, + _instance, + _notifier, + _type, + _reliability, + _is_provided, + is_cyclic, + _eventgroups + }; + bool is_first(false); + { + std::lock_guard its_lock(state_mutex_); + is_first = pending_event_registrations_.find(registration) + == pending_event_registrations_.end(); +#ifndef VSOMEIP_ENABLE_COMPAT + if (is_first) { + pending_event_registrations_.insert(registration); + } +#else + bool insert = true; + if (is_first) { + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end();) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided + && iter->type_ == event_type_e::ET_EVENT + && _type == event_type_e::ET_SELECTIVE_EVENT) { + iter = pending_event_registrations_.erase(iter); + iter = pending_event_registrations_.insert(registration).first; + is_first = true; + insert = false; + break; + } else { + iter++; + } + } + if (insert) { + pending_event_registrations_.insert(registration); + } + } +#endif + } + if (is_first || _is_provided) { + routing_manager_base::register_event(_client, + _service, _instance, + _notifier, + _eventgroups, _type, _reliability, + _cycle, _change_resets_cycle, _update_on_change, + _epsilon_change_func, + _is_provided); + } + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED && is_first) { + send_register_event(get_client(), _service, _instance, + _notifier, _eventgroups, _type, _reliability, + _is_provided, is_cyclic); + } + } +} + +void routing_manager_client::unregister_event(client_t _client, + service_t _service, instance_t _instance, event_t _notifier, + bool _is_provided) { + + routing_manager_base::unregister_event(_client, _service, _instance, + _notifier, _is_provided); + + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::unregister_event_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_event(_notifier); + its_command.set_provided(_is_provided); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } + + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end(); ) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided) { + pending_event_registrations_.erase(iter); + break; + } else { + iter++; + } + } + } +} + +bool routing_manager_client::is_field(service_t _service, instance_t _instance, + event_t _event) const { + auto event = find_event(_service, _instance, _event); + if (event && event->is_field()) { + return true; + } + return false; +} + +void routing_manager_client::subscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + (void)_client; + + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { + send_subscribe(get_client(), _service, _instance, _eventgroup, _major, _event, _filter ); + } + subscription_data_t subscription = { + _service, _instance, + _eventgroup, _major, + _event, _filter, + *_sec_client + }; + pending_subscriptions_.insert(subscription); +} + +void routing_manager_client::send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + if (_event == ANY_EVENT) { + if (!is_subscribe_to_any_event_allowed(get_sec_client(), _client, _service, _instance, _eventgroup)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client + << " : routing_manager_proxy::subscribe: " + << " isn't allowed to subscribe to service/instance/event " + << _service << "/" << _instance << "/ANY_EVENT" + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + get_sec_client(), _service, _instance, _event)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client + << " : routing_manager_proxy::subscribe: " + << " isn't allowed to subscribe to service/instance/event " + << _service << "/" << _instance + << "/" << _event; + return; + } + } + + protocol::subscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(_major); + its_command.set_event(_event); + its_command.set_pending_id(PENDING_SUBSCRIPTION_ID); + its_command.set_filter(_filter); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + client_t its_target_client = find_local_client(_service, _instance); + if (its_target_client != VSOMEIP_ROUTING_CLIENT) { + auto its_target = ep_mgr_->find_or_create_local(its_target_client); + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_subscribe_nack(client_t _subscriber, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, remote_subscription_id_t _id) { + + protocol::subscribe_nack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_subscriber); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (_subscriber != VSOMEIP_ROUTING_CLIENT + && _id == PENDING_SUBSCRIPTION_ID) { + auto its_target = ep_mgr_->find_local(_subscriber); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + return; + } + } + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe nack serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_subscribe_ack(client_t _subscriber, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, remote_subscription_id_t _id) { + + protocol::subscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_subscriber); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (_subscriber != VSOMEIP_ROUTING_CLIENT + && _id == PENDING_SUBSCRIPTION_ID) { + auto its_target = ep_mgr_->find_local(_subscriber); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + return; + } + } + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe ack serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + + (void)_client; + (void)_sec_client; + + { + std::lock_guard its_lock(state_mutex_); + remove_pending_subscription(_service, _instance, _eventgroup, _event); + + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::unsubscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(ANY_MAJOR); + its_command.set_event(_event); + its_command.set_pending_id(PENDING_SUBSCRIPTION_ID); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_target = ep_mgr_->find_local(_service, _instance); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + + VSOMEIP_ERROR << __func__ + << ": unsubscribe serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + } + } +} + +bool routing_manager_client::send(client_t _client, const byte_t *_data, + length_t _size, instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, bool _force) { + + (void)_client; + (void)_bound_client; + (void)_sec_client; + (void)_sent_from_remote; + bool is_sent(false); + bool has_remote_subscribers(false); + { + std::lock_guard its_lock(state_mutex_); + if (state_ != inner_state_type_e::ST_REGISTERED) { + return false; + } + } + if (client_side_logging_) { + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { + service_t its_service = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SERVICE_POS_MIN], + _data[VSOMEIP_SERVICE_POS_MAX]); + if (client_side_logging_filter_.empty() + || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE))) + || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) { + method_t its_method = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_METHOD_POS_MIN], + _data[VSOMEIP_METHOD_POS_MAX]); + session_t its_session = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SESSION_POS_MIN], + _data[VSOMEIP_SESSION_POS_MAX]); + client_t its_client = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + VSOMEIP_INFO << "routing_manager_client::send: (" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_session << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "] " + << "type=" << std::hex << static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]) + << " thread=" << std::hex << std::this_thread::get_id(); + } + } else { + VSOMEIP_ERROR << "routing_manager_client::send: (" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + <<"): message too short to log: " << std::dec << _size; + } + } + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { + std::shared_ptr its_target; + if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + // Request + service_t its_service = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SERVICE_POS_MIN], + _data[VSOMEIP_SERVICE_POS_MAX]); + client_t its_client = find_local_client(its_service, _instance); + if (its_client != VSOMEIP_ROUTING_CLIENT) { + if (is_client_known(its_client)) { + its_target = ep_mgr_->find_or_create_local(its_client); + } + } + } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + // Response + client_t its_client = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + if (its_client != VSOMEIP_ROUTING_CLIENT) { + if (is_client_known(its_client)) { + its_target = ep_mgr_->find_or_create_local(its_client); + } + } + } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && + _client == VSOMEIP_ROUTING_CLIENT) { + // notify + has_remote_subscribers = send_local_notification(get_client(), _data, _size, + _instance, _reliable, _status_check, _force); + } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && + _client != VSOMEIP_ROUTING_CLIENT) { + // notify_one + its_target = ep_mgr_->find_local(_client); + if (its_target) { +#ifdef USE_DLT + trace::header its_header; + if (its_header.prepare(nullptr, true, _instance)) + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); +#endif + return send_local(its_target, get_client(), _data, _size, + _instance, _reliable, protocol::id_e::SEND_ID, _status_check); + } + } + // If no direct endpoint could be found + // or for notifications ~> route to routing_manager_stub +#ifdef USE_DLT + bool message_to_stub(false); +#endif + if (!its_target) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + its_target = sender_; +#ifdef USE_DLT + message_to_stub = true; +#endif + } else { + return false; + } + } + + bool send(true); + protocol::id_e its_command(protocol::id_e::SEND_ID); + + if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (_client != VSOMEIP_ROUTING_CLIENT) { + its_command = protocol::id_e::NOTIFY_ONE_ID; + } else { + its_command = protocol::id_e::NOTIFY_ID; + // Do we need to deliver a notification to the routing manager? + // Only for services which already have remote clients subscribed to + send = has_remote_subscribers; + } + } +#ifdef USE_DLT + else if (!message_to_stub) { + trace::header its_header; + if (its_header.prepare(nullptr, true, _instance)) + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); + } +#endif + if (send) { + is_sent = send_local(its_target, + (its_command == protocol::id_e::NOTIFY_ONE_ID ? _client : get_client()), + _data, _size, _instance, _reliable, its_command, _status_check); + } + } + return (is_sent); +} + +bool routing_manager_client::send_to(const client_t _client, + const std::shared_ptr &_target, + std::shared_ptr _message) { + + (void)_client; + (void)_target; + (void)_message; + + return (false); +} + +bool routing_manager_client::send_to( + const std::shared_ptr &_target, + const byte_t *_data, uint32_t _size, instance_t _instance) { + + (void)_target; + (void)_data; + (void)_size; + (void)_instance; + + return (false); +} + +void routing_manager_client::on_connect(const std::shared_ptr& _endpoint) { + + _endpoint->set_connected(true); + _endpoint->set_established(true); + { + std::lock_guard its_lock(sender_mutex_); + if (_endpoint != sender_) { + return; + } + } + is_connected_ = true; + assign_client(); +} + +void routing_manager_client::on_disconnect(const std::shared_ptr& _endpoint) { + { + std::lock_guard its_lock(sender_mutex_); + is_connected_ = !(_endpoint == sender_); + } + if (!is_connected_) { + VSOMEIP_INFO << "routing_manager_client::on_disconnect: Client 0x" << std::hex + << get_client() << " calling host_->on_state " + << "with DEREGISTERED"; + host_->on_state(state_type_e::ST_DEREGISTERED); + } +} + +void routing_manager_client::on_message( + const byte_t *_data, length_t _size, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port) { + + (void)_receiver; + (void)_is_multicast; + (void)_remote_address; + (void)_remote_port; + +#if 0 + std::stringstream msg; + msg << "rmp::on_message<" << std::hex << get_client() << ">: "; + for (length_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + protocol::id_e its_id; + client_t its_client; + service_t its_service; + instance_t its_instance; + eventgroup_t its_eventgroup; + event_t its_event; + major_version_t its_major; + client_t routing_host_id = configuration_->get_id( + configuration_->get_routing_host_name()); + client_t its_subscriber; + remote_subscription_id_t its_pending_id(PENDING_SUBSCRIPTION_ID); + std::uint32_t its_remote_subscriber_count(0); +#ifndef VSOMEIP_DISABLE_SECURITY + bool is_internal_policy_update(false); +#endif // !VSOMEIP_DISABLE_SECURITY + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + protocol::dummy_command its_dummy_command; + its_dummy_command.deserialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + its_id = its_dummy_command.get_id(); + its_client = its_dummy_command.get_client(); + + bool is_from_routing(false); + if (configuration_->is_security_enabled()) { + if (configuration_->is_local_routing()) { + // if security is enabled, client ID of routing must be configured + // and credential passing is active. Otherwise bound client is zero by default + is_from_routing = (_bound_client == routing_host_id); + } else { + is_from_routing = (_remote_address == configuration_->get_routing_host_address() + && _remote_port == configuration_->get_routing_host_port() + 1); + } + } else { + is_from_routing = (its_client == routing_host_id); + } + + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && !is_from_routing && _bound_client != its_client) { + VSOMEIP_WARNING << std::hex << "Client " + << std::setw(4) << std::setfill('0') << get_client() + << " received a message with command " << int(its_id) + << " from " << std::setw(4) << std::setfill('0') + << its_client << " which doesn't match the bound client " + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } + + switch (its_id) { + case protocol::id_e::SEND_ID: + { + protocol::send_command its_send_command(protocol::id_e::SEND_ID); + its_send_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto a_deserializer = get_deserializer(); + a_deserializer->set_data(its_send_command.get_message()); + std::shared_ptr its_message(a_deserializer->deserialize_message()); + a_deserializer->reset(); + put_deserializer(a_deserializer); + + if (its_message) { + its_message->set_instance(its_send_command.get_instance()); + its_message->set_reliable(its_send_command.is_reliable()); + its_message->set_check_result(its_send_command.get_status()); + if (_sec_client) + its_message->set_sec_client(*_sec_client); + its_message->set_env(get_env(_bound_client)); + + if (!is_from_routing) { + if (utility::is_notification(its_message->get_message_type())) { + if (!is_response_allowed(_bound_client, its_message->get_service(), + its_message->get_instance(), its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a notification from client 0x" << _bound_client + << " which does not offer service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; + return; + } + cache_event_payload(its_message); + } + } else if (utility::is_request(its_message->get_message_type())) { + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && its_message->get_client() != _bound_client) { + VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client() + << " received a request from client 0x" << std::setw(4) << std::setfill('0') + << its_message->get_client() << " to service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() << " which doesn't match the bound client 0x" + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client() + << " : routing_manager_client::on_message: " + << "isn't allowed to send a request to service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } + } else { // response + if (!is_response_allowed(_bound_client, its_message->get_service(), + its_message->get_instance(), its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a response from client 0x" << _bound_client + << " which does not offer service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a response from service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; + return; + } + } + } + } else { + if (!configuration_->is_remote_access_allowed()) { + // if the message is from routing manager, check if + // policy allows remote requests. + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client + << " are not allowed to communicate with service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively with client 0x" << get_client() + << " ~> Skip message!"; + return; + } else if (utility::is_notification(its_message->get_message_type())) { + // As subscription is sent on eventgroup level, incoming remote event ID's + // need to be checked as well if remote clients are allowed + // and the local policy only allows specific events in the eventgroup to be received. + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from remote clients via routing manager with client ID 0x" + << routing_host_id + << " ~> Skip message!"; + return; + } + cache_event_payload(its_message); + } + } + #ifdef USE_DLT + if (client_side_logging_ + && (client_side_logging_filter_.empty() + || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), ANY_INSTANCE))) + || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), its_message->get_instance()))))) { + trace::header its_header; + if (its_header.prepare(nullptr, false, its_send_command.get_instance())) { + uint32_t its_message_size = its_send_command.get_size(); + if (its_message_size >= uint32_t{vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE}) + its_message_size -= uint32_t{vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE}; + else + its_message_size = 0; + + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + &_data[vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE], its_message_size); + } + } + #endif + + host_->on_message(std::move(its_message)); + } else + VSOMEIP_ERROR << "Routing proxy: on_message: " + << "SomeIP-Header deserialization failed!"; + } else + VSOMEIP_ERROR << __func__ + << ": send command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::ASSIGN_CLIENT_ACK_ID: + { + client_t its_assigned_client(VSOMEIP_CLIENT_UNSET); + protocol::assign_client_ack_command its_ack_command; + its_ack_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + its_assigned_client = its_ack_command.get_assigned(); + + on_client_assign_ack(its_assigned_client); + break; + } + + case protocol::id_e::ROUTING_INFO_ID: + if (!configuration_->is_security_enabled() || is_from_routing) { + on_routing_info(_data, _size); + } else { + VSOMEIP_WARNING << "routing_manager_client::on_message: " + << std::hex << "Security: Client 0x" << get_client() + << " received an routing info from a client which isn't the routing manager" + << " : Skip message!"; + } + break; + + case protocol::id_e::PING_ID: + { + protocol::ping_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + send_pong(); + VSOMEIP_TRACE << "PING(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": ping command deserialization failed (" + << std::dec << int(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ID: + { + protocol::subscribe_command its_subscribe_command; + its_subscribe_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_command.get_service(); + its_instance = its_subscribe_command.get_instance(); + its_eventgroup = its_subscribe_command.get_eventgroup(); + its_major = its_subscribe_command.get_major(); + its_event = its_subscribe_command.get_event(); + its_pending_id = its_subscribe_command.get_pending_id(); + auto its_filter = its_subscribe_command.get_filter(); + + std::unique_lock its_lock(incoming_subscriptions_mutex_); + if (its_pending_id != PENDING_SUBSCRIPTION_ID) { + its_lock.unlock(); +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); +#endif + // Remote subscriber: Notify routing manager initially + count subscribes + auto self = shared_from_this(); + host_->on_subscription(its_service, its_instance, its_eventgroup, + its_client, _sec_client, get_env(its_client), true, + [this, self, its_client, its_service, its_instance, + its_eventgroup, its_event, its_filter, its_pending_id, its_major] + (const bool _subscription_accepted) { + + std::uint32_t its_count(0); + if (_subscription_accepted) { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, its_pending_id); + std::set its_already_subscribed_events; + bool inserted = insert_subscription(its_service, its_instance, its_eventgroup, + its_event, its_filter, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events); + if (inserted) { + notify_remote_initially(its_service, its_instance, its_eventgroup, + its_already_subscribed_events); + } + #ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true); + #endif + its_count = get_remote_subscriber_count( + its_service, its_instance, its_eventgroup, true); + } else { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, its_pending_id); + } + VSOMEIP_INFO << "SUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" + << std::dec << (uint16_t)its_major << "] " + << std::boolalpha << (its_pending_id != PENDING_SUBSCRIPTION_ID) + << " " + << (_subscription_accepted ? + std::to_string(its_count) + " accepted." : "not accepted."); + +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event); +#endif + }); + } else if (is_client_known(its_client)) { + its_lock.unlock(); + if (!is_from_routing) { + if (its_event == ANY_EVENT) { + if (!is_subscribe_to_any_event_allowed(_sec_client, its_client, its_service, its_instance, its_eventgroup)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << " isn't allowed to subscribe to service/instance/event " + << its_service << "/" << its_instance << "/ANY_EVENT" + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_event)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << " subscribes to service/instance/event " + << its_service << "/" << its_instance << "/" << its_event + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } + } else { + if (!configuration_->is_remote_access_allowed()) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << std::hex << "Routing manager with client ID 0x" + << its_client + << " isn't allowed to subscribe to service/instance/event " + << its_service << "/" << its_instance + << "/" << its_event + << " respectively to client 0x" << get_client() + << " ~> Skip Subscribe!"; + return; + } + } + + // Local & already known subscriber: create endpoint + send (N)ACK + insert subscription +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); +#endif + (void) ep_mgr_->find_or_create_local(its_client); + auto self = shared_from_this(); + auto its_env = get_env(its_client); + host_->on_subscription(its_service, its_instance, + its_eventgroup, its_client, _sec_client, its_env, true, + [this, self, its_client, its_filter, _sec_client, its_env, its_service, + its_instance, its_eventgroup, its_event, its_major] + (const bool _subscription_accepted) { + if (!_subscription_accepted) { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); + } else { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); + routing_manager_base::subscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_major, its_event, its_filter); +#ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client); +#endif + } +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event); +#endif + }); + } else { + if (_sec_client) { + // Local & not yet known subscriber ~> set pending until subscriber gets known! + subscription_data_t subscription = { + its_service, its_instance, + its_eventgroup, its_major, + its_event, its_filter, + *_sec_client + }; + pending_incoming_subscriptions_[its_client].insert(subscription); + } else { + VSOMEIP_WARNING << __func__ + << ": Local subscription without security info."; + } + } + + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { // local subscription + VSOMEIP_INFO << "SUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" + << std::dec << (uint16_t)its_major << "]"; + } + } else { + VSOMEIP_ERROR << __func__ + << ": subscribe command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + break; + } + + case protocol::id_e::UNSUBSCRIBE_ID: + { + protocol::unsubscribe_command its_unsubscribe; + its_unsubscribe.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_unsubscribe.get_client(); + its_service = its_unsubscribe.get_service(); + its_instance = its_unsubscribe.get_instance(); + its_eventgroup = its_unsubscribe.get_eventgroup(); + its_event = its_unsubscribe.get_event(); + its_pending_id = its_unsubscribe.get_pending_id(); + + host_->on_subscription(its_service, its_instance, its_eventgroup, + its_client, _sec_client, get_env(its_client), false, + [](const bool _subscription_accepted){ + (void)_subscription_accepted; + } + ); + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { + // Local subscriber: withdraw subscription + routing_manager_base::unsubscribe(its_client, _sec_client, its_service, its_instance, its_eventgroup, its_event); + } else { + // Remote subscriber: withdraw subscription only if no more remote subscriber exists + its_remote_subscriber_count = get_remote_subscriber_count(its_service, + its_instance, its_eventgroup, false); + if (!its_remote_subscriber_count) { + routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, nullptr, its_service, + its_instance, its_eventgroup, its_event); + } + send_unsubscribe_ack(its_service, its_instance, its_eventgroup, its_pending_id); + } + VSOMEIP_INFO << "UNSUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " + << (bool)(its_pending_id != PENDING_SUBSCRIPTION_ID) << " " + << std::dec << its_remote_subscriber_count; + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::EXPIRE_ID: + { + protocol::expire_command its_expire; + its_expire.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_expire.get_client(); + its_service = its_expire.get_service(); + its_instance = its_expire.get_instance(); + its_eventgroup = its_expire.get_eventgroup(); + its_event = its_expire.get_event(); + its_pending_id = its_expire.get_pending_id(); + + host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, + _sec_client, get_env(its_client), false, + [](const bool _subscription_accepted){ (void)_subscription_accepted; }); + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { + // Local subscriber: withdraw subscription + routing_manager_base::unsubscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_event); + } else { + // Remote subscriber: withdraw subscription only if no more remote subscriber exists + its_remote_subscriber_count = get_remote_subscriber_count(its_service, + its_instance, its_eventgroup, false); + if (!its_remote_subscriber_count) { + routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, nullptr, + its_service, its_instance, its_eventgroup, its_event); + } + } + VSOMEIP_INFO << "EXPIRED SUBSCRIPTION(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " + << (bool)(its_pending_id != PENDING_SUBSCRIPTION_ID) << " " + << std::dec << its_remote_subscriber_count; + } else + VSOMEIP_ERROR << __func__ + << ": expire deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_NACK_ID: + { + protocol::subscribe_nack_command its_subscribe_nack; + its_subscribe_nack.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_nack.get_service(); + its_instance = its_subscribe_nack.get_instance(); + its_eventgroup = its_subscribe_nack.get_eventgroup(); + its_subscriber = its_subscribe_nack.get_subscriber(); + its_event = its_subscribe_nack.get_event(); + + on_subscribe_nack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); + VSOMEIP_INFO << "SUBSCRIBE NACK(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; + } else + VSOMEIP_ERROR << __func__ + << ": subscribe nack command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ACK_ID: + { + protocol::subscribe_ack_command its_subscribe_ack; + its_subscribe_ack.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_ack.get_service(); + its_instance = its_subscribe_ack.get_instance(); + its_eventgroup = its_subscribe_ack.get_eventgroup(); + its_subscriber = its_subscribe_ack.get_subscriber(); + its_event = its_subscribe_ack.get_event(); + + on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); + VSOMEIP_INFO << "SUBSCRIBE ACK(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::OFFERED_SERVICES_RESPONSE_ID: + { + protocol::offered_services_response_command its_response; + its_response.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (!configuration_->is_security_enabled() || is_from_routing) { + on_offered_services_info(its_response); + } else { + VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client() + << " received an offered services info from a client which isn't the routing manager" + << " : Skip message!"; + } + } else + VSOMEIP_ERROR << __func__ + << ": offered services response command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + case protocol::id_e::RESEND_PROVIDED_EVENTS_ID: + { + protocol::resend_provided_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + resend_provided_event_registrations(); + send_resend_provided_event_response(its_command.get_remote_offer_id()); + + VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" + << std::hex << std::setw(4) << std::setfill('0') + << its_command.get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": resend provided events command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + case protocol::id_e::SUSPEND_ID: + { + on_suspend(); // cleanup remote subscribers + break; + } +#ifndef VSOMEIP_DISABLE_SECURITY + case protocol::id_e::UPDATE_SECURITY_POLICY_INT_ID: + is_internal_policy_update = true; + [[gnu::fallthrough]]; + case protocol::id_e::UPDATE_SECURITY_POLICY_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::update_security_policy_command its_command(is_internal_policy_update); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + auto its_policy = its_command.get_policy(); + uint32_t its_uid; + uint32_t its_gid; + if (its_policy->get_uid_gid(its_uid, its_gid)) { + if (is_internal_policy_update + || its_security->is_policy_update_allowed(its_uid, its_policy)) { + its_security->update_security_policy(its_uid, its_gid, its_policy); + send_update_security_policy_response(its_command.get_update_id()); + } + } else { + VSOMEIP_ERROR << "vSomeIP Security: Policy has no valid uid/gid!"; + } + } else { + VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!"; + } + } else { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy update from a client which isn't the routing manager" + << " : Skip message!"; + } + break; + } + + case protocol::id_e::REMOVE_SECURITY_POLICY_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::remove_security_policy_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + uid_t its_uid(its_command.get_uid()); + gid_t its_gid(its_command.get_gid()); + + if (its_security->is_policy_removal_allowed(its_uid)) { + its_security->remove_security_policy(its_uid, its_gid); + send_remove_security_policy_response(its_command.get_update_id()); + } + } else + VSOMEIP_ERROR << __func__ + << ": remove security policy command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << "received a security policy removal from a client which isn't the routing manager" + << " : Skip message!"; + break; + } + + case protocol::id_e::DISTRIBUTE_SECURITY_POLICIES_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::distribute_security_policies_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + for (auto p : its_command.get_policies()) { + uid_t its_uid; + gid_t its_gid; + p->get_uid_gid(its_uid, its_gid); + if (its_security->is_policy_update_allowed(its_uid, p)) + its_security->update_security_policy(its_uid, its_gid, p); + } + } else + VSOMEIP_ERROR << __func__ + << ": distribute security policies command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy distribution command from a client which isn't the routing manager" + << " : Skip message!"; + break; + } + + case protocol::id_e::UPDATE_SECURITY_CREDENTIALS_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::update_security_credentials_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_update_security_credentials(its_command); + } else + VSOMEIP_ERROR << __func__ + << ": update security credentials command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << "received a security credential update from a client which isn't the routing manager" + << " : Skip message!"; + + break; + } +#endif // !VSOMEIP_DISABLE_SECURITY + default: + break; + } + } else + VSOMEIP_ERROR << __func__ + << ": dummy command deserialization failed (" + << std::dec << static_cast(its_error) + << ")"; +} + +void routing_manager_client::on_routing_info( + const byte_t *_data, uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "rmp::on_routing_info(" << std::hex << get_client() << "): "; + for (uint32_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + protocol::routing_info_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": deserializing routing info command failed (" + << static_cast(its_error) + << ")"; + return; + } + + for (const auto &e : its_command.get_entries()) { + auto its_client = e.get_client(); + switch (e.get_type()) { + case protocol::routing_info_entry_type_e::RIE_ADD_CLIENT: + { + auto its_address = e.get_address(); + if (!its_address.is_unspecified()) { + add_guest(its_client, its_address, e.get_port()); + add_known_client(its_client, ""); + } + + if (its_client == get_client()) { + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + << " (" << host_->get_name() << ") is registered."; +#if defined(__linux__) || defined(ANDROID) + if (!its_security->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_routing_info: RIE_ADD_CLIENT: isn't allowed" + << " to use the server endpoint due to credential check failed!"; + deregister_application(); + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + return; + } +#endif + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERING) { + boost::system::error_code ec; + register_application_timer_.cancel(ec); + send_registered_ack(); + send_pending_commands(); + state_ = inner_state_type_e::ST_REGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + } + + // inform host about its own registration state changes + if (state_ == inner_state_type_e::ST_REGISTERED) { + host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); + } + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT: + { + { + std::lock_guard its_lock(known_clients_mutex_); + known_clients_.erase(its_client); + } + if (its_client == get_client()) { + its_security->remove_client_to_sec_client_mapping(its_client); + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + << " (" << host_->get_name() << ") is deregistered."; + + // inform host about its own registration state changes + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + + { + std::lock_guard its_lock(state_mutex_); + state_ = inner_state_type_e::ST_DEREGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + } else if (its_client != VSOMEIP_ROUTING_CLIENT) { + remove_local(its_client, true); + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE: + { + auto its_address = e.get_address(); + if (!its_address.is_unspecified()) { + add_guest(its_client, its_address, e.get_port()); + add_known_client(its_client, ""); + } + { + // Add yet unknown clients that offer services. Otherwise, + // the service cannot be used. The entry will be overwritten, + // when the offering clients connects. + std::lock_guard its_lock(known_clients_mutex_); + if (known_clients_.find(its_client) == known_clients_.end()) { + known_clients_[its_client] = ""; + } + } + + for (const auto &s : e.get_services()) { + + const auto its_service(s.service_); + const auto its_instance(s.instance_); + const auto its_major(s.major_); + const auto its_minor(s.minor_); + + { + std::lock_guard its_lock(local_services_mutex_); + + // Check whether the service instance is already known. If yes, + // continue with the next service within the routing info. + auto found_service = local_services_.find(its_service); + if (found_service != local_services_.end()) { + if (found_service->second.find(its_instance) != found_service->second.end()) + continue; + } + + local_services_[its_service][its_instance] + = std::make_tuple(its_major, its_minor, its_client); + } + { + std::lock_guard its_lock(state_mutex_); + send_pending_subscriptions(its_service, its_instance, its_major); + } + host_->on_availability(its_service, its_instance, + availability_state_e::AS_AVAILABLE, its_major, its_minor); + VSOMEIP_INFO << "ON_AVAILABLE(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE: + { + for (const auto &s : e.get_services()) { + const auto its_service(s.service_); + const auto its_instance(s.instance_); + const auto its_major(s.major_); + const auto its_minor(s.minor_); + + { + std::lock_guard its_lock(local_services_mutex_); + auto found_service = local_services_.find(its_service); + if (found_service != local_services_.end()) { + found_service->second.erase(its_instance); + // move previously offering client to history + local_services_history_[its_service][its_instance].insert(its_client); + if (found_service->second.size() == 0) { + local_services_.erase(its_service); + } + } + } + on_stop_offer_service(its_service, its_instance, its_major, its_minor); + host_->on_availability(its_service, its_instance, + availability_state_e::AS_UNAVAILABLE, its_major, its_minor); + VSOMEIP_INFO << "ON_UNAVAILABLE(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; + } + break; + } + + default: + VSOMEIP_ERROR << __func__ + << ": Unknown routing info entry type (" + << static_cast(e.get_type()) + << ")"; + break; + } + } + + { + struct subscription_info { + service_t service_id_; + instance_t instance_id_; + eventgroup_t eventgroup_id_; + client_t client_id_; + major_version_t major_; + event_t event_; + std::shared_ptr filter_; + vsomeip_sec_client_t sec_client_; + std::string env_; + }; + std::lock_guard its_lock(incoming_subscriptions_mutex_); + std::forward_list subscription_actions; + if (pending_incoming_subscriptions_.size()) { + { + std::lock_guard its_lock(known_clients_mutex_); + for (const auto &k : known_clients_) { + auto its_client = pending_incoming_subscriptions_.find(k.first); + if (its_client != pending_incoming_subscriptions_.end()) { + for (const auto &subscription : its_client->second) { + subscription_actions.push_front( + { subscription.service_, subscription.instance_, + subscription.eventgroup_, k.first, + subscription.major_, subscription.event_, + subscription.filter_, + subscription.sec_client_, + get_env_unlocked(k.first)}); + } + } + } + } + for (const subscription_info &si : subscription_actions) { +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_, + si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING); +#endif + (void) ep_mgr_->find_or_create_local(si.client_id_); + auto self = shared_from_this(); + host_->on_subscription( + si.service_id_, si.instance_id_, si.eventgroup_id_, + si.client_id_, &si.sec_client_, si.env_, true, + [this, self, si](const bool _subscription_accepted) { + if (!_subscription_accepted) { + send_subscribe_nack(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); + } else { + send_subscribe_ack(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); + routing_manager_base::subscribe(si.client_id_, &si.sec_client_, + si.service_id_, si.instance_id_, si.eventgroup_id_, + si.major_, si.event_, si.filter_); +#ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(si.service_id_, + si.instance_id_, si.eventgroup_id_, si.client_id_); +#endif + } +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_); +#endif + { + std::lock_guard its_lock2(incoming_subscriptions_mutex_); + pending_incoming_subscriptions_.erase(si.client_id_); + } + }); + } + } + } +} + +void routing_manager_client::on_offered_services_info( + protocol::offered_services_response_command &_command) { + + std::vector> its_offered_services_info; + + for (const auto &s : _command.get_services()) + its_offered_services_info.push_back(std::make_pair(s.service_, s.instance_)); + + host_->on_offered_services_info(its_offered_services_info); +} + +void routing_manager_client::reconnect(const std::map &_clients) { + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + // inform host about its own registration state changes + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + + { + std::lock_guard its_lock(state_mutex_); + state_ = inner_state_type_e::ST_DEREGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + + + // Remove all local connections/endpoints + for (const auto &c : _clients) { + if (c.first != VSOMEIP_ROUTING_CLIENT) { + remove_local(c.first, true); + } + } + + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + <<": Reconnecting to routing manager."; + +#if defined(__linux__) || defined(ANDROID) + if (!its_security->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::reconnect: isn't allowed" + << " to use the server endpoint due to credential check failed!"; + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->stop(); + } + return; + } +#endif + + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->restart(); + } +} + +void routing_manager_client::assign_client() { + + protocol::assign_client_command its_command; + its_command.set_client(get_client()); + its_command.set_name(host_->get_name()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error != protocol::error_e::ERROR_OK) { + + VSOMEIP_ERROR << __func__ << ": command creation failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + std::lock_guard its_state_lock(state_mutex_); + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + if (state_ != inner_state_type_e::ST_DEREGISTERED) + return; + state_ = inner_state_type_e::ST_ASSIGNING; + + sender_->send(&its_buffer[0], static_cast(its_buffer.size())); + + boost::system::error_code ec; + register_application_timer_.cancel(ec); + register_application_timer_.expires_from_now(std::chrono::milliseconds(10000)); + register_application_timer_.async_wait( + std::bind( + &routing_manager_client::assign_client_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } +} + +void routing_manager_client::register_application() { + + if (!receiver_) { + VSOMEIP_ERROR << __func__ + << "Cannot register. Local server endpoint does not exist."; + return; + } + + auto its_configuration(get_configuration()); + if (its_configuration->is_local_routing()) { + VSOMEIP_INFO << "Registering to routing manager @ " + << its_configuration->get_network() << "-0"; + } else { + auto its_routing_address(its_configuration->get_routing_host_address()); + auto its_routing_port(its_configuration->get_routing_host_port()); + VSOMEIP_INFO << "Registering to routing manager @ " + << its_routing_address.to_string() << ":" << its_routing_port; + } + + protocol::register_application_command its_command; + its_command.set_client(get_client()); + its_command.set_port(receiver_->get_local_port()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + state_ = inner_state_type_e::ST_REGISTERING; + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + + register_application_timer_.cancel(); + register_application_timer_.expires_from_now(std::chrono::milliseconds(1000)); + register_application_timer_.async_wait( + std::bind( + &routing_manager_client::register_application_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": register application command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::deregister_application() { + + protocol::deregister_application_command its_command; + its_command.set_client(get_client()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": deregister application command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_pong() const { + + protocol::pong_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": pong command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_request_services(const std::set &_requests) { + + if (!_requests.size()) { + return; + } + + protocol::request_service_command its_command; + its_command.set_client(get_client()); + its_command.set_services(_requests); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": request service serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_release_service(client_t _client, service_t _service, + instance_t _instance) { + + (void)_client; + + protocol::release_service_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } +} + +void routing_manager_client::send_pending_event_registrations(client_t _client) { + + protocol::register_events_command its_command; + its_command.set_client(_client); + std::set::iterator it = pending_event_registrations_.begin(); + + while(it != pending_event_registrations_.end()) + { + for(; it!=pending_event_registrations_.end(); it++) { + protocol::register_event reg(it->service_, it->instance_, it->notifier_, it->type_, + it->is_provided_, it->reliability_, it->is_cyclic_ + , (uint16_t)it->eventgroups_.size(), it->eventgroups_); + if(!its_command.add_registration(reg)) {break;} + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": register event command serialization failed (" + << std::dec << int(its_error) << ")"; + } +} + +void routing_manager_client::send_register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, const event_type_e _type, + reliability_type_e _reliability, + bool _is_provided, bool _is_cyclic) { + + (void)_client; + + protocol::register_events_command its_command; + its_command.set_client(get_client()); + + protocol::register_event reg(_service, _instance, _notifier, _type, + _is_provided, _reliability, _is_cyclic, + (uint16_t)_eventgroups.size(), _eventgroups); + + if(!its_command.add_registration(reg)) { + VSOMEIP_ERROR << __func__ << ": register event command is too long."; + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + + if (_is_provided) { + VSOMEIP_INFO << "REGISTER EVENT(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() << "): [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _notifier + << ":is_provider=" << std::boolalpha << _is_provided << "]"; + } + } else + VSOMEIP_ERROR << __func__ + << ": register event command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::on_subscribe_ack(client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + (void)_client; +#if 0 + VSOMEIP_ERROR << "routing_manager_client::" << __func__ + << "(" << std::hex << host_->get_client() << "):" + << "event=" + << std::hex << _service << "." + << std::hex << _instance << "." + << std::hex << _eventgroup << "." + << std::hex << _event; +#endif + if (_event == ANY_EVENT) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + for (const auto& its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/); + } + } + } else { + host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); + } +} + +void routing_manager_client::on_subscribe_nack(client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + (void)_client; + if (_event == ANY_EVENT) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + for (const auto& its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/); + } + } + } else { + host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/); + } +} + +void routing_manager_client::cache_event_payload( + const std::shared_ptr &_message) { + const service_t its_service(_message->get_service()); + const instance_t its_instance(_message->get_instance()); + const method_t its_method(_message->get_method()); + std::shared_ptr its_event = find_event(its_service, its_instance, its_method); + if (its_event) { + if (its_event->is_field()) { + its_event->prepare_update_payload(_message->get_payload(), true); + its_event->update_payload(); + } + } else { + // we received a event which was not yet requested + std::set its_eventgroups; + // create a placeholder field until someone requests this event with + // full information like eventgroup, field or not etc. + routing_manager_base::register_event(host_->get_client(), + its_service, its_instance, + its_method, + its_eventgroups, event_type_e::ET_UNKNOWN, + reliability_type_e::RT_UNKNOWN, + std::chrono::milliseconds::zero(), false, true, + nullptr, + false, false, true); + std::shared_ptr its_event = find_event(its_service, its_instance, its_method); + if (its_event) { + its_event->prepare_update_payload(_message->get_payload(), true); + its_event->update_payload(); + } + } +} + +void routing_manager_client::on_stop_offer_service(service_t _service, + instance_t _instance, + major_version_t _major, + minor_version_t _minor) { + (void) _major; + (void) _minor; + std::map > events; + { + std::lock_guard its_lock(events_mutex_); + auto its_events_service = events_.find(_service); + if (its_events_service != events_.end()) { + auto its_events_instance = its_events_service->second.find(_instance); + if (its_events_instance != its_events_service->second.end()) { + for (auto &e : its_events_instance->second) + events[e.first] = e.second; + } + } + } + for (auto &e : events) { + e.second->unset_payload(); + } +} + +void routing_manager_client::send_pending_commands() { + for (auto &po : pending_offers_) + send_offer_service(get_client(), + po.service_, po.instance_, + po.major_, po.minor_); + + send_pending_event_registrations(get_client()); + + send_request_services(requests_); +} + +void routing_manager_client::init_receiver() { +#if defined(__linux__) || defined(ANDROID) + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + its_security->store_client_to_sec_client_mapping(get_client(), get_sec_client()); + its_security->store_sec_client_to_client_mapping(get_sec_client(), get_client()); +#endif + if (!receiver_) { + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + } else { + std::uint16_t its_port = receiver_->get_local_port(); + if (its_port != ILLEGAL_PORT) + VSOMEIP_INFO << "Reusing local server endpoint@" << its_port; + } +} + +void routing_manager_client::notify_remote_initially(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, const std::set &_events_to_exclude) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + auto service_info = find_service(_service, _instance); + for (const auto &e : its_eventgroup->get_events()) { + if (e->is_field() && e->is_set() + && _events_to_exclude.find(e->get_event()) + == _events_to_exclude.end()) { + std::shared_ptr its_notification + = runtime::get()->create_notification(); + its_notification->set_service(_service); + its_notification->set_instance(_instance); + its_notification->set_method(e->get_event()); + its_notification->set_payload(e->get_payload()); + if (service_info) { + its_notification->set_interface_version(service_info->get_major()); + } + + std::shared_ptr its_serializer(get_serializer()); + if (its_serializer->serialize(its_notification.get())) { + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + send_local(sender_, VSOMEIP_ROUTING_CLIENT, + its_serializer->get_data(), its_serializer->get_size(), + _instance, false, protocol::id_e::NOTIFY_ID, 0); + } + } + its_serializer->reset(); + put_serializer(its_serializer); + } else { + VSOMEIP_ERROR << "Failed to serialize message. Check message size!"; + } + } + } + } + +} + +uint32_t routing_manager_client::get_remote_subscriber_count(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, bool _increment) { + std::lock_guard its_lock(remote_subscriber_count_mutex_); + uint32_t count (0); + bool found(false); + auto found_service = remote_subscriber_count_.find(_service); + if (found_service != remote_subscriber_count_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_group = found_instance->second.find(_eventgroup); + if (found_group != found_instance->second.end()) { + found = true; + if (_increment) { + found_group->second = found_group->second + 1; + } else { + if (found_group->second > 0) { + found_group->second = found_group->second - 1; + } + } + count = found_group->second; + } + } + } + if (!found) { + if (_increment) { + remote_subscriber_count_[_service][_instance][_eventgroup] = 1; + count = 1; + } + } + return count; +} + +void routing_manager_client::clear_remote_subscriber_count( + service_t _service, instance_t _instance) { + std::lock_guard its_lock(remote_subscriber_count_mutex_); + auto found_service = remote_subscriber_count_.find(_service); + if (found_service != remote_subscriber_count_.end()) { + if (found_service->second.erase(_instance)) { + if (!found_service->second.size()) { + remote_subscriber_count_.erase(found_service); + } + } + } +} + +void +routing_manager_client::assign_client_timeout_cbk( + boost::system::error_code const &_error) { + + if (!_error) { + bool register_again(false); + { + std::lock_guard its_lock(state_mutex_); + if (state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; + } + } + if (register_again) { + std::lock_guard its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " request client timeout! Trying again..."; + + if (sender_) { + sender_->restart(); + } + } + } +} + +void routing_manager_client::register_application_timeout_cbk( + boost::system::error_code const &_error) { + + bool register_again(false); + { + std::lock_guard its_lock(state_mutex_); + if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; + } + } + if (register_again) { + std::lock_guard its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " register timeout! Trying again..."; + + if (sender_) + sender_->restart(); + } +} + +void routing_manager_client::send_registered_ack() { + + protocol::registered_ack_command its_command; + its_command.set_client(get_client()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": registered ack command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +bool routing_manager_client::is_client_known(client_t _client) { + + std::lock_guard its_lock(known_clients_mutex_); + return (known_clients_.find(_client) != known_clients_.end()); +} + +bool routing_manager_client::create_placeholder_event_and_subscribe( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _notifier, const std::shared_ptr &_filter, + client_t _client) { + + std::lock_guard its_lock(stop_mutex_); + + bool is_inserted(false); + + if (find_service(_service, _instance)) { + // We received an event for an existing service which was not yet + // requested/offered. Create a placeholder field until someone + // requests/offers this event with full information like eventgroup, + // field/event, etc. + std::set its_eventgroups({ _eventgroup }); + // routing_manager_client: Always register with own client id and shadow = false + routing_manager_base::register_event(host_->get_client(), + _service, _instance, _notifier, + its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN, + std::chrono::milliseconds::zero(), false, true, nullptr, false, false, + true); + + std::shared_ptr its_event = find_event(_service, _instance, _notifier); + if (its_event) { + is_inserted = its_event->add_subscriber(_eventgroup, _filter, _client, false); + } + } + + return is_inserted; +} + +void routing_manager_client::request_debounce_timeout_cbk( + boost::system::error_code const &_error) { + + std::lock_guard its_lock(state_mutex_); + if (!_error) { + if (requests_to_debounce_.size()) { + if (state_ == inner_state_type_e::ST_REGISTERED) { + send_request_services(requests_to_debounce_); + requests_.insert(requests_to_debounce_.begin(), + requests_to_debounce_.end()); + requests_to_debounce_.clear(); + } else { + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_running_ = true; + request_debounce_timer_.expires_from_now(std::chrono::milliseconds( + configuration_->get_request_debouncing(host_->get_name()))); + request_debounce_timer_.async_wait( + std::bind( + &routing_manager_client::request_debounce_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + return; + } + } + } + } + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_running_ = false; + } +} + +void routing_manager_client::register_client_error_handler(client_t _client, + const std::shared_ptr &_endpoint) { + + _endpoint->register_error_handler( + std::bind(&routing_manager_client::handle_client_error, this, _client)); +} + +void routing_manager_client::handle_client_error(client_t _client) { + + if (_client != VSOMEIP_ROUTING_CLIENT) { + VSOMEIP_INFO << "Client 0x" << std::hex << get_client() + << " handles a client error(" << std::hex << _client << ")"; + remove_local(_client, true); + } else { + bool should_reconnect(true); + { + std::unique_lock its_lock(state_mutex_); + should_reconnect = is_started_; + } + if (should_reconnect) { + std::map its_known_clients; + { + std::lock_guard its_lock(known_clients_mutex_); + its_known_clients = known_clients_; + } + reconnect(its_known_clients); + } + } +} + +void routing_manager_client::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { + + protocol::offered_services_request_command its_command; + its_command.set_client(_client); + its_command.set_offer_type(_offer_type); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": offered service request command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_unsubscribe_ack( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + remote_subscription_id_t _id) { + + protocol::unsubscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::resend_provided_event_registrations() { + std::lock_guard its_lock(state_mutex_); + for (const event_data_t& ed : pending_event_registrations_) { + if (ed.is_provided_) { + send_register_event(get_client(), ed.service_, ed.instance_, + ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_, + ed.is_provided_, ed.is_cyclic_); + } + } +} + +void routing_manager_client::send_resend_provided_event_response(pending_remote_offer_id_t _id) { + + protocol::resend_provided_events_command its_command; + its_command.set_client(get_client()); + its_command.set_remote_offer_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": resend provided event command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +#ifndef VSOMEIP_DISABLE_SECURITY +void routing_manager_client::send_update_security_policy_response( + pending_security_update_id_t _update_id) { + + protocol::update_security_policy_response_command its_command; + its_command.set_client(get_client()); + its_command.set_update_id(_update_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": update security policy response command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_remove_security_policy_response( + pending_security_update_id_t _update_id) { + + protocol::remove_security_policy_response_command its_command; + its_command.set_client(get_client()); + its_command.set_update_id(_update_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": update security policy response command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::on_update_security_credentials( + const protocol::update_security_credentials_command &_command) { + + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + for (const auto &c : _command.get_credentials()) { + std::shared_ptr its_policy(std::make_shared()); + boost::icl::interval_set its_gid_set; + uid_t its_uid(c.first); + gid_t its_gid(c.second); + + its_gid_set.insert(its_gid); + + its_policy->credentials_ += std::make_pair( + boost::icl::interval::closed(its_uid, its_uid), its_gid_set); + its_policy->allow_who_ = true; + its_policy->allow_what_ = true; + + its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client()); + } +} +#endif + +void routing_manager_client::on_client_assign_ack(const client_t &_client) { + + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_ASSIGNING) { + if (_client != VSOMEIP_CLIENT_UNSET) { + state_ = inner_state_type_e::ST_ASSIGNED; + + boost::system::error_code ec; + register_application_timer_.cancel(ec); + host_->set_client(_client); + + if (is_started_) { + init_receiver(); + if (receiver_) { + receiver_->start(); + + VSOMEIP_INFO << std::hex << "Client " << get_client() + << " (" << host_->get_name() + << ") successfully connected to routing ~> registering.."; + register_application(); + } else { + state_ = inner_state_type_e::ST_DEREGISTERED; + + host_->set_client(VSOMEIP_CLIENT_UNSET); + + sender_->restart(); + } + } + } else { + VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application."; + } + } else { + VSOMEIP_WARNING << "Client " << std::hex << get_client() + << " received another client identifier (" + << std::hex << _client + << "). Ignoring it. (" + << (int)state_ << ")"; + } +} + +void routing_manager_client::on_suspend() { + + VSOMEIP_INFO << __func__ << ": Application " + << std::hex << std::setw(4) << std::setfill('0') + << host_->get_client(); + + std::lock_guard its_lock(remote_subscriber_count_mutex_); + + // Unsubscribe everything that is left over. + for (const auto &s : remote_subscriber_count_) { + for (const auto &i : s.second) { + for (const auto &e : i.second) + routing_manager_base::unsubscribe( + VSOMEIP_ROUTING_CLIENT, nullptr, + s.first, i.first, e.first, ANY_EVENT); + } + } + + // Remove all entries. + remote_subscriber_count_.clear(); +} + +} // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 07c0740b2..4ebca557a 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,8 +8,9 @@ #include #include #include +#include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include #include @@ -30,10 +31,7 @@ #include "../include/routing_manager_stub.hpp" #include "../include/serviceinfo.hpp" #include "../../configuration/include/configuration.hpp" -#include "../../security/include/security.hpp" - #include "../../endpoints/include/endpoint_definition.hpp" -#include "../../endpoints/include/local_client_endpoint_impl.hpp" #include "../../endpoints/include/tcp_client_endpoint_impl.hpp" #include "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_client_endpoint_impl.hpp" @@ -42,13 +40,15 @@ #include "../../message/include/deserializer.hpp" #include "../../message/include/message_impl.hpp" #include "../../message/include/serializer.hpp" +#include "../../plugin/include/plugin_manager_impl.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../security/include/security.hpp" #include "../../service_discovery/include/constants.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../service_discovery/include/runtime.hpp" #include "../../service_discovery/include/service_discovery.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" -#include "../../plugin/include/plugin_manager_impl.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" #endif @@ -89,11 +89,11 @@ routing_manager_impl::routing_manager_impl(routing_manager_host *_host) : } routing_manager_impl::~routing_manager_impl() { - utility::remove_lockfile(configuration_); - utility::reset_client_ids(); + utility::remove_lockfile(configuration_->get_network()); + utility::reset_client_ids(configuration_->get_network()); } -boost::asio::io_service & routing_manager_impl::get_io() { +boost::asio::io_context &routing_manager_impl::get_io() { return routing_manager_base::get_io(); } @@ -101,6 +101,34 @@ client_t routing_manager_impl::get_client() const { return routing_manager_base::get_client(); } +const vsomeip_sec_client_t *routing_manager_impl::get_sec_client() const { + + return (routing_manager_base::get_sec_client()); +} + +std::string routing_manager_impl::get_client_host() const { + return routing_manager_base::get_client_host(); +} + +void routing_manager_impl::set_client_host(const std::string &_client_host) { + routing_manager_base::set_client_host(_client_host); +} + +std::string routing_manager_impl::get_env(client_t _client) const { + + std::lock_guard its_known_clients_lock(known_clients_mutex_); + return get_env_unlocked(_client); +} + +std::string routing_manager_impl::get_env_unlocked(client_t _client) const { + + auto find_client = known_clients_.find(_client); + if (find_client != known_clients_.end()) { + return (find_client->second); + } + return ""; +} + std::set routing_manager_impl::find_local_clients(service_t _service, instance_t _instance) { return routing_manager_base::find_local_clients(_service, _instance); } @@ -109,18 +137,31 @@ client_t routing_manager_impl::find_local_client(service_t _service, instance_t return routing_manager_base::find_local_client(_service, _instance); } -bool routing_manager_impl::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, +bool routing_manager_impl::is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) { - return routing_manager_base::is_subscribe_to_any_event_allowed(_credentials, _client, + + return routing_manager_base::is_subscribe_to_any_event_allowed(_sec_client, _client, _service, _instance, _eventgroup); } +void routing_manager_impl::add_known_client(client_t _client, const std::string &_client_host) { + routing_manager_base::add_known_client(_client, _client_host); +} + +bool routing_manager_impl::is_routing_manager() const { + return true; +} + void routing_manager_impl::init() { routing_manager_base::init(ep_mgr_impl_); - // TODO: Only instantiate the stub if needed - stub_ = std::make_shared(this, configuration_); - stub_->init(); + if (configuration_->is_routing_enabled()) { + stub_ = std::make_shared(this, configuration_); + stub_->init(); + } else { + VSOMEIP_INFO << "Internal message routing disabled!"; + } if (configuration_->is_sd_enabled()) { VSOMEIP_INFO<< "Service Discovery enabled. Trying to load module."; @@ -162,7 +203,7 @@ void routing_manager_impl::init() { } void routing_manager_impl::start() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) boost::asio::ip::address its_multicast; try { its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast()); @@ -172,6 +213,20 @@ void routing_manager_impl::start() { << "\". Please check your configuration."; } + std::stringstream its_netmask_or_prefix; + auto its_unicast = configuration_->get_unicast_address(); + if (its_unicast.is_v4()) + its_netmask_or_prefix << "netmask:" << configuration_->get_netmask().to_string(); + else + its_netmask_or_prefix << "prefix:" << configuration_->get_prefix(); + + VSOMEIP_INFO << "Client [" + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << "] routes unicast:" << its_unicast.to_string() + << ", " + << its_netmask_or_prefix.str(); + netlink_connector_ = std::make_shared( host_->get_io(), configuration_->get_unicast_address(), its_multicast); netlink_connector_->register_net_if_changes_handler( @@ -185,7 +240,8 @@ void routing_manager_impl::start() { } #endif - stub_->start(); + if (stub_) + stub_->start(); host_->on_state(state_type_e::ST_REGISTERED); if (configuration_->log_version()) { @@ -195,7 +251,7 @@ void routing_manager_impl::start() { version_log_timer_.async_wait(std::bind(&routing_manager_impl::log_version_timer_cbk, this, std::placeholders::_1)); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (configuration_->log_memory()) { std::lock_guard its_lock(memory_log_timer_mutex_); boost::system::error_code ec; @@ -231,7 +287,7 @@ void routing_manager_impl::stop() { std::lock_guard its_lock(local_services_mutex_); for (const auto& s : local_services_) { for (const auto& i : s.second) { - if (std::get<2>(i.second) == client_) { + if (std::get<2>(i.second) == get_client()) { its_services[s.first][i.first] = i.second; } } @@ -249,7 +305,7 @@ void routing_manager_impl::stop() { std::lock_guard its_lock(version_log_timer_mutex_); version_log_timer_.cancel(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { boost::system::error_code ec; std::lock_guard its_lock(memory_log_timer_mutex_); @@ -276,9 +332,10 @@ void routing_manager_impl::stop() { if (discovery_) discovery_->stop(); - stub_->stop(); + if (stub_) + stub_->stop(); - for (const auto& client : ep_mgr_->get_connected_clients()) { + for (const auto client : ep_mgr_->get_connected_clients()) { if (client != VSOMEIP_ROUTING_CLIENT) { remove_local(client, true); } @@ -317,7 +374,7 @@ bool routing_manager_impl::erase_offer_command(service_t _service, instance_t _i if (!found_service_instance->second.empty()) { // check for other commands to be processed auto its_command = found_service_instance->second.front(); - if (std::get<0>(its_command) == VSOMEIP_OFFER_SERVICE) { + if (std::get<0>(its_command) == uint8_t(protocol::id_e::OFFER_SERVICE_ID)) { io_.post([&, its_command, _service, _instance](){ offer_service(std::get<1>(its_command), _service, _instance, std::get<2>(its_command), std::get<3>(its_command), false); @@ -355,7 +412,8 @@ bool routing_manager_impl::offer_service(client_t _client, // only queue commands if method was NOT called via erase_offer_command() if (_must_queue) { - if (!insert_offer_command(_service, _instance, VSOMEIP_OFFER_SERVICE, + if (!insert_offer_command(_service, _instance, + uint8_t(protocol::id_e::OFFER_SERVICE_ID), _client, _major, _minor)) { return false; } @@ -364,15 +422,8 @@ bool routing_manager_impl::offer_service(client_t _client, // Check if the application hosted by routing manager is allowed to offer // offer_service requests of local proxies are checked in rms::on:message if (_client == get_client()) { -#ifdef _WIN32 - std::uint32_t its_routing_uid = ANY_UID; - std::uint32_t its_routing_gid = ANY_GID; -#else - std::uint32_t its_routing_uid = getuid(); - std::uint32_t its_routing_gid = getgid(); -#endif - if (!security::get()->is_offer_allowed(its_routing_uid, its_routing_gid, - _client, _service, _instance)) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_offer( + get_sec_client(), _service, _instance)) { VSOMEIP_WARNING << "routing_manager_impl::offer_service: " << std::hex << "Security: Client 0x" << _client << " isn't allowed to offer the following service/instance " @@ -412,7 +463,8 @@ bool routing_manager_impl::offer_service(client_t _client, && ps.instance_ == _instance && ps.major_ == _major) { insert_subscription(ps.service_, ps.instance_, - ps.eventgroup_, ps.event_, client_, &its_already_subscribed_events); + ps.eventgroup_, ps.event_, nullptr, + get_client(), &its_already_subscribed_events); #if 0 VSOMEIP_ERROR << __func__ << ": event=" @@ -425,8 +477,9 @@ bool routing_manager_impl::offer_service(client_t _client, send_pending_subscriptions(_service, _instance, _major); } - stub_->on_offer_service(_client, _service, _instance, _major, _minor); - on_availability(_service, _instance, true, _major, _minor); + if (stub_) + stub_->on_offer_service(_client, _service, _instance, _major, _minor); + on_availability(_service, _instance, availability_state_e::AS_AVAILABLE, _major, _minor); erase_offer_command(_service, _instance); return true; } @@ -451,7 +504,8 @@ void routing_manager_impl::stop_offer_service(client_t _client, << " (" << std::boolalpha << _must_queue << ")"; if (_must_queue) { - if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE, + if (!insert_offer_command(_service, _instance, + uint8_t(protocol::id_e::STOP_OFFER_SERVICE_ID), _client, _major, _minor)) { return; } @@ -476,8 +530,9 @@ void routing_manager_impl::stop_offer_service(client_t _client, } on_stop_offer_service(_client, _service, _instance, _major, _minor); - stub_->on_stop_offer_service(_client, _service, _instance, _major, _minor); - on_availability(_service, _instance, false, _major, _minor); + if (stub_) + stub_->on_stop_offer_service(_client, _service, _instance, _major, _minor); + on_availability(_service, _instance, availability_state_e::AS_UNAVAILABLE, _major, _minor); } else { VSOMEIP_WARNING << __func__ << " received STOP_OFFER(" << std::hex << std::setw(4) << std::setfill('0') << _client <<"): [" @@ -503,7 +558,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, auto its_info = find_service(_service, _instance); if (!its_info) { - requested_service_add(_client, _service, _instance, _major, _minor); + add_requested_service(_client, _service, _instance, _major, _minor); if (discovery_) { if (!configuration_->is_local_service(_service, _instance)) { // Non local service instance ~> tell SD to find it! @@ -525,7 +580,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, || DEFAULT_MINOR == its_info->get_minor() || _minor == ANY_MINOR)) { if(!its_info->is_local()) { - requested_service_add(_client, _service, _instance, _major, _minor); + add_requested_service(_client, _service, _instance, _major, _minor); if (discovery_) { // Non local service instance ~> tell SD to find it! discovery_->request_service(_service, _instance, _major, @@ -538,12 +593,15 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, } if (_client == get_client()) { - stub_->create_local_receiver(); + if (stub_) + stub_->create_local_receiver(); + + protocol::service its_request(_service, _instance, _major, _minor); + std::set requests; + requests.insert(its_request); - service_data_t request = { _service, _instance, _major, _minor }; - std::set requests; - requests.insert(request); - stub_->handle_requests(_client, requests); + if (stub_) + stub_->handle_requests(_client, requests); } } @@ -560,7 +618,7 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); } routing_manager_base::release_service(_client, _service, _instance); - requested_service_remove(_client, _service, _instance); + remove_requested_service(_client, _service, _instance, ANY_MAJOR, ANY_MINOR); std::shared_ptr its_info(find_service(_service, _instance)); if (its_info && !its_info->is_local()) { @@ -582,9 +640,11 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, } } -void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) { +void routing_manager_impl::subscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { VSOMEIP_INFO << "SUBSCRIBE(" << std::hex << std::setw(4) << std::setfill('0') << _client <<"): [" @@ -600,21 +660,25 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, _eventgroup, _event, subscription_state_e::IS_SUBSCRIBING); #endif auto self = shared_from_this(); - host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, true, - [this, self, _client, _uid, _gid, _service, _instance, _eventgroup, - _event, _major] + host_->on_subscription(_service, _instance, _eventgroup, _client, + _sec_client, get_env(_client), true, + [this, self, _client, _sec_client, _service, _instance, _eventgroup, + _major, _event, _filter] (const bool _subscription_accepted) { (void) ep_mgr_->find_or_create_local(_client); if (!_subscription_accepted) { - stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup, _event); + if (stub_) + stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup, _event); VSOMEIP_INFO << "Subscription request from client: 0x" << std::hex << _client << std::dec << " for eventgroup: 0x" << _eventgroup << " rejected from application handler."; return; - } else { + } else if (stub_) { stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event); } - routing_manager_base::subscribe(_client, _uid, _gid, _service, _instance, _eventgroup, _major, _event); + routing_manager_base::subscribe(_client, _sec_client, + _service, _instance, _eventgroup, _major, + _event, _filter); #ifdef VSOMEIP_ENABLE_COMPAT send_pending_notify_ones(_service, _instance, _eventgroup, _client); routing_manager_base::erase_incoming_subscription_state(_client, _service, _instance, @@ -631,7 +695,7 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, // handle_subscription_state. std::unique_lock its_critical(remote_subscription_state_mutex_); bool inserted = insert_subscription(_service, _instance, _eventgroup, - _event, _client, &its_already_subscribed_events); + _event, _filter, _client, &its_already_subscribed_events); const bool subscriber_is_rm_host = (get_client() == _client); if (inserted) { if (0 == its_local_client) { @@ -654,17 +718,20 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, } } else { its_critical.unlock(); - if (is_available(_service, _instance, _major)) { + if (is_available(_service, _instance, _major) && stub_) { stub_->send_subscribe(ep_mgr_->find_local(_service, _instance), - _client, _service, _instance, _eventgroup, _major, _event, - PENDING_SUBSCRIPTION_ID); + _client, _service, _instance, _eventgroup, _major, + _event, _filter, PENDING_SUBSCRIPTION_ID); } } } if (subscriber_is_rm_host) { std::lock_guard ist_lock(pending_subscription_mutex_); subscription_data_t subscription = { - _service, _instance, _eventgroup, _major, _event, _uid, _gid + _service, _instance, + _eventgroup, _major, + _event, _filter, + *_sec_client }; pending_subscriptions_.insert(subscription); } @@ -674,8 +741,10 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, } } -void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { +void routing_manager_impl::unsubscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) { VSOMEIP_INFO << "UNSUBSCRIBE(" << std::hex << std::setw(4) << std::setfill('0') << _client << "): [" @@ -702,7 +771,8 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } if (discovery_) { - host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, false, + host_->on_subscription(_service, _instance, _eventgroup, _client, + _sec_client, get_env(_client), false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); if (0 == find_local_client(_service, _instance)) { if (get_client() == _client) { @@ -728,10 +798,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, if (get_client() == _client) { std::lock_guard ist_lock(pending_subscription_mutex_); remove_pending_subscription(_service, _instance, _eventgroup, _event); - stub_->send_unsubscribe( - ep_mgr_->find_local(_service, _instance), - _client, _service, _instance, _eventgroup, _event, - PENDING_SUBSCRIPTION_ID); + if (stub_) + stub_->send_unsubscribe( + ep_mgr_->find_local(_service, _instance), + _client, _service, _instance, _eventgroup, _event, + PENDING_SUBSCRIPTION_ID); } } ep_mgr_impl_->clear_multicast_endpoints(_service, _instance); @@ -742,15 +813,16 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } bool routing_manager_impl::send(client_t _client, - std::shared_ptr _message) { - return routing_manager_base::send(_client, _message); + std::shared_ptr _message, bool _force) { + + return routing_manager_base::send(_client, _message, _force); } bool routing_manager_impl::send(client_t _client, const byte_t *_data, length_t _size, instance_t _instance, bool _reliable, - client_t _bound_client, - credentials_t _credentials, - uint8_t _status_check, bool _sent_from_remote) { + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, bool _force) { + bool is_sent(false); if (_size > VSOMEIP_MESSAGE_TYPE_POS) { std::shared_ptr its_target; @@ -775,15 +847,14 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } else if (is_notification && _client && !is_service_discovery) { // Selective notifications! if (_client == get_client()) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif - deliver_message(_data, _size, _instance, _reliable, _bound_client, _credentials, _status_check, _sent_from_remote); + deliver_message(_data, _size, _instance, _reliable, + _bound_client, _sec_client, + _status_check, _sent_from_remote); return true; } its_target = find_local(_client); @@ -794,16 +865,15 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, if ((is_request && its_client == get_client()) || (is_response && find_local_client(its_service, _instance) == get_client()) || (is_notification && find_local_client(its_service, _instance) == VSOMEIP_ROUTING_CLIENT)) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif - is_sent = send_local(its_target, get_client(), _data, _size, _instance, _reliable, VSOMEIP_SEND, _status_check); + is_sent = send_local(its_target, get_client(), _data, _size, _instance, + _reliable, protocol::id_e::SEND_ID, _status_check); } else { // Check whether hosting application should get the message // If not, check routes to external @@ -811,7 +881,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, || (find_local_client(its_service, _instance) == host_->get_client() && is_request)) { // TODO: Find out how to handle session id here - is_sent = deliver_message(_data, _size, _instance, _reliable, VSOMEIP_ROUTING_CLIENT, _credentials, _status_check); + is_sent = deliver_message(_data, _size, _instance, _reliable, + VSOMEIP_ROUTING_CLIENT, _sec_client, _status_check); } else { e2e_buffer its_buffer; @@ -844,13 +915,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, its_service, _instance, _reliable); if (its_target) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif is_sent = its_target->send(_data, _size); } else { @@ -868,7 +936,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, std::shared_ptr its_info(find_service(its_service, _instance)); if (its_info || is_service_discovery) { if (is_notification && !is_service_discovery) { - send_local_notification(get_client(), _data, _size, _instance, _reliable, _status_check); + (void)send_local_notification(get_client(), _data, _size, _instance, + _reliable, _status_check, _force); method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); std::shared_ptr its_event = find_event(its_service, _instance, its_method); @@ -930,13 +999,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } #ifdef USE_DLT if (has_sent) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(nullptr, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif } @@ -962,13 +1028,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, (sd_info_ ? sd_info_->get_endpoint(false) : nullptr) : its_info->get_endpoint(_reliable); if (its_target) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif is_sent = its_target->send(_data, _size); } else { @@ -1009,6 +1072,7 @@ bool routing_manager_impl::send_to( const client_t _client, const std::shared_ptr &_target, std::shared_ptr _message) { + bool is_sent(false); std::shared_ptr its_serializer(get_serializer()); @@ -1050,19 +1114,17 @@ bool routing_manager_impl::send_to( bool routing_manager_impl::send_to( const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, instance_t _instance) { + std::shared_ptr its_endpoint = ep_mgr_impl_->find_server_endpoint( _target->get_remote_port(), _target->is_reliable()); if (its_endpoint) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #else (void) _instance; #endif @@ -1081,13 +1143,10 @@ bool routing_manager_impl::send_via_sd( if (its_endpoint) { #ifdef USE_DLT if (tc_->is_sd_enabled()) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, 0x0)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif @@ -1136,13 +1195,15 @@ void routing_manager_impl::register_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, const std::set &_eventgroups, event_type_e _type, - reliability_type_e _reliability, bool _is_provided) { + reliability_type_e _reliability, bool _is_provided, bool _is_cyclic) { + routing_manager_base::register_event(_client, _service, _instance, _notifier, _eventgroups, _type, _reliability, - std::chrono::milliseconds::zero(), false, true, - nullptr, + (_is_cyclic ? std::chrono::milliseconds(1) + : std::chrono::milliseconds::zero()), + false, true, nullptr, _is_provided, true); } @@ -1172,7 +1233,7 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, if (its_event) { std::set > its_targets; const auto its_reliability = its_event->get_reliability(); - for (const auto& g : its_event->get_eventgroups()) { + for (const auto g : its_event->get_eventgroups()) { const auto its_eventgroup = find_eventgroup(_service, _instance, g); if (its_eventgroup) { const auto its_subscriptions = its_eventgroup->get_remote_subscriptions(); @@ -1197,7 +1258,7 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, if (its_targets.size() > 0) { for (const auto &its_target : its_targets) { - its_event->set_payload(_payload, _client, its_target, _force); + its_event->set_payload(_payload, _client, its_target); } } } else { @@ -1209,11 +1270,11 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, } void routing_manager_impl::on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) { + availability_state_e _state, major_version_t _major, minor_version_t _minor) { // insert subscriptions of routing manager into service discovery // to send SubscribeEventgroup after StopOffer / Offer was received - if (_is_available) { + if (_state == availability_state_e::AS_AVAILABLE) { if (discovery_) { const client_t its_local_client = find_local_client(_service, _instance); // remote service @@ -1241,7 +1302,7 @@ void routing_manager_impl::on_availability(service_t _service, instance_t _insta } } } - host_->on_availability(_service, _instance, _is_available, _major, _minor); + host_->on_availability(_service, _instance, _state, _major, _minor); } @@ -1273,7 +1334,7 @@ bool routing_manager_impl::offer_service_remotely(service_t _service, << "]"; ret = false; } else { - if (!stub_->send_provided_event_resend_request(its_offering_client, + if (stub_ && !stub_->send_provided_event_resend_request(its_offering_client, pending_remote_offer_add(_service, _instance))) { VSOMEIP_ERROR << __func__ << ": Couldn't send event resend" << "request to client 0x" << std::hex << std::setw(4) @@ -1332,7 +1393,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, clear_remote_subscriber(_service, _instance); if (discovery_ && its_info) { - discovery_->stop_offer_service(its_info); + discovery_->stop_offer_service(its_info, true); its_info->set_endpoint(std::shared_ptr(), _reliable); } } else { @@ -1344,7 +1405,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, // ensure to not send StopOffer for endpoint on which the service is // still offered its_copied_info->set_endpoint(std::shared_ptr(), !_reliable); - discovery_->stop_offer_service(its_copied_info); + discovery_->stop_offer_service(its_copied_info, true); } } @@ -1353,8 +1414,8 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, } void routing_manager_impl::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, credentials_t _credentials, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { #if 0 @@ -1369,10 +1430,12 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, method_t its_method; uint8_t its_check_status = e2e::profile_interface::generic_check_status::E2E_OK; instance_t its_instance(0x0); + message_type_e its_message_type; #ifdef USE_DLT bool is_forwarded(true); #endif if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { + its_message_type = static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]); its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); if (its_service == VSOMEIP_SD_SERVICE) { @@ -1381,7 +1444,11 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, if (discovery_ && its_method == sd::method) { if (configuration_->get_sd_port() == _remote_port) { if (!_remote_address.is_unspecified()) { - discovery_->on_message(_data, _size, _remote_address, _destination); + // ACL check SD message + if(!is_acl_message_allowed(_receiver, its_service, ANY_INSTANCE, _remote_address)) { + return; + } + discovery_->on_message(_data, _size, _remote_address, _is_multicast); } else { VSOMEIP_ERROR << "Ignored SD message from unknown address."; } @@ -1391,7 +1458,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } } } else { - if(_destination.is_multicast()) { + if (_is_multicast) { its_instance = ep_mgr_impl_->find_instance_multicast(its_service, _remote_address); } else { its_instance = ep_mgr_impl_->find_instance(its_service, _receiver); @@ -1417,7 +1484,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } //Ignore messages with invalid message type if(_size >= VSOMEIP_MESSAGE_TYPE_POS) { - if(!utility::is_valid_message_type(static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]))) { + if(!utility::is_valid_message_type(its_message_type)) { VSOMEIP_ERROR << "Ignored SomeIP message with invalid message type."; return; } @@ -1436,7 +1503,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } // Security checks if enabled! - if (security::get()->is_enabled()) { + if (configuration_->is_security_enabled()) { if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { client_t requester = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_CLIENT_POS_MIN], @@ -1456,7 +1523,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, << " which is already used locally ~> Skip message!"; return; } - if (!security::get()->is_remote_client_allowed()) { + if (!configuration_->is_remote_access_allowed()) { // check if policy allows remote requests. VSOMEIP_WARNING << "routing_manager_impl::on_message: " << std::hex << "Security: Remote client with client ID 0x" << requester @@ -1485,19 +1552,22 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } #endif } + + // ACL check message + if(!is_acl_message_allowed(_receiver, its_service, its_instance, _remote_address)) { + return; + } + // Common way of message handling #ifdef USE_DLT is_forwarded = #endif on_message(its_service, its_instance, _data, _size, _receiver->is_reliable(), - _bound_client, _credentials, its_check_status, true); + _bound_client, _sec_client, its_check_status, true); } } #ifdef USE_DLT if (is_forwarded) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; const boost::asio::ip::address_v4 its_remote_address = _remote_address.is_v4() ? _remote_address.to_v4() : @@ -1508,19 +1578,16 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, trace::protocol_e::udp; its_header.prepare(its_remote_address, _remote_port, its_protocol, false, its_instance); - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, _data, - its_data_size); + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); } #endif } -bool routing_manager_impl::on_message( - service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, - bool _reliable, client_t _bound_client, - credentials_t _credentials, - uint8_t _check_status, - bool _is_from_remote) { +bool routing_manager_impl::on_message(service_t _service, instance_t _instance, + const byte_t *_data, length_t _size, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _check_status, bool _is_from_remote) { #if 0 std::stringstream msg; msg << "rmi::on_message(" @@ -1541,15 +1608,29 @@ bool routing_manager_impl::on_message( _data[VSOMEIP_CLIENT_POS_MAX]); } +#if 0 + // ACL message check for local test purpouse + std::shared_ptr its_info = find_service(_service, _instance); + if (its_info) { + std::shared_ptr _receiver = its_info->get_endpoint(_reliable); + if (_receiver && _receiver.get()) { + if(!is_acl_message_allowed(_receiver.get(), _service, _instance, + boost::asio::ip::address_v4::from_string("127.0.0.1"))) { + return false; + } + } + } +#endif + if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { is_forwarded = deliver_notification(_service, _instance, _data, _size, - _reliable, _bound_client, _credentials, _check_status, _is_from_remote); + _reliable, _bound_client, _sec_client, _check_status, _is_from_remote); } else if (its_client == host_->get_client()) { deliver_message(_data, _size, _instance, - _reliable, _bound_client, _credentials, _check_status, _is_from_remote); + _reliable, _bound_client, _sec_client, _check_status, _is_from_remote); } else { send(its_client, _data, _size, _instance, _reliable, - _bound_client, _credentials, _check_status, _is_from_remote); //send to proxy + _bound_client, _sec_client, _check_status, _is_from_remote, false); //send to proxy } return is_forwarded; } @@ -1689,7 +1770,7 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se if (discovery_) { if (its_info->get_major() == _major && its_info->get_minor() == _minor) { - discovery_->stop_offer_service(its_info); + discovery_->stop_offer_service(its_info, true); } } del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr), @@ -1782,11 +1863,11 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se } bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, - instance_t _instance, bool _reliable, client_t _bound_client, credentials_t _credentials, + instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check, bool _is_from_remote) { + bool is_delivered(false); - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); auto its_deserializer = get_deserializer(); its_deserializer->set_data(_data, _size); @@ -1798,8 +1879,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, its_message->set_instance(_instance); its_message->set_reliable(_reliable); its_message->set_check_result(_status_check); - its_message->set_uid(std::get<0>(_credentials)); - its_message->set_gid(std::get<1>(_credentials)); + if (_sec_client) + its_message->set_sec_client(*_sec_client); + its_message->set_env(get_env(_bound_client)); if (!_is_from_remote) { if (utility::is_notification(its_message->get_message_type())) { @@ -1814,9 +1896,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a notification from service/instance/event " @@ -1828,7 +1910,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, } } } else if (utility::is_request(its_message->get_message_type())) { - if (security::get()->is_enabled() + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() && its_message->get_client() != _bound_client) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message:" @@ -1841,9 +1924,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, return false; } - if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_message->get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to send a request to service/instance/method " @@ -1864,9 +1947,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a response from service/instance/method " @@ -1879,7 +1962,7 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, } } } else { - if (!security::get()->is_remote_client_allowed()) { + if (!configuration_->is_remote_access_allowed()) { // if the message is from remote, check if // policy allows remote requests. VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() @@ -1892,9 +1975,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else if (utility::is_notification(its_message->get_message_type())) { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a notification from service/instance/event " @@ -1918,10 +2001,10 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, bool routing_manager_impl::deliver_notification( service_t _service, instance_t _instance, - const byte_t *_data, length_t _length, - bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _length, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check, bool _is_from_remote) { + event_t its_event_id = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); client_t its_client_id = VSOMEIP_BYTES_TO_WORD( @@ -1934,7 +2017,7 @@ bool routing_manager_impl::deliver_notification( // no subscribers for this specific event / check subscriptions // to other events of the event's eventgroups bool cache_event = false; - for (const auto& eg : its_event->get_eventgroups()) { + for (const auto eg : its_event->get_eventgroups()) { std::shared_ptr egi = find_eventgroup(_service, _instance, eg); if (egi) { for (const auto &e : egi->get_events()) { @@ -1957,37 +2040,30 @@ bool routing_manager_impl::deliver_notification( return true; // as there is nothing to do } } - const uint32_t its_length(utility::get_payload_size(_data, _length)); - if (its_length != _length - VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_ERROR << "Message length mismatch, dropping message!"; - return false; - } - std::shared_ptr its_payload - = runtime::get()->create_payload(&_data[VSOMEIP_PAYLOAD_POS], - its_length); - if (!its_event->set_payload_dont_notify(its_payload)) { - // do not forward the notification as it was filtered - return false; - } } + auto its_length = utility::get_payload_size(_data, _length); + auto its_payload = runtime::get()->create_payload( + &_data[VSOMEIP_PAYLOAD_POS], its_length); + // incoming events statistics (void) insert_event_statistics( - _service, - _instance, - its_event_id, - utility::get_payload_size(_data, _length)); + _service, _instance, its_event_id, its_length); + // Ignore the filter for messages coming from other local clients + // as the filter was already applied there. + auto its_subscribers + = its_event->update_and_get_filtered_subscribers(its_payload, _is_from_remote); if (its_event->get_type() != event_type_e::ET_SELECTIVE_EVENT) { - for (const auto& its_local_client : its_event->get_subscribers()) { + for (const auto its_local_client : its_subscribers) { if (its_local_client == host_->get_client()) { deliver_message(_data, _length, _instance, _reliable, - _bound_client, _credentials, _status_check, _is_from_remote); + _bound_client, _sec_client, _status_check, _is_from_remote); } else { std::shared_ptr its_local_target = find_local(its_local_client); if (its_local_target) { send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, - _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check); + _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } @@ -1998,20 +2074,20 @@ bool routing_manager_impl::deliver_notification( if (its_client_id == VSOMEIP_ROUTING_CLIENT) its_client_id = get_client(); - auto its_subscribers = its_event->get_subscribers(); if (its_subscribers.find(its_client_id) != its_subscribers.end()) { if (its_client_id == host_->get_client()) { deliver_message(_data, _length, _instance, _reliable, - _bound_client, _credentials, _status_check, _is_from_remote); + _bound_client, _sec_client, _status_check, _is_from_remote); } else { std::shared_ptr its_local_target = find_local(its_client_id); if (its_local_target) { send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, - _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check); + _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } } + } else { VSOMEIP_WARNING << __func__ << ": Event [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." @@ -2048,10 +2124,10 @@ std::shared_ptr routing_manager_impl::create_service_discovery_endpoin its_service_endpoint->add_default_target(VSOMEIP_SD_SERVICE, _address, _port); if (!_reliable) { - auto its_udp_server_endpoint_impl = std::dynamic_pointer_cast< + auto its_server_endpoint = std::dynamic_pointer_cast< udp_server_endpoint_impl>(its_service_endpoint); - if (its_udp_server_endpoint_impl) - its_udp_server_endpoint_impl->join(_address); + if (its_server_endpoint) + its_server_endpoint->join(_address); } } else { VSOMEIP_ERROR<< "Service Discovery endpoint could not be created. " @@ -2102,6 +2178,37 @@ routing_manager_impl::get_offered_service_instances(service_t _service) const { return its_instances; } +bool routing_manager_impl::is_acl_message_allowed(endpoint *_receiver, + service_t _service, instance_t _instance, + const boost::asio::ip::address &_remote_address) const { + if (message_acceptance_handler_ && _receiver) { + // Check the ACL whitelist rules if shall accepts the message + + message_acceptance_t message_acceptance { +#if VSOMEIP_BOOST_VERSION < 106600 + static_cast(_remote_address.to_v4().to_ulong()), _receiver->get_local_port(), +#else + _remote_address.to_v4().to_uint(), _receiver->get_local_port(), +#endif + _receiver->is_local(), _service, _instance + }; + if (!message_acceptance_handler_(message_acceptance)) { + VSOMEIP_WARNING << "Message from " << _remote_address.to_string() + << std::hex << " with service/instance " << _instance << "/" + << _instance << " was rejected by the ACL check."; + return false; + } +#if 0 + else { + VSOMEIP_INFO << "Message from " << _remote_address.to_string() + << std::hex << " with service/instance " << _instance << "/" + << _instance << " was accepted by the ACL check."; + } +#endif + } + return true; +} + /////////////////////////////////////////////////////////////////////////////// // PRIVATE /////////////////////////////////////////////////////////////////////////////// @@ -2166,20 +2273,7 @@ void routing_manager_impl::remove_local(client_t _client, bool _remove_uid) { } routing_manager_base::remove_local(_client, clients_subscriptions, _remove_uid); - std::forward_list> services_to_release_; - { - std::lock_guard its_lock(requested_services_mutex_); - auto its_client = requested_services_.find(_client); - if (its_client != requested_services_.end()) { - for (const auto& its_service : its_client->second) { - for (const auto& its_instance : its_service.second) { - services_to_release_.push_front( - { its_service.first, its_instance.first }); - } - } - } - } - for (const auto &s : services_to_release_) { + for (const auto &s : get_requested_services(_client)) { release_service(_client, s.first, s.second); } } @@ -2210,7 +2304,7 @@ void routing_manager_impl::add_routing_info( std::lock_guard its_lock(routing_state_mutex_); if (routing_state_ == routing_state_e::RS_SUSPENDED) { - VSOMEIP_INFO << "rmi::" << __func__ << " We are suspened --> do nothing."; + VSOMEIP_INFO << "rmi::" << __func__ << " We are suspended --> do nothing."; return; } @@ -2280,89 +2374,63 @@ void routing_manager_impl::add_routing_info( { bool connected(false); std::lock_guard 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)) { - // SWS_SD_00376 establish TCP connection to service - // service is marked as available later in on_connect() - if(!connected) { - if (udp_inserted) { - // atomically create reliable and unreliable endpoint - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance); - } else { - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true); - } - connected = true; - } - its_info->add_client(client_id.first); - break; - } - } + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + // SWS_SD_00376 establish TCP connection to service + // service is marked as available later in on_connect() + if (!connected) { + if (udp_inserted) { + // atomically create reliable and unreliable endpoint + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance); + } else { + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance, true); } + connected = true; } + its_info->add_client(its_client); } } } else if (_reliable_port != ILLEGAL_PORT && is_reliable_known) { std::lock_guard its_lock(requested_services_mutex_); - bool connected(false); - 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)) { - std::shared_ptr ep = its_info->get_endpoint(true); - if (ep) { - if (ep->is_established() && - !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, ep); - } - } - } else { - // no endpoint yet, but requested -> create one - - // SWS_SD_00376 establish TCP connection to service - // service is marked as available later in on_connect() - if (!connected) { - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true); - connected = true; - } - its_info->add_client(client_id.first); - } - break; - } + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + std::shared_ptr ep = its_info->get_endpoint(true); + if (ep) { + if (ep->is_established() && + stub_ && + !stub_->contained_in_routing_info( + VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), + its_info->get_minor())) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, + 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, ep); } } + } else { + // no endpoint yet, but requested -> create one + + // SWS_SD_00376 establish TCP connection to service + // service is marked as available later in on_connect() + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance, true); + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + its_info->add_client(its_client); + } } + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, + its_info->get_major(), its_info->get_minor()); } } @@ -2375,38 +2443,28 @@ void routing_manager_impl::add_routing_info( { bool connected(false); std::lock_guard its_lock(requested_services_mutex_); - for (const auto &client_id : requested_services_) { - const auto found_service = client_id.second.find(_service); - if (found_service != client_id.second.end()) { - const 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(!connected) { - ep_mgr_impl_->find_or_create_remote_client(_service, _instance, - false); - connected = true; - } - its_info->add_client(client_id.first); - break; - } - } - } + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + if (!connected) { + ep_mgr_impl_->find_or_create_remote_client(_service, _instance, + false); + connected = true; } + its_info->add_client(its_client); } } } if (!is_reliable_known && !tcp_inserted) { // UDP only service can be marked as available instantly - on_availability(_service, _instance, true, _major, _minor); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, _major, _minor); + if (stub_) + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, _major, _minor); + } } if (discovery_) { std::shared_ptr ep = its_info->get_endpoint(false); @@ -2416,43 +2474,32 @@ void routing_manager_impl::add_routing_info( } } else if (_unreliable_port != ILLEGAL_PORT && is_unreliable_known) { std::lock_guard 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 (_reliable_port == ILLEGAL_PORT && !is_reliable_known && - !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 ep = its_info->get_endpoint(false); - if (ep && ep->is_established()) { - discovery_->on_endpoint_connected( - _service, _instance, - ep); - } - } - } - break; - } + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + if (_reliable_port == ILLEGAL_PORT && !is_reliable_known && + stub_ && + !stub_->contained_in_routing_info( + VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), + its_info->get_minor())) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, + 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 ep = its_info->get_endpoint(false); + if (ep && ep->is_established()) { + discovery_->on_endpoint_connected( + _service, _instance, + ep); } } } + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, _major, _minor); } } } @@ -2464,10 +2511,12 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst if(!its_info) return; - on_availability(_service, _instance, false, - its_info->get_major(), its_info->get_minor()); - stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_UNAVAILABLE, its_info->get_major(), its_info->get_minor()); + if (stub_) + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), its_info->get_minor()); // Implicit unsubscribe std::vector> its_events; @@ -2482,7 +2531,7 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst // do no longer exist and the last received payload is no // longer valid. for (auto &its_event : its_eventgroup.second->get_events()) { - const auto& its_subscribers = its_event->get_subscribers(); + const auto its_subscribers = its_event->get_subscribers(); for (const auto its_subscriber : its_subscribers) { if (its_subscriber != get_client()) { its_event->remove_subscriber( @@ -2747,24 +2796,12 @@ void routing_manager_impl::init_routing_info() { = configuration_->get_reliable_port(i.first, i.second); uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); - major_version_t its_major - = configuration_->get_major_version(i.first, i.second); - minor_version_t its_minor - = configuration_->get_minor_version(i.first, i.second); - ttl_t its_ttl - = configuration_->get_ttl(i.first, i.second); if (its_reliable_port != ILLEGAL_PORT || its_unreliable_port != ILLEGAL_PORT) { - VSOMEIP_INFO << "Adding static remote service [" - << std::hex << std::setw(4) << std::setfill('0') - << i.first << "." << i.second - << std::dec << ":" << +its_major << "." << its_minor - << "]"; - add_routing_info(i.first, i.second, - its_major, its_minor, its_ttl, + DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, its_address, its_reliable_port, its_address, its_unreliable_port); @@ -3009,7 +3046,7 @@ void routing_manager_impl::on_subscribe_ack(client_t _client, host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); } - } else { + } else if (stub_) { stub_->send_subscribe_ack(its_subscriber, _service, _instance, _eventgroup, _event); } @@ -3025,20 +3062,13 @@ std::shared_ptr routing_manager_impl::find_or_create_remote_client( void routing_manager_impl::on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id, bool _simulated) { + event_t _event, remote_subscription_id_t _id) { (void)_event; // TODO: Remove completely? auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { auto its_subscription = its_eventgroup->get_remote_subscription(_id); if (its_subscription) { - if (_simulated) { - // method was called because a subscription for unoffered - // service was received. Therefore, remove the remote_subscription - // from the eventgroupinfo to ensure subsequent similar - // subscriptions are handled like a new/unknown subscription - its_eventgroup->remove_remote_subscription(_id); - } its_subscription->set_client_state(_client, remote_subscription_state_e::SUBSCRIPTION_NACKED); @@ -3167,13 +3197,10 @@ void routing_manager_impl::send_error(return_code_e _return_code, its_endpoint_def->is_reliable()); if (its_endpoint) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #else (void) _instance; #endif @@ -3233,6 +3260,14 @@ routing_manager_impl::expire_subscriptions(bool _force) { auto its_subscriptions = its_eventgroup.second->get_remote_subscriptions(); for (auto &s : its_subscriptions) { + if(!s) { + VSOMEIP_ERROR << __func__ + << ": Remote subscription is NULL for eventgroup [" + << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup.first << "]"; + continue; + } for (auto its_client : s->get_clients()) { if (_force) { its_expired_subscriptions[s].insert(its_client); @@ -3429,13 +3464,10 @@ bool routing_manager_impl::handle_local_offer_service(client_t _client, service_ } if (!already_pinged) { // find out endpoint of previously offering application - std::shared_ptr - its_old_endpoint - = std::dynamic_pointer_cast( - find_local(its_stored_client)); + auto its_old_endpoint = find_local(its_stored_client); if (its_old_endpoint) { std::lock_guard its_lock(pending_offers_mutex_); - if(stub_->send_ping(its_stored_client)) { + if (stub_ && stub_->send_ping(its_stored_client)) { pending_offers_[_service][_instance] = std::make_tuple(_major, _minor, _client, its_stored_client); @@ -3557,10 +3589,11 @@ void routing_manager_impl::register_client_error_handler(client_t _client, } void routing_manager_impl::handle_client_error(client_t _client) { - VSOMEIP_INFO << "Client 0x" << std::hex << get_client() + VSOMEIP_INFO << "routing_manager_impl::" << __func__ << " Client 0x" << std::hex << get_client() << " handles a client error(" << std::hex << _client << ")"; if (stub_) - stub_->update_registration(_client, registration_type_e::DEREGISTER_ON_ERROR); + stub_->update_registration(_client, registration_type_e::DEREGISTER_ON_ERROR, + boost::asio::ip::address(), 0); std::forward_list> its_offers; @@ -3619,17 +3652,18 @@ std::shared_ptr routing_manager_impl::get_endpoint_manage void routing_manager_impl::send_subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { + event_t _event, const std::shared_ptr &_filter) { auto endpoint = ep_mgr_->find_local(_service, _instance); - if (endpoint) { + if (endpoint && stub_) { stub_->send_subscribe(endpoint, _client, - _service, _instance, _eventgroup, _major, _event, PENDING_SUBSCRIPTION_ID); + _service, _instance, + _eventgroup, _major, + _event, _filter, + PENDING_SUBSCRIPTION_ID); } } void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { - - // Ignore setting to the current routing state { std::lock_guard its_lock(routing_state_mutex_); if (routing_state_ == _routing_state) { @@ -3640,7 +3674,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { routing_state_ = _routing_state; } - if(discovery_) { + if (discovery_) { switch (_routing_state) { case routing_state_e::RS_SUSPENDED: { @@ -3656,6 +3690,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { // remove all remote subscriptions to remotely offered services on this node expire_subscriptions(true); + std::vector> _service_infos; // send StopOffer messages for remotely offered services on this node for (const auto &its_service : get_offered_services()) { for (const auto &its_instance : its_service.second) { @@ -3666,9 +3701,16 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << " still offered by " << std::hex << std::setw(4) << std::setfill('0') << its_client; } - discovery_->stop_offer_service(its_instance.second); + // collect stop offers to be sent out + if (discovery_->stop_offer_service(its_instance.second, false)) { + _service_infos.push_back(its_instance.second); + } } } + // send collected stop offers packed together in one ore multiple SD messages + discovery_->send_collected_stop_offers(_service_infos); + _service_infos.clear(); + { std::lock_guard its_lock(remote_subscription_state_mutex_); remote_subscription_state_.clear(); @@ -3746,7 +3788,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { for (const auto &its_instance : its_service.second) { if (host_->get_configuration()->is_someip( its_service.first, its_instance.first)) { - discovery_->stop_offer_service(its_instance.second); + discovery_->stop_offer_service(its_instance.second, true); } } } @@ -3791,7 +3833,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { } void routing_manager_impl::on_net_interface_or_route_state_changed( - bool _is_interface, std::string _if, bool _available) { + bool _is_interface, const std::string &_if, bool _available) { std::lock_guard its_lock(pending_sd_offers_mutex_); auto log_change_message = [&_if, _available, _is_interface](bool _warning) { std::stringstream ss; @@ -3864,36 +3906,184 @@ void routing_manager_impl::start_ip_routing() { VSOMEIP_INFO << VSOMEIP_ROUTING_READY_MESSAGE; } -void routing_manager_impl::requested_service_add(client_t _client, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { +void +routing_manager_impl::add_requested_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + std::lock_guard ist_lock(requested_services_mutex_); - requested_services_[_client][_service][_instance].insert({ _major, _minor }); + requested_services_[_service][_instance][_major][_minor].insert(_client); } -void routing_manager_impl::requested_service_remove(client_t _client, - service_t _service, - instance_t _instance) { +void +routing_manager_impl::remove_requested_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + std::lock_guard ist_lock(requested_services_mutex_); - auto found_client = requested_services_.find(_client); - if (found_client != requested_services_.end()) { - auto found_service = found_client->second.find(_service); - if (found_service != found_client->second.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - // delete all requested major/minor versions - found_service->second.erase(_instance); - if (!found_service->second.size()) { - found_client->second.erase(_service); - if (!found_client->second.size()) { - requested_services_.erase(_client); + + using minor_map_t = std::map >; + using major_map_t = std::map; + using instance_map_t = std::map; + + auto delete_client = [&_client]( + minor_map_t::iterator& _minor_iter, + const major_map_t::iterator& _parent_major_iter) { + if (_minor_iter->second.erase(_client)) { // client was requester + if (_minor_iter->second.empty()) { + // client was last requester of this minor version + _minor_iter = _parent_major_iter->second.erase(_minor_iter); + } else { // there are still other requesters of this minor version + ++_minor_iter; + } + } else { // client wasn't requester + ++_minor_iter; + } + }; + + auto handle_minor = [&_minor, &delete_client]( + major_map_t::iterator& _major_iter, + const instance_map_t::iterator& _parent_instance_iter) { + if (_minor == ANY_MINOR) { + for (auto minor_iter = _major_iter->second.begin(); + minor_iter != _major_iter->second.end(); ) { + delete_client(minor_iter, _major_iter); + } + } else { + auto found_minor = _major_iter->second.find(_minor); + if (found_minor != _major_iter->second.end()) { + delete_client(found_minor, _major_iter); + } + } + if (_major_iter->second.empty()) { + // client was last requester of this major version + _major_iter = _parent_instance_iter->second.erase(_major_iter); + } else { + ++_major_iter; + } + }; + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + if (_major == ANY_MAJOR) { + for (auto major_iter = found_instance->second.begin(); + major_iter != found_instance->second.end();) { + handle_minor(major_iter, found_instance); + } + } else { + auto found_major = found_instance->second.find(_major); + if (found_major != found_instance->second.end()) { + handle_minor(found_major, found_instance); + } + } + if (found_instance->second.empty()) { + // client was last requester of this instance + found_service->second.erase(found_instance); + if (found_service->second.empty()) { + // client was last requester of this service + requested_services_.erase(found_service); + } + } + } + } +} + +std::vector > +routing_manager_impl::get_requested_services(client_t _client) { + std::lock_guard ist_lock(requested_services_mutex_); + std::vector> its_requests; + for (const auto& service : requested_services_) { + for (const auto& instance : service.second) { + bool requested = false; + for (const auto& major : instance.second) { + for (const auto& minor : major.second) { + if (minor.second.find(_client) != minor.second.end()) { + requested = true; + break; + } + } + if (requested) { + break; + } + } + if (requested) { + its_requests.push_back( + std::make_pair(service.first, instance.first)); + break; + } + } + } + return (its_requests); +} + +std::set +routing_manager_impl::get_requesters(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + std::lock_guard ist_lock(requested_services_mutex_); + return (get_requesters_unlocked(_service, _instance, _major, _minor)); +} + +std::set +routing_manager_impl::get_requesters_unlocked( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + std::set its_requesters; + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (const auto& its_major : found_instance->second) { + if (its_major.first == _major || _major == DEFAULT_MAJOR + || its_major.first == ANY_MAJOR) { + for (const auto &its_minor : its_major.second) { + if (its_minor.first <= _minor + || _minor == DEFAULT_MINOR + || its_minor.first == ANY_MINOR) { + if (its_requesters.empty()) { + its_requesters = its_minor.second; + } else { + its_requesters.insert(its_minor.second.cbegin(), + its_minor.second.cend()); + } + } } } } } } + return (its_requesters); +} + +bool +routing_manager_impl::has_requester_unlocked( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (const auto& its_major : found_instance->second) { + if (its_major.first == _major || _major == DEFAULT_MAJOR + || its_major.first == ANY_MAJOR) { + for (const auto &its_minor : its_major.second) { + if (its_minor.first <= _minor + || _minor == DEFAULT_MINOR + || its_minor.first == ANY_MINOR) { + + return (true); + } + } + } + } + } + } + return (false); } std::set @@ -3934,7 +4124,7 @@ void routing_manager_impl::clear_targets_and_pending_sub_from_eventgroups( // longer valid. for (auto &its_event : its_eventgroup.second->get_events()) { const auto its_subscribers = its_event->get_subscribers(); - for (const auto& its_subscriber : its_subscribers) { + for (const auto its_subscriber : its_subscribers) { if (its_subscriber != get_client()) { its_event->remove_subscriber( its_eventgroup.first, its_subscriber); @@ -3994,7 +4184,9 @@ void routing_manager_impl::call_sd_endpoint_connected( bool routing_manager_impl::create_placeholder_event_and_subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client) { + event_t _event, const std::shared_ptr &_filter, + client_t _client) { + bool is_inserted(false); // we received a event which was not yet requested/offered // create a placeholder field until someone requests/offers this event with @@ -4047,7 +4239,8 @@ bool routing_manager_impl::create_placeholder_event_and_subscribe( std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, false); + is_inserted = its_event->add_subscriber( + _eventgroup, _filter, _client, false); } return is_inserted; } @@ -4097,7 +4290,7 @@ void routing_manager_impl::handle_subscription_state( // Subscription already acknowledged! if (_client == get_client()) { host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); - } else { + } else if (stub_) { stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event); } } @@ -4140,11 +4333,10 @@ void routing_manager_impl::memory_log_timer_cbk( if (_error) { return; } -#ifndef _WIN32 + +#if defined(__linux__) || defined(ANDROID) static const std::uint32_t its_pagesize = static_cast(getpagesize() / 1024); -#else - static const std::uint32_t its_pagesize = 4096 / 1024; -#endif + std::FILE *its_file = std::fopen("/proc/self/statm", "r"); if (!its_file) { VSOMEIP_ERROR << "memory_log_timer_cbk: couldn't open:" @@ -4166,11 +4358,10 @@ void routing_manager_impl::memory_log_timer_cbk( << std::string(std::strerror(errno)); } std::fclose(its_file); -#ifndef _WIN32 + struct timespec cputs, monots; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cputs); clock_gettime(CLOCK_MONOTONIC, &monots); -#endif VSOMEIP_INFO << "memory usage: " << "VmSize " << std::dec << its_size * its_pagesize << " kB, " @@ -4178,12 +4369,11 @@ void routing_manager_impl::memory_log_timer_cbk( << "shared pages " << std::dec << its_sharedpages * its_pagesize << " kB, " << "text " << std::dec << its_text * its_pagesize << " kB, " << "data " << std::dec << its_data * its_pagesize << " kB " -#ifndef _WIN32 << "| monotonic time: " << std::dec << monots.tv_sec << "." << std::dec << monots.tv_nsec << " cpu time: " << std::dec << cputs.tv_sec << "." << std::dec << cputs.tv_nsec -#endif ; +#endif { std::lock_guard its_lock(memory_log_timer_mutex_); @@ -4278,8 +4468,9 @@ void routing_manager_impl::send_subscription( const remote_subscription_id_t _id) { if (host_->get_client() == _offering_client) { auto self = shared_from_this(); - for (const auto& its_client : _clients) { - host_->on_subscription(_service, _instance, _eventgroup, its_client, own_uid_, own_gid_, true, + for (const auto its_client : _clients) { + host_->on_subscription(_service, _instance, _eventgroup, its_client, + get_sec_client(), get_env(its_client), true, [this, self, _service, _instance, _eventgroup, its_client, _id] (const bool _is_accepted) { try { @@ -4288,7 +4479,7 @@ void routing_manager_impl::send_subscription( &routing_manager_stub_host::on_subscribe_nack, std::dynamic_pointer_cast(shared_from_this()), its_client, _service, _instance, - _eventgroup, ANY_EVENT, _id, false); + _eventgroup, ANY_EVENT, _id); io_.post(its_callback); } else { const auto its_callback = std::bind( @@ -4304,15 +4495,15 @@ void routing_manager_impl::send_subscription( }); } } else { // service hosted by local client - for (const auto& its_client : _clients) { - if (!stub_->send_subscribe(find_local(_offering_client), its_client, - _service, _instance, _eventgroup, _major, ANY_EVENT, _id)) { + for (const auto its_client : _clients) { + if (stub_ && !stub_->send_subscribe(find_local(_offering_client), its_client, + _service, _instance, _eventgroup, _major, ANY_EVENT, nullptr, _id)) { try { const auto its_callback = std::bind( &routing_manager_stub_host::on_subscribe_nack, std::dynamic_pointer_cast(shared_from_this()), its_client, _service, _instance, _eventgroup, - ANY_EVENT, _id, true); + ANY_EVENT, _id); io_.post(its_callback); } catch (const std::exception &e) { VSOMEIP_ERROR << __func__ << e.what(); @@ -4378,7 +4569,8 @@ void routing_manager_impl::on_resend_provided_events_response( } void routing_manager_impl::print_stub_status() const { - stub_->print_endpoint_status(); + if (stub_) + stub_->print_endpoint_status(); } void routing_manager_impl::service_endpoint_connected( @@ -4389,9 +4581,12 @@ void routing_manager_impl::service_endpoint_connected( if (!_unreliable_only) { // Mark only TCP-only and TCP+UDP services available here // UDP-only services are already marked as available in add_routing_info - on_availability(_service, _instance, true, _major, _minor); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, _major, _minor); + if (stub_) + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + _major, _minor); } std::shared_ptr its_timer = @@ -4413,9 +4608,12 @@ void routing_manager_impl::service_endpoint_disconnected( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, const std::shared_ptr& _endpoint) { (void)_endpoint; - on_availability(_service, _instance, false, _major, _minor); - stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_UNAVAILABLE, _major, _minor); + if (stub_) + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + _major, _minor); VSOMEIP_WARNING << __func__ << ": lost connection to remote service: [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; @@ -4432,9 +4630,9 @@ routing_manager_impl::send_unsubscription(client_t _offering_client, if (host_->get_client() == _offering_client) { auto self = shared_from_this(); - for (const auto& its_client : _removed) { - host_->on_subscription(_service, _instance, - _eventgroup, its_client, own_uid_, own_gid_, false, + for (const auto its_client : _removed) { + host_->on_subscription(_service, _instance, _eventgroup, + its_client, get_sec_client(), get_env(its_client),false, [this, self, _service, _instance, _eventgroup, its_client, _id] (const bool _is_accepted) { @@ -4452,8 +4650,8 @@ routing_manager_impl::send_unsubscription(client_t _offering_client, ); } } else { - for (const auto& its_client : _removed) { - if (!stub_->send_unsubscribe(find_local(_offering_client), its_client, + for (const auto its_client : _removed) { + if (stub_ && !stub_->send_unsubscribe(find_local(_offering_client), its_client, _service, _instance, _eventgroup, ANY_EVENT, _id)) { try { const auto its_callback = std::bind( @@ -4480,19 +4678,21 @@ routing_manager_impl::send_expired_subscription(client_t _offering_client, auto self = shared_from_this(); for (const auto its_client : _removed) { host_->on_subscription(_service, _instance, - _eventgroup, its_client, own_uid_, own_gid_, false, + _eventgroup, its_client, get_sec_client(), get_env(its_client), false, [] (const bool _subscription_accepted){ (void)_subscription_accepted; }); } } else { for (const auto its_client : _removed) { - stub_->send_expired_subscription(find_local(_offering_client), its_client, - _service, _instance, _eventgroup, ANY_EVENT, _id); + if (stub_) + stub_->send_expired_subscription(find_local(_offering_client), its_client, + _service, _instance, _eventgroup, ANY_EVENT, _id); } } } +#ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_impl::update_security_policy_configuration( uint32_t _uid, uint32_t _gid, @@ -4518,6 +4718,7 @@ routing_manager_impl::remove_security_policy_configuration( return (false); } +#endif // !VSOMEIP_DISABLE_SECURITY bool routing_manager_impl::insert_event_statistics(service_t _service, instance_t _instance, method_t _method, length_t _length) { @@ -4527,7 +4728,7 @@ bool routing_manager_impl::insert_event_statistics(service_t _service, instance_ const auto its_tuple = std::make_tuple(_service, _instance, _method); const auto its_main_s = message_statistics_.find(its_tuple); if (its_main_s != message_statistics_.end()) { - // increase counter and calculate moving avergae for payload length + // increase counter and calculate moving average for payload length its_main_s->second.avg_length_ = (its_main_s->second.avg_length_ * its_main_s->second.counter_ + _length) / (its_main_s->second.counter_ + 1); @@ -4537,10 +4738,10 @@ bool routing_manager_impl::insert_event_statistics(service_t _service, instance_ // check list for entry with least counter value uint32_t its_min_count(0xFFFFFFFF); auto its_tuple_to_discard = std::make_tuple(0xFFFF, 0xFFFF, 0xFFFF); - for (const auto &it : message_statistics_) { - if (it.second.counter_ < its_min_count) { - its_min_count = it.second.counter_; - its_tuple_to_discard = it.first; + for (const auto &s : message_statistics_) { + if (s.second.counter_ < its_min_count) { + its_min_count = s.second.counter_; + its_tuple_to_discard = s.first; } } if (its_min_count != 0xFFFF @@ -4580,7 +4781,7 @@ void routing_manager_impl::statistics_log_timer_cbk(boost::system::error_code co { std::lock_guard its_lock(message_statistics_mutex_); for (const auto &s : message_statistics_) { - if (s.second.counter_ / (its_interval / 1000) >= its_min_freq) { + if (s.second.counter_ / (its_interval / 1000) > its_min_freq) { uint16_t its_subscribed(0); std::shared_ptr its_event = find_event(std::get<0>(s.first), std::get<1>(s.first), std::get<2>(s.first)); if (its_event) { @@ -4621,9 +4822,86 @@ void routing_manager_impl::statistics_log_timer_cbk(boost::system::error_code co } } +bool +routing_manager_impl::get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const { + + return (routing_manager_base::get_guest(_client, _address, _port)); +} + +void +routing_manager_impl::add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) { + + routing_manager_base::add_guest(_client, _address, _port); +} + +void +routing_manager_impl::remove_guest(client_t _client) { + + routing_manager_base::remove_guest(_client); +} + void routing_manager_impl::send_suspend() const { + if (stub_) + stub_->send_suspend(); +} + +void routing_manager_impl::clear_local_services() { + + std::lock_guard its_lock(local_services_mutex_); + local_services_.clear(); +} + +void routing_manager_impl::register_message_acceptance_handler( + const message_acceptance_handler_t& _handler) { + message_acceptance_handler_ = _handler; +} + +void +routing_manager_impl::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + std::map > > >its_eventgroups; + { + std::lock_guard its_lock(eventgroups_mutex_); + its_eventgroups = eventgroups_; + } + for (const auto &its_service : its_eventgroups) { + for (const auto &its_instance : its_service.second) { + for (const auto &its_eventgroup : its_instance.second) { + const auto its_info = its_eventgroup.second; + for (auto its_subscription + : its_info->get_remote_subscriptions()) { + auto its_definition = its_subscription->get_reliable(); + if (its_definition + && its_definition->get_address() == _remote_address + && its_definition->get_port() == _remote_port + && its_definition->get_remote_port() == _local_port) { + + VSOMEIP_INFO << __func__ + << ": Removing subscription to [" + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_instance() << "." + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_eventgroup() + << "] from target " + << its_definition->get_address() << ":" + << std::dec << its_definition->get_port() + << " reliable=true"; - stub_->send_suspend(); + on_remote_unsubscribe(its_subscription); + } + } + } + } + } } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp deleted file mode 100644 index 06573a517..000000000 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ /dev/null @@ -1,2734 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../include/event.hpp" -#include "../include/routing_manager_host.hpp" -#include "../include/routing_manager_proxy.hpp" -#include "../../configuration/include/configuration.hpp" -#include "../../security/include/policy.hpp" -#include "../../security/include/security_impl.hpp" - -#include "../../endpoints/include/local_client_endpoint_impl.hpp" -#include "../../endpoints/include/local_server_endpoint_impl.hpp" -#include "../../message/include/deserializer.hpp" -#include "../../message/include/message_impl.hpp" -#include "../../message/include/serializer.hpp" -#include "../../service_discovery/include/runtime.hpp" -#include "../../utility/include/byteorder.hpp" -#include "../../utility/include/utility.hpp" -#ifdef USE_DLT -#include "../../tracing/include/connector_impl.hpp" -#endif - -namespace vsomeip_v3 { - -routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host, - bool _client_side_logging, - const std::set > & _client_side_logging_filter) : - routing_manager_base(_host), - is_connected_(false), - is_started_(false), - state_(inner_state_type_e::ST_DEREGISTERED), - sender_(nullptr), - receiver_(nullptr), - register_application_timer_(io_), - request_debounce_timer_ (io_), - request_debounce_timer_running_(false), - client_side_logging_(_client_side_logging), - client_side_logging_filter_(_client_side_logging_filter) -{ -} - -routing_manager_proxy::~routing_manager_proxy() { -} - -void routing_manager_proxy::init() { - routing_manager_base::init(std::make_shared(this, io_, configuration_)); - { - std::lock_guard its_lock(sender_mutex_); - sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); - } -} - -void routing_manager_proxy::start() { - is_started_ = true; - { - std::lock_guard its_lock(sender_mutex_); - if (!sender_) { - // application has been stopped and started again - sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); - } - if (sender_) { - sender_->start(); - } - } -} - -void routing_manager_proxy::stop() { - std::unique_lock its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERING) { - register_application_timer_.cancel(); - } - - const std::chrono::milliseconds its_timeout(configuration_->get_shutdown_timeout()); - while (state_ == inner_state_type_e::ST_REGISTERING) { - std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); - if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << client_ << " registering timeout on stop"; - break; - } - } - - if (state_ == inner_state_type_e::ST_REGISTERED) { - deregister_application(); - // Waiting de-register acknowledge to synchronize shutdown - while (state_ == inner_state_type_e::ST_REGISTERED) { - std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); - if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << client_ << " couldn't deregister application - timeout"; - break; - } - } - } - is_started_ = false; - its_lock.unlock(); - - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_.cancel(); - } - - if (receiver_) { - receiver_->stop(); - } - receiver_ = nullptr; - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->stop(); - } - // delete the sender - sender_ = nullptr; - } - - for (const auto& client : ep_mgr_->get_connected_clients()) { - if (client != VSOMEIP_ROUTING_CLIENT) { - remove_local(client, true); - } - } - - std::stringstream its_client; - its_client << utility::get_base_path(configuration_) << std::hex << client_; -#ifdef _WIN32 - ::_unlink(its_client.str().c_str()); -#else - if (-1 == ::unlink(its_client.str().c_str())) { - VSOMEIP_ERROR<< "routing_manager_proxy::stop unlink failed (" - << its_client.str() << "): "<< std::strerror(errno); - } -#endif -} - -std::shared_ptr routing_manager_proxy::get_configuration() const { - return host_->get_configuration(); -} - -bool routing_manager_proxy::offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - - if(!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) { - VSOMEIP_WARNING << "routing_manager_proxy::offer_service," - << "routing_manager_base::offer_service returned false"; - return false; - } - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - send_offer_service(_client, _service, _instance, _major, _minor); - } - service_data_t offer = { _service, _instance, _major, _minor }; - pending_offers_.insert(offer); - } - return true; -} - -void routing_manager_proxy::send_offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - (void)_client; - - byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor, - sizeof(_minor)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::stop_offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - - (void)_client; - - { - // Hold the mutex to ensure no placeholder event is created inbetween. - std::lock_guard its_lock(stop_mutex_); - - routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor); - clear_remote_subscriber_count(_service, _instance); - - // Note: The last argument does not matter here as a proxy - // does not manage endpoints to the external network. - clear_service_info(_service, _instance, false); - } - - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_STOP_OFFER_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor, - sizeof(_minor)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - auto it = pending_offers_.begin(); - while (it != pending_offers_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != pending_offers_.end()) pending_offers_.erase(it); - } -} - -void routing_manager_proxy::request_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - routing_manager_base::request_service(_client, - _service, _instance, _major, _minor); - { - std::lock_guard its_lock(state_mutex_); - size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name()); - service_data_t request = { _service, _instance, _major, _minor }; - if (!request_debouncing_time) { - if (state_ == inner_state_type_e::ST_REGISTERED) { - std::set requests; - requests.insert(request); - send_request_services(requests); - } - requests_.insert(request); - } else { - requests_to_debounce_.insert(request); - std::lock_guard its_lock(request_timer_mutex_); - if (!request_debounce_timer_running_) { - request_debounce_timer_running_ = true; - request_debounce_timer_.expires_from_now(std::chrono::milliseconds(request_debouncing_time)); - request_debounce_timer_.async_wait( - std::bind( - &routing_manager_proxy::request_debounce_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } - } -} - -void routing_manager_proxy::release_service(client_t _client, - service_t _service, instance_t _instance) { - routing_manager_base::release_service(_client, _service, _instance); - { - std::lock_guard its_lock(state_mutex_); - remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); - - auto it = requests_to_debounce_.begin(); - while (it != requests_to_debounce_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != requests_to_debounce_.end()) { - requests_to_debounce_.erase(it); - } else if (state_ == inner_state_type_e::ST_REGISTERED) { - send_release_service(_client, _service, _instance); - } - - { - auto it = requests_.begin(); - while (it != requests_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != requests_.end()) requests_.erase(it); - } - } -} - -void routing_manager_proxy::register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, const event_type_e _type, - reliability_type_e _reliability, - std::chrono::milliseconds _cycle, bool _change_resets_cycle, - bool _update_on_change, epsilon_change_func_t _epsilon_change_func, - bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) { - (void)_is_shadow; - (void)_is_cache_placeholder; - - const event_data_t registration = { - _service, - _instance, - _notifier, - _type, - _reliability, - _is_provided, - _eventgroups - }; - bool is_first(false); - { - std::lock_guard its_lock(state_mutex_); - is_first = pending_event_registrations_.find(registration) - == pending_event_registrations_.end(); -#ifndef VSOMEIP_ENABLE_COMPAT - if (is_first) { - pending_event_registrations_.insert(registration); - } -#else - bool insert = true; - if (is_first) { - for (auto iter = pending_event_registrations_.begin(); - iter != pending_event_registrations_.end();) { - if (iter->service_ == _service - && iter->instance_ == _instance - && iter->notifier_ == _notifier - && iter->is_provided_ == _is_provided - && iter->type_ == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) { - iter = pending_event_registrations_.erase(iter); - iter = pending_event_registrations_.insert(registration).first; - is_first = true; - insert = false; - break; - } else { - iter++; - } - } - if (insert) { - pending_event_registrations_.insert(registration); - } - } -#endif - } - if (is_first || _is_provided) { - routing_manager_base::register_event(_client, - _service, _instance, - _notifier, - _eventgroups, _type, _reliability, - _cycle, _change_resets_cycle, _update_on_change, - _epsilon_change_func, - _is_provided); - } - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED && is_first) { - send_register_event(client_, _service, _instance, - _notifier, _eventgroups, _type, _reliability, _is_provided); - } - } -} - -void routing_manager_proxy::unregister_event(client_t _client, - service_t _service, instance_t _instance, event_t _notifier, - bool _is_provided) { - - routing_manager_base::unregister_event(_client, _service, _instance, - _notifier, _is_provided); - - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNREGISTER_EVENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier, - sizeof(_notifier)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] - = static_cast(_is_provided); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - - for (auto iter = pending_event_registrations_.begin(); - iter != pending_event_registrations_.end(); ) { - if (iter->service_ == _service - && iter->instance_ == _instance - && iter->notifier_ == _notifier - && iter->is_provided_ == _is_provided) { - pending_event_registrations_.erase(iter); - break; - } else { - iter++; - } - } - } -} - -bool routing_manager_proxy::is_field(service_t _service, instance_t _instance, - event_t _event) const { - auto event = find_event(_service, _instance, _event); - if (event && event->is_field()) { - return true; - } - return false; -} - -void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { - (void)_uid; - (void)_gid; - { - credentials_t its_credentials = std::make_pair(own_uid_, own_gid_); - if (_event == ANY_EVENT) { - if (!is_subscribe_to_any_event_allowed(its_credentials, _client, _service, _instance, _eventgroup)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client - << " : routing_manager_proxy::subscribe: " - << " isn't allowed to subscribe to service/instance/event " - << _service << "/" << _instance << "/ANY_EVENT" - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } else { - auto its_security = security_impl::get(); - if (!its_security) - return; - if (!its_security->is_client_allowed(own_uid_, own_gid_, - _client, _service, _instance, _event)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client - << " : routing_manager_proxy::subscribe: " - << " isn't allowed to subscribe to service/instance/event " - << _service << "/" << _instance - << "/" << _event; - return; - } - } - - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { - send_subscribe(client_, _service, _instance, _eventgroup, _major, _event ); - } - subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid}; - pending_subscriptions_.insert(subscription); - } -} - -void routing_manager_proxy::send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { - (void)_client; - - byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - client_t target_client = find_local_client(_service, _instance); - if (target_client != VSOMEIP_ROUTING_CLIENT) { - auto its_target = ep_mgr_->find_or_create_local(target_client); - its_target->send(its_command, sizeof(its_command)); - } else { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_subscribe_nack(client_t _subscriber, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber, - sizeof(_subscriber)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id, - sizeof(_id)); - - if (_subscriber != VSOMEIP_ROUTING_CLIENT - && _id == PENDING_SUBSCRIPTION_ID) { - auto its_target = ep_mgr_->find_local(_subscriber); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - return; - } - } - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_subscribe_ack(client_t _subscriber, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber, - sizeof(_subscriber)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id, - sizeof(_id)); - - if (_subscriber != VSOMEIP_ROUTING_CLIENT - && _id == PENDING_SUBSCRIPTION_ID) { - auto its_target = ep_mgr_->find_local(_subscriber); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - return; - } - } - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; - (void)_uid; - (void)_gid; - { - std::lock_guard its_lock(state_mutex_); - remove_pending_subscription(_service, _instance, _eventgroup, _event); - - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - auto its_target = ep_mgr_->find_local(_service, _instance); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - } else { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - } -} - -bool routing_manager_proxy::send(client_t _client, const byte_t *_data, - length_t _size, instance_t _instance, - bool _reliable, - client_t _bound_client, - credentials_t _credentials, - uint8_t _status_check, - bool _sent_from_remote) { - (void)_client; - (void)_bound_client; - (void)_credentials; - (void)_sent_from_remote; - bool is_sent(false); - bool has_remote_subscribers(false); - { - std::lock_guard its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - return false; - } - } - if (client_side_logging_) { - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - if (client_side_logging_filter_.empty() - || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE))) - || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) { - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - VSOMEIP_INFO << "routing_manager_proxy::send: (" - << std::hex << std::setw(4) << std::setfill('0') << client_ <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_method << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_session << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "] " - << "type=" << std::hex << static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]) - << " thread=" << std::hex << std::this_thread::get_id(); - } - } else { - VSOMEIP_ERROR << "routing_manager_proxy::send: (" - << std::hex << std::setw(4) << std::setfill('0') << client_ - <<"): message too short to log: " << std::dec << _size; - } - } - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - std::shared_ptr its_target; - if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - // Request - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - client_t its_client = find_local_client(its_service, _instance); - if (its_client != VSOMEIP_ROUTING_CLIENT) { - if (is_client_known(its_client)) { - its_target = ep_mgr_->find_or_create_local(its_client); - } - } - } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - // Response - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - if (its_client != VSOMEIP_ROUTING_CLIENT) { - if (is_client_known(its_client)) { - its_target = ep_mgr_->find_or_create_local(its_client); - } - } - } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && - _client == VSOMEIP_ROUTING_CLIENT) { - // notify - has_remote_subscribers = send_local_notification(get_client(), _data, _size, - _instance, _reliable, _status_check); - } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && - _client != VSOMEIP_ROUTING_CLIENT) { - // notify_one - its_target = ep_mgr_->find_local(_client); - if (its_target) { -#ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - - trace::header its_header; - if (its_header.prepare(nullptr, true, _instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); -#endif - return send_local(its_target, get_client(), _data, _size, - _instance, _reliable, VSOMEIP_SEND, _status_check); - } - } - // If no direct endpoint could be found - // or for notifications ~> route to routing_manager_stub -#ifdef USE_DLT - bool message_to_stub(false); -#endif - if (!its_target) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - its_target = sender_; -#ifdef USE_DLT - message_to_stub = true; -#endif - } else { - return false; - } - } - - bool send(true); - uint8_t command = VSOMEIP_SEND; - - if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (_client != VSOMEIP_ROUTING_CLIENT) { - command = VSOMEIP_NOTIFY_ONE; - } else { - command = VSOMEIP_NOTIFY; - // Do we need to deliver a notification to the routing manager? - // Only for services which already have remote clients subscribed to - send = has_remote_subscribers; - } - } -#ifdef USE_DLT - else if (!message_to_stub) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - - trace::header its_header; - if (its_header.prepare(nullptr, true, _instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); - } -#endif - if (send) { - is_sent = send_local(its_target, - (command == VSOMEIP_NOTIFY_ONE ? _client : get_client()), - _data, _size, _instance, _reliable, command, _status_check); - } - } - return (is_sent); -} - -bool routing_manager_proxy::send_to(const client_t _client, - const std::shared_ptr &_target, - std::shared_ptr _message) { - (void)_client; - (void)_target; - (void)_message; - return (false); -} - -bool routing_manager_proxy::send_to( - const std::shared_ptr &_target, - const byte_t *_data, uint32_t _size, instance_t _instance) { - (void)_target; - (void)_data; - (void)_size; - (void)_instance; - return (false); -} - -void routing_manager_proxy::on_connect(const std::shared_ptr& _endpoint) { - _endpoint->set_connected(true); - _endpoint->set_established(true); - { - std::lock_guard its_lock(sender_mutex_); - if (_endpoint != sender_) { - return; - } - } - is_connected_ = true; - assign_client(); -} - -void routing_manager_proxy::on_disconnect(const std::shared_ptr& _endpoint) { - - bool is_disconnected((_endpoint == sender_)); - if (is_disconnected) { - { - std::lock_guard its_lock(sender_mutex_); - is_connected_ = false; - } - - VSOMEIP_INFO << "routing_manager_proxy::on_disconnect: Client 0x" << std::hex - << get_client() << " calling host_->on_state " - << "with DEREGISTERED"; - host_->on_state(state_type_e::ST_DEREGISTERED); - } -} - -void routing_manager_proxy::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port) { - (void)_receiver; - (void)_destination; - (void)_remote_address; - (void)_remote_port; -#if 0 - std::stringstream msg; - msg << "rmp::on_message: "; - for (length_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - byte_t its_command; - client_t its_client; - length_t its_length; - service_t its_service; - instance_t its_instance; - eventgroup_t its_eventgroup; - event_t its_event; - major_version_t its_major; - client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host()); - client_t its_subscriber; - remote_subscription_id_t its_subscription_id(PENDING_SUBSCRIPTION_ID); - std::uint32_t its_remote_subscriber_count(0); - bool is_internal_policy_update(false); - - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); - - auto its_security = security_impl::get(); - if (!its_security) - return; - - if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) { - its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], - sizeof(its_client)); - std::memcpy(&its_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_length)); - - bool message_from_routing(false); - if (its_security->is_enabled()) { - // if security is enabled, client ID of routing must be configured - // and credential passing is active. Otherwise bound client is zero by default - message_from_routing = (_bound_client == routing_host_id); - } else { - message_from_routing = (its_client == routing_host_id); - } - - if (its_security->is_enabled() && !message_from_routing && - _bound_client != its_client) { - VSOMEIP_WARNING << std::hex << "Client " << std::setw(4) << std::setfill('0') << get_client() - << " received a message with command " << (uint32_t)its_command - << " from " << std::setw(4) << std::setfill('0') - << its_client << " which doesn't match the bound client " - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } - - switch (its_command) { - case VSOMEIP_SEND: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command with too small size -> skip!"; - break; - } - instance_t its_instance; - bool its_reliable; - uint8_t its_check_status; - std::memcpy(&its_instance,&_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(instance_t)); - std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - sizeof(its_reliable)); - std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - sizeof(its_check_status)); - - // reduce by size of instance, flush, reliable, client and is_valid_crc flag - const std::uint32_t its_message_size = its_length - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; - break; - } - - auto a_deserializer = get_deserializer(); - a_deserializer->set_data(&_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS], - its_message_size); - std::shared_ptr its_message(a_deserializer->deserialize_message()); - a_deserializer->reset(); - put_deserializer(a_deserializer); - - if (its_message) { - its_message->set_instance(its_instance); - its_message->set_reliable(its_reliable); - its_message->set_check_result(its_check_status); - its_message->set_uid(std::get<0>(_credentials)); - its_message->set_gid(std::get<1>(_credentials)); - - if (!message_from_routing) { - if (utility::is_notification(its_message->get_message_type())) { - if (!is_response_allowed(_bound_client, its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a notification from client 0x" << _bound_client - << " which does not offer service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } else { - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; - return; - } - cache_event_payload(its_message); - } - } else if (utility::is_request(its_message->get_message_type())) { - if (its_security->is_enabled() - && its_message->get_client() != _bound_client) { - VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client() - << " received a request from client 0x" << std::setw(4) << std::setfill('0') - << its_message->get_client() << " to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() << " which doesn't match the bound client 0x" - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } - - if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid, - its_message->get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client() - << " : routing_manager_proxy::on_message: " - << "isn't allowed to send a request to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } - } else { // response - if (!is_response_allowed(_bound_client, its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a response from client 0x" << _bound_client - << " which does not offer service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } else { - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a response from service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; - return; - } - } - } - } else { - if (!its_security->is_remote_client_allowed()) { - // if the message is from routing manager, check if - // policy allows remote requests. - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client - << " are not allowed to communicate with service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively with client 0x" << get_client() - << " ~> Skip message!"; - return; - } else if (utility::is_notification(its_message->get_message_type())) { - // As subscription is sent on eventgroup level, incoming remote event ID's - // need to be checked as well if remote clients are allowed - // and the local policy only allows specific events in the eventgroup to be received. - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from remote clients via routing manager with client ID 0x" - << routing_host_id - << " ~> Skip message!"; - return; - } - cache_event_payload(its_message); - } - } -#ifdef USE_DLT - if (client_side_logging_ - && (client_side_logging_filter_.empty() - || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), ANY_INSTANCE))) - || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), its_message->get_instance()))))) { - trace::header its_header; - if (its_header.prepare(nullptr, false, its_instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS], - static_cast(its_message_size)); - } -#endif - - host_->on_message(std::move(its_message)); - } else { - VSOMEIP_ERROR << "Routing proxy: on_message: " - << "SomeIP-Header deserialization failed!"; - } - break; - } - - case VSOMEIP_ASSIGN_CLIENT_ACK: { - if (_size != VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_ASSIGN_CLIENT_ACK command with wrong size ~> skip!"; - break; - } - client_t its_assigned_client(VSOMEIP_CLIENT_UNSET); - std::memcpy(&its_assigned_client, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS], sizeof(client_)); - on_client_assign_ack(its_assigned_client); - break; - } - case VSOMEIP_ROUTING_INFO: - if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "Received a ROUTING_INFO command with invalid size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << "routing_manager_proxy::on_message: " - << std::hex << "Security: Client 0x" << get_client() - << " received an routing info from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - - case VSOMEIP_PING: - if (_size != VSOMEIP_PING_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a PING command with wrong size ~> skip!"; - break; - } - send_pong(); - VSOMEIP_TRACE << "PING(" - << std::hex << std::setw(4) << std::setfill('0') << client_ << ")"; - break; - - case VSOMEIP_SUBSCRIBE: - if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_major)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9], - sizeof(its_subscription_id)); - { - std::unique_lock its_lock(incoming_subscriptions_mutex_); - if (its_subscription_id != PENDING_SUBSCRIPTION_ID) { - its_lock.unlock(); -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); -#endif - // Remote subscriber: Notify routing manager initially + count subscribes - auto self = shared_from_this(); - host_->on_subscription(its_service, its_instance, its_eventgroup, - its_client, its_sender_uid, its_sender_gid, true, - [this, self, its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id, its_major] - (const bool _subscription_accepted){ - std::uint32_t its_count = 0; - if(_subscription_accepted) { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id); - std::set its_already_subscribed_events; - bool inserted = insert_subscription(its_service, its_instance, its_eventgroup, - its_event, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events); - if (inserted) { - notify_remote_initially(its_service, its_instance, its_eventgroup, - its_already_subscribed_events); - } -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true); -#endif - its_count = get_remote_subscriber_count(its_service, its_instance, its_eventgroup, true); - } else { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id); - } - VSOMEIP_INFO << "SUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" - << std::dec << (uint16_t)its_major << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << (_subscription_accepted ? std::to_string(its_count) : "-") - << (_subscription_accepted ? " ACCEPTED" : " NOT ACCEPTED"); -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); -#endif - }); - } else if (is_client_known(its_client)) { - its_lock.unlock(); - if (!message_from_routing) { - if (its_event == ANY_EVENT) { - if (!is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, its_instance, its_eventgroup)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << " isn't allowed to subscribe to service/instance/event " - << its_service << "/" << its_instance << "/ANY_EVENT" - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } else { - if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, its_event)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << " subscribes to service/instance/event " - << its_service << "/" << its_instance << "/" << its_event - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } - } else { - if (!its_security->is_remote_client_allowed()) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << std::hex << "Routing manager with client ID 0x" - << its_client - << " isn't allowed to subscribe to service/instance/event " - << its_service << "/" << its_instance - << "/" << its_event - << " respectively to client 0x" << get_client() - << " ~> Skip Subscribe!"; - return; - } - } - - // Local & already known subscriber: create endpoint + send (N)ACK + insert subscription -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); -#endif - (void) ep_mgr_->find_or_create_local(its_client); - auto self = shared_from_this(); - host_->on_subscription(its_service, its_instance, - its_eventgroup, its_client, its_sender_uid, its_sender_gid, true, - [this, self, its_client, its_sender_uid, its_sender_gid, its_service, - its_instance, its_eventgroup, its_event, its_major] - (const bool _subscription_accepted) { - if (!_subscription_accepted) { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - } else { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - routing_manager_base::subscribe(its_client, its_sender_uid, its_sender_gid, - its_service, its_instance, its_eventgroup, its_major, its_event); -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client); -#endif - } -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); -#endif - }); - } else { - // Local & not yet known subscriber ~> set pending until subscriber gets known! - subscription_data_t subscription = { its_service, its_instance, - its_eventgroup, its_major, its_event, its_sender_uid, its_sender_gid }; - pending_incoming_subscripitons_[its_client].insert(subscription); - } - } - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { // local subscription - VSOMEIP_INFO << "SUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" - << std::dec << (uint16_t)its_major << "]"; - } - break; - - case VSOMEIP_UNSUBSCRIBE: - if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received an UNSUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_subscription_id)); - host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { - // Local subscriber: withdraw subscription - routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event); - } else { - // Remote subscriber: withdraw subscription only if no more remote subscriber exists - its_remote_subscriber_count = get_remote_subscriber_count(its_service, - its_instance, its_eventgroup, false); - if (!its_remote_subscriber_count) { - routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service, - its_instance, its_eventgroup, its_event); - } - send_unsubscribe_ack(its_service, its_instance, its_eventgroup, - its_subscription_id); - } - VSOMEIP_INFO << "UNSUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << std::dec << its_remote_subscriber_count; - break; - - case VSOMEIP_EXPIRED_SUBSCRIPTION: - if (_size != VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received an VSOMEIP_EXPIRED_SUBSCRIPTION command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_subscription_id)); - host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { - // Local subscriber: withdraw subscription - routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event); - } else { - // Remote subscriber: withdraw subscription only if no more remote subscriber exists - its_remote_subscriber_count = get_remote_subscriber_count(its_service, - its_instance, its_eventgroup, false); - if (!its_remote_subscriber_count) { - routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service, - its_instance, its_eventgroup, its_event); - } - } - VSOMEIP_INFO << "UNSUBSCRIBE EXPIRED SUBSCRIPTION(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << std::dec << its_remote_subscriber_count; - break; - - case VSOMEIP_SUBSCRIBE_NACK: - if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_NACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_event)); - - on_subscribe_nack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); - VSOMEIP_INFO << "SUBSCRIBE NACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; - break; - - case VSOMEIP_SUBSCRIBE_ACK: - if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_event)); - - on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); - VSOMEIP_INFO << "SUBSCRIBE ACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; - break; - - case VSOMEIP_OFFERED_SERVICES_RESPONSE: - if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_RESPONSE command with invalid size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_offered_services_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client() - << " received an offered services info from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - case VSOMEIP_RESEND_PROVIDED_EVENTS: { - if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!"; - break; - } - pending_remote_offer_id_t its_pending_remote_offer_id(0); - std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_remote_offer_id_t)); - resend_provided_event_registrations(); - send_resend_provided_event_response(its_pending_remote_offer_id); - VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" - << std::hex << std::setw(4) << std::setfill('0') - << its_client << ")"; - break; - } - case VSOMEIP_UPDATE_SECURITY_POLICY_INT: - is_internal_policy_update = true; - /* Fallthrough */ - case VSOMEIP_UPDATE_SECURITY_POLICY: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE + sizeof(pending_security_update_id_t) || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - pending_security_update_id_t its_update_id(0); - - std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); - - std::shared_ptr its_policy(std::make_shared()); - const byte_t *its_policy_data = _data + (VSOMEIP_COMMAND_PAYLOAD_POS + - sizeof(pending_security_update_id_t)); - - uint32_t its_policy_size = uint32_t(_size - (VSOMEIP_COMMAND_PAYLOAD_POS - + sizeof(pending_security_update_id_t))); - - bool is_valid = its_policy->deserialize(its_policy_data, its_policy_size); - if (is_valid) { - uint32_t its_uid; - uint32_t its_gid; - is_valid = its_policy->get_uid_gid(its_uid, its_gid); - if (is_valid) { - if (is_internal_policy_update - || its_security->is_policy_update_allowed(its_uid, its_policy)) { - its_security->update_security_policy(its_uid, its_gid, its_policy); - send_update_security_policy_response(its_update_id); - } - } else { - VSOMEIP_ERROR << "vSomeIP Security: Policy has no valid uid/gid!"; - } - } else { - VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!"; - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a security policy update from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_REMOVE_SECURITY_POLICY: { - if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY command with wrong size ~> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - pending_security_update_id_t its_update_id(0); - uint32_t its_uid(ANY_UID); - uint32_t its_gid(ANY_GID); - - std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); - std::memcpy(&its_uid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(uint32_t)); - std::memcpy(&its_gid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(uint32_t)); - if (its_security->is_policy_removal_allowed(its_uid)) { - its_security->remove_security_policy(its_uid, its_gid); - send_remove_security_policy_response(its_update_id); - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << "received a security policy removal from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_DISTRIBUTE_SECURITY_POLICIES: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_DISTRIBUTE_SECURITY_POLICIES command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - uint32_t its_policy_count(0); - uint32_t its_policy_size(0); - const byte_t* buffer_ptr = 0; - - if (VSOMEIP_COMMAND_PAYLOAD_POS + sizeof(uint32_t) * 2 <= _size) { - std::memcpy(&its_policy_count, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(uint32_t)); - - // skip policy count field - buffer_ptr = _data + (VSOMEIP_COMMAND_PAYLOAD_POS + - sizeof(uint32_t)); - - for (uint32_t i = 0; i < its_policy_count; i++) { - uint32_t its_uid(0); - uint32_t its_gid(0); - std::shared_ptr its_policy(std::make_shared()); - // length field of next (UID/GID + policy) - if (buffer_ptr + sizeof(uint32_t) <= _data + _size) { - std::memcpy(&its_policy_size, buffer_ptr, - sizeof(uint32_t)); - buffer_ptr += sizeof(uint32_t); - - if (buffer_ptr + its_policy_size <= _data + _size) { - if (its_security->parse_policy(buffer_ptr, its_policy_size, its_uid, its_gid, its_policy)) { - if (its_security->is_policy_update_allowed(its_uid, its_policy)) { - its_security->update_security_policy(its_uid, its_gid, its_policy); - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " could not parse policy!"; - } - } - } - } - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a security policy distribution command from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_UPDATE_SECURITY_CREDENTIALS: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_CREDENTIALS command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_update_security_credentials(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << "received a security credential update from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - - case VSOMEIP_SUSPEND: - on_suspend(); // cleanup remote subscribers - break; - - default: - break; - } - } -} - -void routing_manager_proxy::on_routing_info(const byte_t *_data, - uint32_t _size) { -#if 0 - std::stringstream msg; - msg << "rmp::on_routing_info(" << std::hex << client_ << "): "; - for (uint32_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - auto its_security = security_impl::get(); - if (!its_security) - return; - - uint32_t i = 0; - while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) { - routing_info_entry_e routing_info_entry; - std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e)); - i += uint32_t(sizeof(routing_info_entry_e)); - - uint32_t its_client_size; - std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - if (its_client_size + i > _size) { - VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : " - << "Processing of routing info failed due to bad length fields!"; - return; - } - - if (i + sizeof(client_t) <= _size) { - client_t its_client; - std::memcpy(&its_client, &_data[i], sizeof(client_t)); - i += uint32_t(sizeof(client_t)); - - if (routing_info_entry == routing_info_entry_e::RIE_ADD_CLIENT) { - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.insert(its_client); - } - if (its_client == get_client()) { - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << " (" << host_->get_name() << ") is registered."; - -#ifndef _WIN32 - if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_routing_info: RIE_ADD_CLIENT: isn't allowed" - << " to use the server endpoint due to credential check failed!"; - deregister_application(); - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - return; - } -#endif - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERING) { - boost::system::error_code ec; - register_application_timer_.cancel(ec); - send_registered_ack(); - send_pending_commands(); - state_ = inner_state_type_e::ST_REGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - } - - // inform host about its own registration state changes - if (state_ == inner_state_type_e::ST_REGISTERED) - host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); - - } - } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) { - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.erase(its_client); - } - if (its_client == get_client()) { - its_security->remove_client_to_uid_gid_mapping(its_client); - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << " (" << host_->get_name() << ") is deregistered."; - - // inform host about its own registration state changes - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - - { - std::lock_guard its_lock(state_mutex_); - state_ = inner_state_type_e::ST_DEREGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - } else if (its_client != VSOMEIP_ROUTING_CLIENT) { - remove_local(its_client, true); - } - } - - uint32_t j = 0; - while (j + sizeof(uint32_t) <= its_client_size) { - uint32_t its_services_size; - std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t)); - j += uint32_t(sizeof(uint32_t)); - - if (its_services_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - its_services_size -= uint32_t(sizeof(service_t)); - - service_t its_service; - std::memcpy(&its_service, &_data[i + j], sizeof(service_t)); - j += uint32_t(sizeof(service_t)); - - while (its_services_size >= sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - instance_t its_instance; - std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t)); - j += uint32_t(sizeof(instance_t)); - - major_version_t its_major; - std::memcpy(&its_major, &_data[i + j], sizeof(major_version_t)); - j += uint32_t(sizeof(major_version_t)); - - minor_version_t its_minor; - std::memcpy(&its_minor, &_data[i + j], sizeof(minor_version_t)); - j += uint32_t(sizeof(minor_version_t)); - - if (routing_info_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE) { - if (get_routing_state() == routing_state_e::RS_SUSPENDED) { - VSOMEIP_INFO << "rmp::" <<__func__ << " We are in suspended mode, the service will not be added!"; - return; - } - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.insert(its_client); - } - { - std::lock_guard its_lock(local_services_mutex_); - local_services_[its_service][its_instance] = std::make_tuple(its_major, its_minor, its_client); - } - { - std::lock_guard its_lock(state_mutex_); - send_pending_subscriptions(its_service, its_instance, its_major); - } - host_->on_availability(its_service, its_instance, true, its_major, its_minor); - VSOMEIP_INFO << "ON_AVAILABLE(" - << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance - << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; - } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) { - { - std::lock_guard its_lock(local_services_mutex_); - auto found_service = local_services_.find(its_service); - if (found_service != local_services_.end()) { - found_service->second.erase(its_instance); - // move previously offering client to history - local_services_history_[its_service][its_instance].insert(its_client); - if (found_service->second.size() == 0) { - local_services_.erase(its_service); - } - } - } - on_stop_offer_service(its_service, its_instance, its_major, its_minor); - host_->on_availability(its_service, its_instance, false, its_major, its_minor); - VSOMEIP_INFO << "ON_UNAVAILABLE(" - << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance - << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; - - if (its_client == get_client()) { - VSOMEIP_INFO << __func__ - << ": Clearing subscriptions for service [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "]"; - unsubscribe_all(its_service, its_instance); - } - } - - its_services_size -= uint32_t(sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t) ); - } - } - } - - i += j; - } - } - { - struct subscription_info { - service_t service_id_; - instance_t instance_id_; - eventgroup_t eventgroup_id_; - client_t client_id_; - major_version_t major_; - event_t event_; - uid_t uid_; - gid_t gid_; - }; - std::lock_guard its_lock(incoming_subscriptions_mutex_); - std::forward_list subscription_actions; - if (pending_incoming_subscripitons_.size()) { - { - std::lock_guard its_lock(known_clients_mutex_); - for (const client_t client : known_clients_) { - auto its_client = pending_incoming_subscripitons_.find(client); - if (its_client != pending_incoming_subscripitons_.end()) { - for (const auto& subscription : its_client->second) { - subscription_actions.push_front( - { subscription.service_, subscription.instance_, - subscription.eventgroup_, client, - subscription.major_, subscription.event_, - subscription.uid_, subscription.gid_ }); - } - } - } - } - for (const subscription_info &si : subscription_actions) { -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_, - si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING); -#endif - (void) ep_mgr_->find_or_create_local(si.client_id_); - auto self = shared_from_this(); - host_->on_subscription( - si.service_id_, si.instance_id_, si.eventgroup_id_, - si.client_id_, si.uid_, si.gid_, true, - [this, self, si](const bool _subscription_accepted) { - if (!_subscription_accepted) { - send_subscribe_nack(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); - } else { - send_subscribe_ack(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); - routing_manager_base::subscribe(si.client_id_, si.uid_, si.gid_, - si.service_id_, si.instance_id_, si.eventgroup_id_, - si.major_, si.event_); -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(si.service_id_, - si.instance_id_, si.eventgroup_id_, si.client_id_); -#endif - } -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_); -#endif - { - std::lock_guard its_lock2(incoming_subscriptions_mutex_); - pending_incoming_subscripitons_.erase(si.client_id_); - } - }); - } - } - } -} - -void routing_manager_proxy::on_offered_services_info(const byte_t *_data, - uint32_t _size) { -#if 0 - std::stringstream msg; - msg << "rmp::on_offered_services_info(" << std::hex << client_ << "): "; - for (uint32_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - std::vector> its_offered_services_info; - - uint32_t i = 0; - while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) { - routing_info_entry_e routing_info_entry; - std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e)); - i += uint32_t(sizeof(routing_info_entry_e)); - - uint32_t its_service_entry_size; - std::memcpy(&its_service_entry_size, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - if (its_service_entry_size + i > _size) { - VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : " - << "Processing of offered services info failed due to bad length fields!"; - return; - } - - if (its_service_entry_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - service_t its_service; - std::memcpy(&its_service, &_data[i], sizeof(service_t)); - i += uint32_t(sizeof(service_t)); - - instance_t its_instance; - std::memcpy(&its_instance, &_data[i], sizeof(instance_t)); - i += uint32_t(sizeof(instance_t)); - - major_version_t its_major; - std::memcpy(&its_major, &_data[i], sizeof(major_version_t)); - i += uint32_t(sizeof(major_version_t)); - - minor_version_t its_minor; - std::memcpy(&its_minor, &_data[i], sizeof(minor_version_t)); - i += uint32_t(sizeof(minor_version_t)); - - its_offered_services_info.push_back(std::make_pair(its_service, its_instance)); - } - } - host_->on_offered_services_info(its_offered_services_info); -} - -void routing_manager_proxy::reconnect(const std::unordered_set &_clients) { - auto its_security = security_impl::get(); - if (!its_security) - return; - - // inform host about its own registration state changes - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - - { - std::lock_guard its_lock(state_mutex_); - state_ = inner_state_type_e::ST_DEREGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - - - // Remove all local connections/endpoints - for (const auto& its_client : _clients) { - if (its_client != VSOMEIP_ROUTING_CLIENT) { - remove_local(its_client, true); - } - } - - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - <<": Reconnecting to routing manager."; - -#ifndef _WIN32 - if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::reconnect: isn't allowed" - << " to use the server endpoint due to credential check failed!"; - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->stop(); - } - return; - } -#endif - - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->restart(); - } -} - -void routing_manager_proxy::assign_client() { - std::vector its_command; - - std::string its_name(host_->get_name()); - uint32_t its_size(static_cast(its_name.size())); - its_command.resize(7 + its_name.size()); - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ASSIGN_CLIENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - if (0 < its_name.size()) - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], its_name.c_str(), - its_name.size()); - - std::lock_guard its_state_lock(state_mutex_); - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - if (state_ != inner_state_type_e::ST_DEREGISTERED) - return; - state_ = inner_state_type_e::ST_ASSIGNING; - - sender_->send(&its_command[0], static_cast(its_command.size())); - - boost::system::error_code ec; - register_application_timer_.cancel(ec); - register_application_timer_.expires_from_now(std::chrono::milliseconds(10000)); - register_application_timer_.async_wait( - std::bind( - &routing_manager_proxy::assign_client_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } -} - -void routing_manager_proxy::register_application() { - byte_t its_command[] = { - VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - state_ = inner_state_type_e::ST_REGISTERING; - sender_->send(its_command, sizeof(its_command)); - - register_application_timer_.cancel(); - register_application_timer_.expires_from_now(std::chrono::milliseconds(1000)); - register_application_timer_.async_wait( - std::bind( - &routing_manager_proxy::register_application_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } -} - -void routing_manager_proxy::deregister_application() { - std::vector its_command(VSOMEIP_COMMAND_HEADER_SIZE, 0); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_DEREGISTER_APPLICATION; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - if (is_connected_) - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(&its_command[0], uint32_t(its_command.size())); - } - } -} - -void routing_manager_proxy::send_pong() const { - byte_t its_pong[] = { - VSOMEIP_PONG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - - std::memcpy(&its_pong[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_t)); - - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_pong, sizeof(its_pong)); - } - } -} - -void routing_manager_proxy::send_request_services(std::set& _requests) { - if (!_requests.size()) { - return; - } - size_t its_size = (VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE) * _requests.size(); - if (its_size > (std::numeric_limits::max)()) { - VSOMEIP_ERROR<< "routing_manager_proxy::send_request_services too many" - << " requests (" << std::dec << its_size << "), returning."; - return; - } - - std::vector its_command(its_size + VSOMEIP_COMMAND_HEADER_SIZE); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], - &client_, sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], - &its_size, sizeof(std::uint32_t)); - - uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) - + sizeof(major_version_t) + sizeof(minor_version_t)); - - unsigned int i = 0; - for (auto its_service : _requests) { - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], - &its_service.service_, sizeof(its_service.service_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], - &its_service.instance_, sizeof(its_service.instance_)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)] = its_service.major_; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], - &its_service.minor_, sizeof(its_service.minor_)); - ++i; - } - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(&its_command[0], - static_cast(its_size + VSOMEIP_COMMAND_HEADER_SIZE)); - } - } -} - -void routing_manager_proxy::send_release_service(client_t _client, service_t _service, - instance_t _instance) { - (void)_client; - byte_t its_command[VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RELEASE_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, const event_type_e _type, - reliability_type_e _reliability, - bool _is_provided) { - - std::size_t its_eventgroups_size = (_eventgroups.size() * sizeof(eventgroup_t)) + - VSOMEIP_REGISTER_EVENT_COMMAND_SIZE; - if (its_eventgroups_size > (std::numeric_limits::max)()) { - VSOMEIP_ERROR<< "routing_manager_proxy::send_register_event too many" - << " eventgroups (" << std::dec << its_eventgroups_size << "), returning."; - return; - } - byte_t *its_command = new byte_t[its_eventgroups_size]; - uint32_t its_size = static_cast(its_eventgroups_size) - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REGISTER_EVENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier, - sizeof(_notifier)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] - = static_cast(_type); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7] - = static_cast(_is_provided); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8] - = static_cast(_reliability); - - std::size_t i = 9; - for (auto eg : _eventgroups) { - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + i], &eg, - sizeof(eventgroup_t)); - i += sizeof(eventgroup_t); - } - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, static_cast(its_eventgroups_size)); - } - } - - if (_is_provided) { - VSOMEIP_INFO << "REGISTER EVENT(" - << std::hex << std::setw(4) << std::setfill('0') << client_ << "): [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _notifier - << ":is_provider=" << _is_provided << "]"; - } - - delete[] its_command; -} - -void routing_manager_proxy::on_subscribe_ack(client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; -#if 0 - VSOMEIP_ERROR << "routing_manager_proxy::" << __func__ - << "(" << std::hex << host_->get_client() << "):" - << "event=" - << std::hex << _service << "." - << std::hex << _instance << "." - << std::hex << _eventgroup << "." - << std::hex << _event; -#endif - if (_event == ANY_EVENT) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - for (const auto& its_event : its_eventgroup->get_events()) { - host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/); - } - } - } else { - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); - } -} - -void routing_manager_proxy::on_subscribe_nack(client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; - if (_event == ANY_EVENT) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - for (const auto& its_event : its_eventgroup->get_events()) { - host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/); - } - } - } else { - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/); - } -} - -void routing_manager_proxy::cache_event_payload( - const std::shared_ptr &_message) { - const service_t its_service(_message->get_service()); - const instance_t its_instance(_message->get_instance()); - const method_t its_method(_message->get_method()); - std::shared_ptr its_event = find_event(its_service, its_instance, its_method); - if (its_event) { - if (its_event->is_field()) { - its_event->set_payload_dont_notify(_message->get_payload()); - } - } else { - // we received a event which was not yet requested - std::set its_eventgroups; - // create a placeholder field until someone requests this event with - // full information like eventgroup, field or not etc. - routing_manager_base::register_event(host_->get_client(), - its_service, its_instance, - its_method, - its_eventgroups, event_type_e::ET_UNKNOWN, - reliability_type_e::RT_UNKNOWN, - std::chrono::milliseconds::zero(), false, true, - nullptr, - false, false, true); - std::shared_ptr its_event = find_event(its_service, its_instance, its_method); - if (its_event) { - its_event->set_payload_dont_notify(_message->get_payload()); - } - } - -} - -void routing_manager_proxy::on_stop_offer_service(service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { - (void) _major; - (void) _minor; - std::map > events; - { - std::lock_guard its_lock(events_mutex_); - auto its_events_service = events_.find(_service); - if (its_events_service != events_.end()) { - auto its_events_instance = its_events_service->second.find(_instance); - if (its_events_instance != its_events_service->second.end()) { - for (auto &e : its_events_instance->second) - events[e.first] = e.second; - } - } - } - for (auto &e : events) { - e.second->unset_payload(); - } -} - -void routing_manager_proxy::send_pending_commands() { - for (auto &po : pending_offers_) - send_offer_service(client_, - po.service_, po.instance_, - po.major_, po.minor_); - - for (auto &per : pending_event_registrations_) - send_register_event(client_, - per.service_, per.instance_, - per.notifier_, - per.eventgroups_, per.type_, per.reliability_, - per.is_provided_); - - send_request_services(requests_); -} - -void routing_manager_proxy::init_receiver() { -#ifndef _WIN32 - auto its_security = security_impl::get(); - if (!its_security) - return; - - its_security->store_client_to_uid_gid_mapping(get_client(), own_uid_, own_gid_); - its_security->store_uid_gid_to_client_mapping(own_uid_, own_gid_, get_client()); -#endif - receiver_ = ep_mgr_->create_local_server(shared_from_this()); -} - -void routing_manager_proxy::notify_remote_initially(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, const std::set &_events_to_exclude) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - auto service_info = find_service(_service, _instance); - for (const auto &e : its_eventgroup->get_events()) { - if (e->is_field() && e->is_set() - && _events_to_exclude.find(e->get_event()) - == _events_to_exclude.end()) { - std::shared_ptr its_notification - = runtime::get()->create_notification(); - its_notification->set_service(_service); - its_notification->set_instance(_instance); - its_notification->set_method(e->get_event()); - its_notification->set_payload(e->get_payload()); - if (service_info) { - its_notification->set_interface_version(service_info->get_major()); - } - - std::shared_ptr its_serializer(get_serializer()); - if (its_serializer->serialize(its_notification.get())) { - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - send_local(sender_, VSOMEIP_ROUTING_CLIENT, its_serializer->get_data(), - its_serializer->get_size(), _instance, false, VSOMEIP_NOTIFY); - } - } - its_serializer->reset(); - put_serializer(its_serializer); - } else { - VSOMEIP_ERROR << "Failed to serialize message. Check message size!"; - } - } - } - } - -} - -uint32_t routing_manager_proxy::get_remote_subscriber_count(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, bool _increment) { - std::lock_guard its_lock(remote_subscriber_count_mutex_); - uint32_t count (0); - bool found(false); - auto found_service = remote_subscriber_count_.find(_service); - if (found_service != remote_subscriber_count_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - auto found_group = found_instance->second.find(_eventgroup); - if (found_group != found_instance->second.end()) { - found = true; - if (_increment) { - found_group->second = found_group->second + 1; - } else { - if (found_group->second > 0) { - found_group->second = found_group->second - 1; - } - } - count = found_group->second; - } - } - } - if (!found) { - if (_increment) { - remote_subscriber_count_[_service][_instance][_eventgroup] = 1; - count = 1; - } - } - return count; -} - -void routing_manager_proxy::clear_remote_subscriber_count( - service_t _service, instance_t _instance) { - std::lock_guard its_lock(remote_subscriber_count_mutex_); - auto found_service = remote_subscriber_count_.find(_service); - if (found_service != remote_subscriber_count_.end()) { - if (found_service->second.erase(_instance)) { - if (!found_service->second.size()) { - remote_subscriber_count_.erase(found_service); - } - } - } -} - -void -routing_manager_proxy::assign_client_timeout_cbk( - boost::system::error_code const &_error) { - if (!_error) { - bool register_again(false); - { - std::lock_guard its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " request client timeout! Trying again..."; - - if (sender_) { - sender_->restart(); - } - } - } -} - -void routing_manager_proxy::register_application_timeout_cbk( - boost::system::error_code const &_error) { - - bool register_again(false); - { - std::lock_guard its_lock(state_mutex_); - if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " register timeout! Trying again..."; - - if (sender_) - sender_->restart(); - } -} - -void routing_manager_proxy::send_registered_ack() { - byte_t its_command[VSOMEIP_COMMAND_HEADER_SIZE] = { - VSOMEIP_REGISTERED_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - client_t client = get_client(); - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client, - sizeof(client)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, VSOMEIP_COMMAND_HEADER_SIZE); - } - } -} - -bool routing_manager_proxy::is_client_known(client_t _client) { - std::lock_guard its_lock(known_clients_mutex_); - return (known_clients_.find(_client) != known_clients_.end()); -} - -bool routing_manager_proxy::create_placeholder_event_and_subscribe( - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _notifier, client_t _client) { - - std::lock_guard its_lock(stop_mutex_); - - bool is_inserted(false); - - if (find_service(_service, _instance)) { - // We received an event for an existing service which was not yet - // requested/offered. Create a placeholder field until someone - // requests/offers this event with full information like eventgroup, - // field/event, etc. - std::set its_eventgroups({ _eventgroup }); - // routing_manager_proxy: Always register with own client id and shadow = false - routing_manager_base::register_event(host_->get_client(), - _service, _instance, _notifier, - its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN, - std::chrono::milliseconds::zero(), false, true, nullptr, false, false, - true); - - std::shared_ptr its_event = find_event(_service, _instance, _notifier); - if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, false); - } - } - - return is_inserted; -} - -void routing_manager_proxy::request_debounce_timeout_cbk( - boost::system::error_code const &_error) { - std::lock_guard its_lock(state_mutex_); - if (!_error) { - if (requests_to_debounce_.size()) { - if (state_ == inner_state_type_e::ST_REGISTERED) { - send_request_services(requests_to_debounce_); - requests_.insert(requests_to_debounce_.begin(), - requests_to_debounce_.end()); - requests_to_debounce_.clear(); - } else { - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_running_ = true; - request_debounce_timer_.expires_from_now(std::chrono::milliseconds( - configuration_->get_request_debouncing(host_->get_name()))); - request_debounce_timer_.async_wait( - std::bind( - &routing_manager_proxy::request_debounce_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - return; - } - } - } - } - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_running_ = false; - } -} - -void routing_manager_proxy::register_client_error_handler(client_t _client, - const std::shared_ptr &_endpoint) { - _endpoint->register_error_handler( - std::bind(&routing_manager_proxy::handle_client_error, this, _client)); -} - -void routing_manager_proxy::handle_client_error(client_t _client) { - if (_client != VSOMEIP_ROUTING_CLIENT) { - VSOMEIP_INFO << "Client 0x" << std::hex << get_client() - << " handles a client error(" << std::hex << _client << ")"; - remove_local(_client, true); - } else { - bool should_reconnect(true); - { - std::unique_lock its_lock(state_mutex_); - should_reconnect = is_started_; - } - if (should_reconnect) { - std::unordered_set its_known_clients; - { - std::lock_guard its_lock(known_clients_mutex_); - its_known_clients = known_clients_; - } - reconnect(its_known_clients); - } - } -} - -void routing_manager_proxy::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { - (void)_client; - - byte_t its_command[VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFERED_SERVICES_REQUEST; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_offer_type, - sizeof(_offer_type)); - - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } -} - -void routing_manager_proxy::send_unsubscribe_ack( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_id, - sizeof(_id)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::resend_provided_event_registrations() { - std::lock_guard its_lock(state_mutex_); - for (const event_data_t& ed : pending_event_registrations_) { - if (ed.is_provided_) { - send_register_event(client_, ed.service_, ed.instance_, - ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_, - ed.is_provided_); - } - } -} - -void routing_manager_proxy::send_resend_provided_event_response(pending_remote_offer_id_t _id) { - byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id, - sizeof(pending_remote_offer_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_update_security_policy_response(pending_security_update_id_t _update_id) { - byte_t its_command[VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(pending_security_update_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_remove_security_policy_response(pending_security_update_id_t _update_id) { - byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(pending_security_update_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::on_update_security_credentials(const byte_t *_data, uint32_t _size) { - auto its_security = security_impl::get(); - if (!its_security) - return; - - uint32_t i = 0; - while ( (i + sizeof(uint32_t) + sizeof(uint32_t)) <= _size) { - std::shared_ptr its_policy(std::make_shared()); - - boost::icl::interval_set its_gid_set; - uint32_t its_uid, its_gid; - - std::memcpy(&its_uid, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - std::memcpy(&its_gid, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - its_gid_set.insert(its_gid); - - its_policy->credentials_ += std::make_pair( - boost::icl::interval::closed(its_uid, its_uid), its_gid_set); - its_policy->allow_who_ = true; - its_policy->allow_what_ = true; - - its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client()); - } -} - -void routing_manager_proxy::on_client_assign_ack(const client_t &_client) { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_ASSIGNING) { - if (_client != VSOMEIP_CLIENT_UNSET) { - state_ = inner_state_type_e::ST_ASSIGNED; - - boost::system::error_code ec; - register_application_timer_.cancel(ec); - host_->set_client(_client); - client_ = _client; - - if (is_started_) { - init_receiver(); - if (receiver_) { - receiver_->start(); - - VSOMEIP_INFO << std::hex << "Client " << client_ - << " (" << host_->get_name() - << ") successfully connected to routing ~> registering.."; - register_application(); - } else { - state_ = inner_state_type_e::ST_DEREGISTERED; - - host_->set_client(VSOMEIP_CLIENT_UNSET); - client_ = VSOMEIP_CLIENT_UNSET; - - sender_->restart(); - } - } - } else { - VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application."; - } - } else { - VSOMEIP_WARNING << "Client " << std::hex << client_ - << " received another client identifier (" - << std::hex << _client - << "). Ignoring it. (" - << (int)state_ << ")"; - } -} - -void routing_manager_proxy::on_suspend() { - - VSOMEIP_INFO << __func__ << ": Application " - << std::hex << std::setw(4) << std::setfill('0') - << host_->get_client(); - - std::lock_guard its_lock(remote_subscriber_count_mutex_); - - // Unsubscribe everything that is left over. - for (const auto &s : remote_subscriber_count_) { - for (const auto &i : s.second) { - for (const auto e : i.second) - routing_manager_base::unsubscribe( - VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, - s.first, i.first, e.first, ANY_EVENT); - } - } - - // Remove all entries. - remote_subscriber_count_.clear(); -} - -} // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 406b0d941..16ad36d74 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,28 +11,56 @@ #include #include +#include +#include #include #include -#include +#include #include #include "../include/routing_manager_stub.hpp" #include "../include/routing_manager_stub_host.hpp" #include "../include/remote_subscription.hpp" #include "../../configuration/include/configuration.hpp" -#include "../../security/include/security.hpp" - -#include "../../endpoints/include/local_server_endpoint_impl.hpp" #include "../../endpoints/include/endpoint_manager_impl.hpp" +#include "../../endpoints/include/netlink_connector.hpp" +#include "../../protocol/include/deregister_application_command.hpp" +#include "../../protocol/include/distribute_security_policies_command.hpp" +#include "../../protocol/include/dummy_command.hpp" +#include "../../protocol/include/expire_command.hpp" +#include "../../protocol/include/offer_service_command.hpp" +#include "../../protocol/include/offered_services_request_command.hpp" +#include "../../protocol/include/offered_services_response_command.hpp" +#include "../../protocol/include/ping_command.hpp" +#include "../../protocol/include/pong_command.hpp" +#include "../../protocol/include/register_application_command.hpp" +#include "../../protocol/include/register_events_command.hpp" +#include "../../protocol/include/registered_ack_command.hpp" +#include "../../protocol/include/release_service_command.hpp" +#include "../../protocol/include/remove_security_policy_command.hpp" +#include "../../protocol/include/remove_security_policy_response_command.hpp" +#include "../../protocol/include/request_service_command.hpp" +#include "../../protocol/include/resend_provided_events_command.hpp" +#include "../../protocol/include/routing_info_command.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../protocol/include/stop_offer_service_command.hpp" +#include "../../protocol/include/subscribe_ack_command.hpp" +#include "../../protocol/include/subscribe_command.hpp" +#include "../../protocol/include/subscribe_nack_command.hpp" +#include "../../protocol/include/suspend_command.hpp" +#include "../../protocol/include/unregister_event_command.hpp" +#include "../../protocol/include/unsubscribe_ack_command.hpp" +#include "../../protocol/include/unsubscribe_command.hpp" +#include "../../protocol/include/update_security_credentials_command.hpp" +#include "../../protocol/include/update_security_policy_command.hpp" +#include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../security/include/security.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" -#include "../implementation/message/include/payload_impl.hpp" namespace vsomeip_v3 { -const std::vector routing_manager_stub::its_ping_( - { VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - routing_manager_stub::routing_manager_stub( routing_manager_stub_host *_host, const std::shared_ptr& _configuration) : @@ -40,7 +68,7 @@ routing_manager_stub::routing_manager_stub( io_(_host->get_io()), watchdog_timer_(_host->get_io()), client_id_timer_(_host->get_io()), - endpoint_(nullptr), + root_(nullptr), local_receiver_(nullptr), configuration_(_configuration), is_socket_activated_(false), @@ -48,20 +76,31 @@ routing_manager_stub::routing_manager_stub( max_local_message_size_(configuration_->get_max_message_size_local()), configured_watchdog_timeout_(configuration_->get_watchdog_timeout()), pinged_clients_timer_(io_), - pending_security_update_id_(0) { + pending_security_update_id_(0) +#if defined(__linux__) || defined(ANDROID) + , is_local_link_available_(false) +#endif +{ } routing_manager_stub::~routing_manager_stub() { } void routing_manager_stub::init() { + init_routing_endpoint(); + + std::string its_env; + char its_hostname[1024]; + if (gethostname(its_hostname, sizeof(its_hostname)) == 0) + its_env = its_hostname; + host_->set_client_host(its_env); } void routing_manager_stub::start() { { std::lock_guard its_lock(used_client_ids_mutex_); - used_client_ids_ = utility::get_used_client_ids(); + used_client_ids_ = utility::get_used_client_ids(configuration_->get_network()); // Wait VSOMEIP_MAX_CONNECT_TIMEOUT * 2 and expect after that time // that all client_ids are used have to be connected to the routing. // Otherwise they can be marked as "erroneous client". @@ -73,12 +112,23 @@ void routing_manager_stub::start() { std::placeholders::_1)); } - if (!endpoint_) { - // application has been stopped and started again - init_routing_endpoint(); - } - if (endpoint_) { - endpoint_->start(); +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + if (!root_) { + // application has been stopped and started again + init_routing_endpoint(); + } + if (root_) { + root_->start(); + } +#if defined(__linux__) || defined(ANDROID) + } else { + if (local_link_connector_) + local_link_connector_->start(); +#endif } client_registration_running_ = true; @@ -122,47 +172,60 @@ void routing_manager_stub::stop() { client_id_timer_.cancel(); } - if( !is_socket_activated_) { - endpoint_->stop(); - endpoint_ = nullptr; - std::stringstream its_endpoint_path; - its_endpoint_path << utility::get_base_path(configuration_) << std::hex - << VSOMEIP_ROUTING_CLIENT; -#ifdef _WIN32 - ::_unlink(its_endpoint_path.str().c_str()); -#else - if (-1 == ::unlink(its_endpoint_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" - << its_endpoint_path.str() << "): "<< std::strerror(errno); + bool is_local_routing(configuration_->is_local_routing()); + +#if defined(__linux__) || defined(ANDROID) + if (local_link_connector_) + local_link_connector_->stop(); +#endif // __linux__ || ANDROID + + if (!is_socket_activated_) { + root_->stop(); + root_ = nullptr; + + if (is_local_routing) { + std::stringstream its_endpoint_path; + its_endpoint_path << utility::get_base_path(configuration_->get_network()) + << std::hex << VSOMEIP_ROUTING_CLIENT; + #ifdef _WIN32 + ::_unlink(its_endpoint_path.str().c_str()); + #else + if (-1 == ::unlink(its_endpoint_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" + << its_endpoint_path.str() << "): "<< std::strerror(errno); + } + #endif } -#endif } - if(local_receiver_) { + if (local_receiver_) { local_receiver_->stop(); local_receiver_ = nullptr; - std::stringstream its_local_receiver_path; - its_local_receiver_path << utility::get_base_path(configuration_) - << std::hex << host_->get_client(); + + if (is_local_routing) { + std::stringstream its_local_receiver_path; + its_local_receiver_path << utility::get_base_path(configuration_->get_network()) + << std::hex << host_->get_client(); #ifdef _WIN32 - ::_unlink(its_local_receiver_path.str().c_str()); + ::_unlink(its_local_receiver_path.str().c_str()); #else - if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" - << its_local_receiver_path.str() << "): "<< std::strerror(errno); - } + if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" + << its_local_receiver_path.str() << "): "<< std::strerror(errno); + } #endif + } } } void routing_manager_stub::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + (void)_receiver; - (void)_destination; + (void)_is_multicast; (void)_remote_address; (void) _remote_port; #if 0 @@ -173,97 +236,118 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, VSOMEIP_INFO << msg.str(); #endif - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); - - if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) { - byte_t its_command; - client_t its_client; - std::string its_client_endpoint; - service_t its_service; - instance_t its_instance; - method_t its_method; - eventgroup_t its_eventgroup; - event_t its_notifier; - event_type_e its_event_type; - bool is_provided(false); - major_version_t its_major; - minor_version_t its_minor; - std::shared_ptr its_payload; - const byte_t *its_data; - uint32_t its_size; - bool its_reliable(false); - client_t its_client_from_header; - client_t its_target_client; - client_t its_subscriber; - uint8_t its_check_status(0); - std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); - offer_type_e its_offer_type; - - its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], - sizeof(its_client)); - - if (security::get()->is_enabled() && _bound_client != its_client) { - VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " - << "Routing Manager received a message from client " - << std::hex << std::setw(4) << std::setfill('0') - << its_client << " with command " << (uint32_t)its_command - << " which doesn't match the bound client " - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } + client_t its_client; + protocol::id_e its_id; + std::string its_client_endpoint; + service_t its_service; + instance_t its_instance; + method_t its_method; + eventgroup_t its_eventgroup; + event_t its_notifier; + major_version_t its_major; + minor_version_t its_minor; + std::shared_ptr its_payload; + bool is_reliable(false); + client_t its_subscriber; + uint8_t its_check_status(0); + std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); + port_t its_port(ILLEGAL_PORT); + + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + // Use dummy command to deserialize id and client. + protocol::dummy_command its_base_command; + its_base_command.deserialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { - std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_size)); + VSOMEIP_ERROR << __func__ + << ": deserialization of command and client identifier failed (" + << std::dec << static_cast(its_error) + << ")"; + return; + } - if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) { - switch (its_command) { - case VSOMEIP_REGISTER_APPLICATION: - if (_size != VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::REGISTER); - break; + its_client = its_base_command.get_client(); + its_id = its_base_command.get_id(); - case VSOMEIP_DEREGISTER_APPLICATION: - if (_size != VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a DEREGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::DEREGISTER); - break; + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && _bound_client != its_client) { + VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " + << "Routing Manager received a message from client " + << std::hex << std::setw(4) << std::setfill('0') + << its_client << " with command " << (uint32_t)its_id + << " which doesn't match the bound client " + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } - case VSOMEIP_PONG: - if (_size != VSOMEIP_PONG_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a PONG command with wrong size ~> skip!"; - break; - } + switch (its_id) { + + case protocol::id_e::REGISTER_APPLICATION_ID: + { + protocol::register_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::REGISTER, + _remote_address, its_command.get_port()); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::DEREGISTER_APPLICATION_ID: + { + protocol::deregister_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::DEREGISTER, + _remote_address, its_port); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::PONG_ID: + { + protocol::pong_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { on_pong(its_client); VSOMEIP_TRACE << "PONG(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - - case VSOMEIP_OFFER_SERVICE: - if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!"; - break; - } + << std::hex << std::setw(4) << std::setfill('0') + << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing pong failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance)) { + case protocol::id_e::OFFER_SERVICE_ID: + { + protocol::offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_offer( + _sec_client, its_service, its_instance)) { host_->offer_service(its_client, its_service, its_instance, its_major, its_minor); } else { @@ -272,48 +356,54 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << "the following service/instance " << its_service << "/" << its_instance << " ~> Skip offer!"; } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing offer service failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - case VSOMEIP_STOP_OFFER_SERVICE: - if (_size != VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a STOP_OFFER_SERVICE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - host_->stop_offer_service(its_client, its_service, its_instance, its_major, its_minor); - break; - - case VSOMEIP_SUBSCRIBE: - if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_major)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(its_notifier)); + case protocol::id_e::STOP_OFFER_SERVICE_ID: + { + protocol::stop_offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + host_->stop_offer_service(its_client, + its_service, its_instance, + its_major, its_minor); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing stop offer service failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ID: + { + protocol::subscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_major = its_command.get_major(); + its_notifier = its_command.get_event(); + auto its_filter = its_command.get_filter(); if (its_notifier == ANY_EVENT) { - if (host_->is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, + if (host_->is_subscribe_to_any_event_allowed(_sec_client, its_client, its_service, its_instance, its_eventgroup)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -322,10 +412,10 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } else { - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, its_notifier)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_notifier)) { + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -334,456 +424,397 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::UNSUBSCRIBE_ID: + { + protocol::unsubscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_notifier = its_command.get_event(); + + host_->unsubscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_notifier); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ACK_ID: + { + protocol::subscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_UNSUBSCRIBE: - if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNSUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_notifier)); - - host_->unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, - its_instance, its_eventgroup, its_notifier); - break; - - case VSOMEIP_SUBSCRIBE_ACK: - if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe ack failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::SUBSCRIBE_NACK_ID: + { + protocol::subscribe_nack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_SUBSCRIBE_NACK: - if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_NACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_nack(its_subscriber, its_service, - its_instance, its_eventgroup, its_notifier, - its_subscription_id, false); + its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE NACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; - case VSOMEIP_UNSUBSCRIBE_ACK: - if (_size != VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_UNSUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscription_id)); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe nack failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::UNSUBSCRIBE_ACK_ID: + { + protocol::unsubscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscription_id = its_command.get_pending_id(); + host_->on_unsubscribe_ack(its_client, its_service, its_instance, its_eventgroup, its_subscription_id); + VSOMEIP_INFO << "UNSUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]"; - break; - case VSOMEIP_SEND: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - its_client_from_header = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_CLIENT_POS_MIN], - its_data[VSOMEIP_CLIENT_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_METHOD_POS_MIN], - its_data[VSOMEIP_METHOD_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - sizeof(its_reliable)); - std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - sizeof(its_check_status)); - - // Allow response messages from local proxies as answer to remote requests - // but check requests sent by local proxies to remote against policy. - if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client_from_header, its_service, its_instance, its_method)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client_from_header - << " : routing_manager_stub::on_message: " - << " isn't allowed to send a request to service/instance/method " - << its_service << "/" << its_instance << "/" << its_method - << " ~> Skip message!"; - return; - } - } - // reduce by size of instance, flush, reliable, client and is_valid_crc flag - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; - break; - } - host_->on_message(its_service, its_instance, its_data, its_message_size, - its_reliable, _bound_client, _credentials, its_check_status, false); - break; - } - case VSOMEIP_NOTIFY: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - // reduce by size of instance, flush, reliable, is_valid_crc flag and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance, its_data, its_message_size); - break; - } - case VSOMEIP_NOTIFY_ONE: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_target_client, &_data[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN], - sizeof(client_t)); - // reduce by size of instance, flush, reliable flag, is_valid_crc and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(its_target_client, its_service, its_instance, - its_data, its_message_size, true); - break; - } - case VSOMEIP_REQUEST_SERVICE: - { - uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) - + sizeof(major_version_t) + sizeof(minor_version_t)); - if (its_size % entry_size > 0) { - VSOMEIP_WARNING << "Received a REQUEST_SERVICE command with invalid size -> skip!"; - break; - } - uint32_t request_count(its_size / entry_size); - std::set requests; - for (uint32_t i = 0; i < request_count; ++i) { - service_t its_service; - instance_t its_instance; - major_version_t its_major; - minor_version_t its_minor; - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], - sizeof(its_minor)); - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, 0x00, true)) { - host_->request_service(its_client, its_service, its_instance, - its_major, its_minor ); - service_data_t request = { - its_service, its_instance, - its_major, its_minor - }; - requests.insert(request); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex - << its_client << " : routing_manager_stub::on_message: " - << "requests service/instance " - << its_service << "/" << its_instance - << " which violates the security policy ~> Skip request!"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe ack failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SEND_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_method = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_METHOD_POS_MIN], + its_message_data[VSOMEIP_METHOD_POS_MAX]); + its_client = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_CLIENT_POS_MIN], + its_message_data[VSOMEIP_CLIENT_POS_MAX]); + + its_instance = its_command.get_instance(); + is_reliable = its_command.is_reliable(); + its_check_status = its_command.get_status(); + + // Allow response messages from local proxies as answer to remote requests + // but check requests sent by local proxies to remote against policy. + if (utility::is_request(its_message_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_method)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_stub::on_message: " + << " isn't allowed to send a request to service/instance/method " + << its_service << "/" << its_instance << "/" << its_method + << " ~> Skip message!"; + return; } } - if (security::get()->is_enabled()) { - handle_credentials(its_client, requests); + // reduce by size of instance, flush, reliable, client and is_valid_crc flag + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; + break; } - handle_requests(its_client, requests); - break; + host_->on_message(its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + is_reliable, _bound_client, _sec_client, its_check_status, false); } + } + break; + } - case VSOMEIP_RELEASE_SERVICE: - if (_size != VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RELEASE_SERVICE command with wrong size ~> skip!"; + case protocol::id_e::NOTIFY_ID: + case protocol::id_e::NOTIFY_ONE_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_client = its_command.get_target(); + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_instance = its_command.get_instance(); + + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; break; } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - host_->release_service(its_client, its_service, its_instance); + host_->on_notification(its_client, its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + its_id == protocol::id_e::NOTIFY_ONE_ID); break; + } + } + break; + } - case VSOMEIP_REGISTER_EVENT: { - if (_size < VSOMEIP_REGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_EVENT command with wrong size ~> skip!"; - break; + case protocol::id_e::REQUEST_SERVICE_ID: + { + protocol::request_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + its_client = its_command.get_client(); + auto its_requests = its_command.get_services(); + + std::set its_allowed_requests; + for (const auto &r : its_requests) { + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_request( + _sec_client, r.service_, r.instance_)) { + host_->request_service(its_client, + r.service_, r.instance_, r.major_, r.minor_); + its_allowed_requests.insert(r); } + } + if (configuration_->is_security_enabled()) { + handle_credentials(its_client, its_allowed_requests); + } + handle_requests(its_client, its_allowed_requests); + } else + VSOMEIP_ERROR << __func__ << ": request service deserialization failed (" + << std::dec << static_cast(its_error) << ")"; - std::set its_eventgroups; - reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN; - - std::memcpy(&its_service, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&its_event_type, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event_type)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(is_provided)); - std::memcpy(&its_reliability, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_reliability)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; + break; + } + + case protocol::id_e::RELEASE_SERVICE_ID: + { + protocol::release_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->release_service(its_command.get_client(), + its_command.get_service(), its_command.get_instance()); + } else + VSOMEIP_ERROR << __func__ << ": release service deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::REGISTER_EVENT_ID: + { + protocol::register_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + for(std::size_t i = 0; i < its_command.get_num_registrations(); i++) { + protocol::register_event register_event; + if (!its_command.get_registration_at(i, register_event)) { + continue; } - for (std::size_t i = 9; i+1 < its_size; i++) { - std::memcpy(&its_eventgroup, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + i], - sizeof(its_eventgroup)); - its_eventgroups.insert(its_eventgroup); + + its_service = register_event.get_service(); + its_instance = register_event.get_instance(); + + if (register_event.is_provided() + && !configuration_->is_offered_remote(its_service, its_instance)) { + continue; } + host_->register_shadow_event(its_client, its_service, its_instance, - its_notifier, its_eventgroups, its_event_type, - its_reliability, - is_provided); + register_event.get_event(), register_event.get_eventgroups(), + register_event.get_event_type(), register_event.get_reliability(), + register_event.is_provided(), register_event.is_cyclic()); + VSOMEIP_INFO << "REGISTER EVENT(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << ":reliability=" - << (std::uint32_t)(its_reliability) << "]"; - break; + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":eventtype=" << std::dec << (int)register_event.get_event_type() + << ":is_provided=" << std::boolalpha << register_event.is_provided() + << ":reliable=" << std::dec << (int)register_event.get_reliability() << "]"; } - case VSOMEIP_UNREGISTER_EVENT: - if (_size != VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNREGISTER_EVENT command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(is_provided)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; - } - host_->unregister_shadow_event(its_client, its_service, its_instance, - its_notifier, is_provided); - VSOMEIP_INFO << "UNREGISTER EVENT(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << "]"; - break; - case VSOMEIP_REGISTERED_ACK: - if (_size != VSOMEIP_REGISTERED_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTERED_ACK command with wrong size ~> skip!"; - break; - } - VSOMEIP_INFO << "REGISTERED_ACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - case VSOMEIP_OFFERED_SERVICES_REQUEST: { - if (_size != VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_REQUEST command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_offer_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_offer_type)); + } else + VSOMEIP_ERROR << __func__ << ": register event deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - std::lock_guard its_guard(routing_info_mutex_); - create_offered_services_info(its_client); - - for (const auto& found_client : routing_info_) { - // skip services which are offered on remote hosts - if (found_client.first != VSOMEIP_ROUTING_CLIENT) { - for (const auto &its_service : found_client.second.second) { - for (const auto &its_instance : its_service.second) { - uint16_t its_reliable_port = configuration_->get_reliable_port(its_service.first, - its_instance.first); - uint16_t its_unreliable_port = configuration_->get_unreliable_port( - its_service.first, its_instance.first); - - if (its_offer_type == offer_type_e::OT_LOCAL) { - if (its_reliable_port == ILLEGAL_PORT - && its_unreliable_port == ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - else if (its_offer_type == offer_type_e::OT_REMOTE) { - if (its_reliable_port != ILLEGAL_PORT - || its_unreliable_port != ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } else if (its_offer_type == offer_type_e::OT_ALL) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - } - } - } - send_offered_services_info(its_client); - break; - } - case VSOMEIP_RESEND_PROVIDED_EVENTS: { - if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!"; - break; - } - pending_remote_offer_id_t its_pending_remote_offer_id(0); - std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_remote_offer_id_t)); - host_->on_resend_provided_events_response(its_pending_remote_offer_id); - VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - } - case VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::UNREGISTER_EVENT_ID: + { + protocol::unregister_event_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->unregister_shadow_event(its_command.get_client(), + its_command.get_service(), its_command.get_instance(), + its_command.get_event(), its_command.is_provided()); + + VSOMEIP_INFO << "UNREGISTER EVENT(" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_client() << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_instance() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_event() + << ":is_provider=" << std::boolalpha << its_command.is_provided() << "]"; + } else + VSOMEIP_ERROR << __func__ << ": unregister event deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - case VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::REGISTERED_ACK_ID: + { + protocol::registered_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + VSOMEIP_INFO << "REGISTERED_ACK(" + << std::hex << std::setw(4) << std::setfill('0') + << its_command.get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ << ": registered ack deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - } + case protocol::id_e::OFFERED_SERVICES_REQUEST_ID: + { + protocol::offered_services_request_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + on_offered_service_request(its_command.get_client(), its_command.get_offer_type()); + } else + VSOMEIP_ERROR << __func__ << ": offer service request deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::RESEND_PROVIDED_EVENTS_ID: + { + protocol::resend_provided_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + host_->on_resend_provided_events_response(its_command.get_remote_offer_id()); + VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ << ": resend provided events deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } +#ifndef VSOMEIP_DISABLE_SECURITY + case protocol::id_e::UPDATE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::update_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::REMOVE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::remove_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; } +#endif // !VSOMEIP_DISABLE_SECURITY + default: + VSOMEIP_WARNING << __func__ << ": Received an unhandled command (" + << std::dec << static_cast(its_id) << ")"; } } +void routing_manager_stub::add_known_client(client_t _client, const std::string &_client_host) { + host_->add_known_client(_client, _client_host); +} + void routing_manager_stub::on_register_application(client_t _client) { + auto endpoint = host_->find_local(_client); if (endpoint) { VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client @@ -794,15 +825,21 @@ void routing_manager_stub::on_register_application(client_t _client) { std::lock_guard its_lock(routing_info_mutex_); routing_info_[_client].first = 0; } +#ifndef VSOMEIP_DISABLE_SECURITY + if (configuration_->is_local_routing()) { + vsomeip_sec_client_t its_sec_client; + std::set > its_policies; + + policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS) { + get_requester_policies(its_sec_client.client.uds_client.user, + its_sec_client.client.uds_client.group, its_policies); + } - std::pair its_uid_gid; - std::set > its_policies; - - security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid); - get_requester_policies(its_uid_gid.first, its_uid_gid.second, its_policies); - - if (!its_policies.empty()) - send_requester_policies({ _client }, its_policies); + if (!its_policies.empty()) + send_requester_policies({ _client }, its_policies); + } +#endif // !VSOMEIP_DISABLE_SECURITY } } @@ -827,15 +864,59 @@ void routing_manager_stub::on_deregister_application(client_t _client) { routing_info_.erase(_client); } for (const auto &s : services_to_report) { - host_->on_availability(std::get<0>(s), std::get<1>(s), false, + host_->on_availability(std::get<0>(s), std::get<1>(s), + availability_state_e::AS_UNAVAILABLE, std::get<2>(s), std::get<3>(s)); host_->on_stop_offer_service(_client, std::get<0>(s), std::get<1>(s), std::get<2>(s), std::get<3>(s)); } } +void +routing_manager_stub::on_offered_service_request(client_t _client, + offer_type_e _offer_type) { + + protocol::offered_services_response_command its_command; + its_command.set_client(_client); + + for (const auto& found_client : routing_info_) { + // skip services which are offered on remote hosts + if (found_client.first != VSOMEIP_ROUTING_CLIENT) { + for (const auto &s : found_client.second.second) { + for (const auto &i : s.second) { + uint16_t its_reliable_port + = configuration_->get_reliable_port(s.first, i.first); + uint16_t its_unreliable_port + = configuration_->get_unreliable_port(s.first, i.first); + bool has_port = (its_reliable_port != ILLEGAL_PORT + || its_unreliable_port != ILLEGAL_PORT); + + if (_offer_type == offer_type_e::OT_ALL + || (_offer_type == offer_type_e::OT_LOCAL && !has_port) + || (_offer_type == offer_type_e::OT_REMOTE && has_port)) { + + protocol::service its_service(s.first, i.first, + i.second.first, i.second.second); + its_command.add_service(its_service); + } + } + } + } + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } +} + void routing_manager_stub::client_registration_func(void) { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -845,9 +926,9 @@ void routing_manager_stub::client_registration_func(void) { #endif std::unique_lock its_lock(client_registration_mutex_); while (client_registration_running_) { - while (!pending_client_registrations_.size() && client_registration_running_) { - client_registration_condition_.wait(its_lock); - } + client_registration_condition_.wait(its_lock, [this] { + return pending_client_registrations_.size() || !client_registration_running_; + }); std::map> its_registrations( pending_client_registrations_); @@ -867,44 +948,53 @@ void routing_manager_stub::client_registration_func(void) { // endpoint error to avoid writing in an already closed socket if (b != registration_type_e::DEREGISTER_ON_ERROR) { std::lock_guard its_guard(routing_info_mutex_); - create_client_routing_info(r.first); - insert_client_routing_info(r.first, - b == registration_type_e::REGISTER ? - routing_info_entry_e::RIE_ADD_CLIENT : - routing_info_entry_e::RIE_DEL_CLIENT, - r.first); - // distribute updated security config to new clients + add_connection(r.first, r.first); + protocol::routing_info_entry its_entry; + its_entry.set_client(r.first); if (b == registration_type_e::REGISTER) { + boost::asio::ip::address its_address; + port_t its_port; + + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + if (host_->get_guest(r.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } +#ifndef VSOMEIP_DISABLE_SECURITY + // distribute updated security config to new clients send_cached_security_policies(r.first); +#endif // !VSOMEIP_DISABLE_SECURITY + } else { + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); } - send_client_routing_info(r.first); + send_client_routing_info(r.first, its_entry); } if (b != registration_type_e::REGISTER) { { std::lock_guard its_guard(routing_info_mutex_); - auto its_connection = connection_matrix_.find(r.first); - if (its_connection != connection_matrix_.end()) { - for (auto its_client : its_connection->second) { + auto find_connections = connection_matrix_.find(r.first); + if (find_connections != connection_matrix_.end()) { + for (auto its_client : find_connections->second) { if (its_client != r.first && its_client != VSOMEIP_ROUTING_CLIENT && its_client != get_client()) { - create_client_routing_info(its_client); - insert_client_routing_info(its_client, - routing_info_entry_e::RIE_DEL_CLIENT, r.first); - send_client_routing_info(its_client); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); + its_entry.set_client(r.first); + send_client_routing_info(its_client, its_entry); } } - connection_matrix_.erase(r.first); + remove_source(r.first); } - for (const auto& its_client : connection_matrix_) { - connection_matrix_[its_client.first].erase(r.first); + for (const auto &its_connections : connection_matrix_) { + remove_connection(its_connections.first, r.first); } service_requests_.erase(r.first); } // Don't remove client ID to UID maping as same client // could have passed its credentials again host_->remove_local(r.first, false); - utility::release_client_id(r.first); + utility::release_client_id(configuration_->get_network(), r.first); } } } @@ -913,9 +1003,75 @@ void routing_manager_stub::client_registration_func(void) { } void routing_manager_stub::init_routing_endpoint() { - endpoint_ = host_->get_endpoint_manager()->create_local_server( - &is_socket_activated_, shared_from_this()); + +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + bool is_successful = host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + + if (!is_successful) { + VSOMEIP_WARNING << "Routing root creating (partially) failed. Please check your configuration."; + } +#if defined(__linux__) || defined(ANDROID) + } else { + auto its_host_address = configuration_->get_routing_host_address(); + local_link_connector_ = std::make_shared( + io_, its_host_address, boost::asio::ip::address(), false); // routing host doesn't need link up + if (local_link_connector_) { + local_link_connector_->register_net_if_changes_handler( + std::bind(&routing_manager_stub::on_net_state_change, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } +#endif // __linux__ || ANDROID + } +} + +#if defined(__linux__) || defined(ANDROID) +void +routing_manager_stub::on_net_state_change( + bool _is_interface, const std::string &_name, bool _is_available) { + + VSOMEIP_INFO << __func__ + << "("<< std::hex << std::this_thread::get_id() << "): " + << std::boolalpha << _is_interface << " " + << _name << " " + << std::boolalpha << _is_available; + + if (_is_interface) { + if (_is_available) { + if (!is_local_link_available_) { + is_local_link_available_ = true; + if (!root_) + (void)host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + if (root_) { + VSOMEIP_INFO << __func__ + << ": Starting routing root."; + root_->start(); + } else + VSOMEIP_WARNING << "Routing root creating (partially) failed. " + "Please check your configuration."; + } + } else { + if (is_local_link_available_) { + + VSOMEIP_INFO << __func__ + << ": Stopping routing root."; + root_->stop(); + + routing_info_.clear(); + host_->clear_local_services(); + + is_local_link_available_ = false; + } + } + } } +#endif // __linux__ || ANDROID void routing_manager_stub::on_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { @@ -925,11 +1081,11 @@ void routing_manager_stub::on_offer_service(client_t _client, std::lock_guard its_guard(routing_info_mutex_); routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor); - if (security::get()->is_enabled()) { + if (configuration_->is_security_enabled()) { distribute_credentials(_client, _service, _instance); } inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true); + protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE, true); } void routing_manager_stub::on_stop_offer_service(client_t _client, @@ -947,102 +1103,29 @@ void routing_manager_stub::on_stop_offer_service(client_t _client, if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } else if( _major == DEFAULT_MAJOR && _minor == DEFAULT_MINOR) { found_service->second.erase(_instance); if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } } } } } -void routing_manager_stub::create_client_routing_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_ROUTING_INFO); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_routing_info_[_target] = its_command; -} - -void routing_manager_stub::create_client_credentials_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_UPDATE_SECURITY_CREDENTIALS); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::insert_client_credentials_info(client_t _target, std::set> _credentials) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } - - auto its_command = client_credentials_info_[_target]; - - // insert uid / gid credential pairs - for (auto its_credentials : _credentials) { - //uid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast(&std::get<0>(its_credentials))[i]); - } - //gid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast(&std::get<1>(its_credentials))[i]); - } - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::send_client_credentials_info(const client_t _target) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } +void routing_manager_stub::send_client_credentials(const client_t _target, + std::set> &_credentials) { std::shared_ptr its_endpoint = host_->find_local(_target); if (its_endpoint) { - auto its_command = client_credentials_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; + protocol::update_security_credentials_command its_command; + its_command.set_client(_target); + its_command.set_credentials(_credentials); #if 0 std::stringstream msg; @@ -1052,235 +1135,66 @@ void routing_manager_stub::send_client_credentials_info(const client_t _target) VSOMEIP_INFO << msg.str(); #endif - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Credentials info exceeds maximum message size: Can't send!"; - } - - client_credentials_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send credentials info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - -void routing_manager_stub::create_offered_services_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_OFFERED_SERVICES_RESPONSE); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - offered_services_info_[_target] = its_command; -} - - -void routing_manager_stub::send_client_routing_info(const client_t _target) { - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - std::shared_ptr its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = client_routing_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_routing_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!"; - } - - client_routing_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send routing info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - - -void routing_manager_stub::send_offered_services_info(const client_t _target) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } - std::shared_ptr its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = offered_services_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_offered_services_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!"; - } - - offered_services_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send offered services info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if(its_buffer.size() <= max_local_message_size_ + || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": Credentials info exceeds maximum message size: Can't send!"; + + } else + VSOMEIP_ERROR << __func__ + << ": update security credentials command serialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending credentials to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } -void routing_manager_stub::insert_client_routing_info(client_t _target, - routing_info_entry_e _entry, - client_t _client, service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { - - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - - connection_matrix_[_target].insert(_client); - - auto its_command = client_routing_info_[_target]; - - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast(&_entry)[i]); - } - - std::size_t its_size_pos = its_command.size(); - std::size_t its_entry_size = its_command.size(); - - // Client size placeholder - byte_t placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(placeholder); - } - // Client - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&_client)[i]); - } - - if (_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE || - _entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) { - //Service - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast(&its_service_entry_size)[i]); - } - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_minor)[i]); - } - } - - // File client size - its_entry_size = its_command.size() - its_entry_size - uint32_t(sizeof(uint32_t)); - std::memcpy(&its_command[its_size_pos], &its_entry_size, sizeof(uint32_t)); +void routing_manager_stub::send_client_routing_info(const client_t _target, + protocol::routing_info_entry &_entry) { - client_routing_info_[_target] = its_command; + std::vector its_entries; + its_entries.emplace_back(_entry); + send_client_routing_info(_target, std::move(its_entries)); } -void routing_manager_stub::insert_offered_services_info(client_t _target, - routing_info_entry_e _entry, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { +void routing_manager_stub::send_client_routing_info(const client_t _target, + std::vector &&_entries) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } + auto its_target_endpoint = host_->find_local(_target); + if (its_target_endpoint) { - auto its_command = offered_services_info_[_target]; + protocol::routing_info_command its_command; + its_command.set_client(get_client()); + its_command.set_entries(std::move(_entries)); - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast(&_entry)[i]); - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // entry size - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast(&its_service_entry_size)[i]); - } - //Service - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_minor)[i]); - } - - offered_services_info_[_target] = its_command; + if (its_error == protocol::error_e::ERROR_OK) { + its_target_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": routing info command serialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending routing info to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _service, instance_t _instance) { @@ -1298,38 +1212,30 @@ void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _s } // search for UID / GID linked with the client ID that offers the requested services - std::pair its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) { + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_hoster, its_sec_client)) { + std::pair its_uid_gid; + its_uid_gid.first = its_sec_client.client.uds_client.user; + its_uid_gid.second = its_sec_client.client.uds_client.group; its_credentials.insert(its_uid_gid); for (auto its_requesting_client : its_requesting_clients) { - std::pair its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - create_client_credentials_info(its_requesting_client); - insert_client_credentials_info(its_requesting_client, its_credentials); - send_client_credentials_info(its_requesting_client); - } + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping( + its_requesting_client, its_requester_sec_client)) { + if (!utility::compare(its_sec_client, its_requester_sec_client)) + send_client_credentials(its_requesting_client, its_credentials); } } } } -void routing_manager_stub::inform_provider(client_t _hoster, service_t _service, +void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry) { + protocol::routing_info_entry_type_e _type, bool _inform_service) { - if (_hoster != VSOMEIP_ROUTING_CLIENT - && _hoster != host_->get_client()) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(_hoster); - } -}; + boost::asio::ip::address its_address; + port_t its_port; -void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry, bool _inform_service) { for (auto its_client : service_requests_) { auto its_service = its_client.second.find(_service); if (its_service != its_client.second.end()) { @@ -1338,31 +1244,39 @@ void routing_manager_stub::inform_requesters(client_t _hoster, service_t _servic if (_inform_service) { if (_hoster != VSOMEIP_ROUTING_CLIENT && _hoster != host_->get_client()) { - if (!is_already_connected(_hoster, its_client.first)) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, - routing_info_entry_e::RIE_ADD_CLIENT, - its_client.first); - send_client_routing_info(_hoster); + if (!is_connected(_hoster, its_client.first)) { + add_connection(_hoster, its_client.first); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(its_client.first); + if (host_->get_guest(its_client.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + send_client_routing_info(_hoster, its_entry); } } } if (its_client.first != VSOMEIP_ROUTING_CLIENT && its_client.first != get_client()) { - create_client_routing_info(its_client.first); - insert_client_routing_info(its_client.first, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(its_client.first); + add_connection(its_client.first, _hoster); + protocol::routing_info_entry its_entry; + its_entry.set_type(_type); + its_entry.set_client(_hoster); + if ((_type == protocol::routing_info_entry_type_e::RIE_ADD_CLIENT + || _type == protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE) + && host_->get_guest(_hoster, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ _service, _instance, _major, _minor} ); + send_client_routing_info(its_client.first, its_entry); } } } } } -bool routing_manager_stub::is_already_connected(client_t _source, client_t _sink) { - return connection_matrix_[_source].find(_sink) != connection_matrix_[_source].end(); -} - void routing_manager_stub::broadcast(const std::vector &_command) const { std::lock_guard its_guard(routing_info_mutex_); for (const auto& a : routing_info_) { @@ -1376,42 +1290,50 @@ void routing_manager_stub::broadcast(const std::vector &_command) const } } -bool routing_manager_stub::send_subscribe(const std::shared_ptr& _target, - client_t _client, service_t _service, instance_t _instance, +bool routing_manager_stub::send_subscribe( + const std::shared_ptr& _target, client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event, remote_subscription_id_t _id) { + event_t _event, const std::shared_ptr &_filter, + remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::subscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(_major); + its_command.set_event(_event); + its_command.set_filter(_filter); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe command serialization failed (" + << std::dec << int(its_error) << ")"; + } else { - VSOMEIP_WARNING << __func__ << " Couldn't send subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_unsubscribe( @@ -1419,37 +1341,41 @@ bool routing_manager_stub::send_unsubscribe( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::unsubscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send unsubscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send unsubscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_expired_subscription( @@ -1457,100 +1383,94 @@ bool routing_manager_stub::send_expired_subscription( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_EXPIRED_SUBSCRIPTION; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::expire_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send expired subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send expired subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } void routing_manager_stub::send_subscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } void routing_manager_stub::send_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_nack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } @@ -1576,7 +1496,19 @@ bool routing_manager_stub::contained_in_routing_info( // Watchdog void routing_manager_stub::broadcast_ping() const { - broadcast(its_ping_); + + protocol::ping_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } void routing_manager_stub::on_pong(client_t _client) { @@ -1656,8 +1588,8 @@ void routing_manager_stub::create_local_receiver() { if (local_receiver_) { return; } -#ifndef _WIN32 - else if (!security::get()->check_credentials(get_client(), getuid(), getgid())) { +#if defined(__linux__) || defined(ANDROID) + else if (!policy_manager_impl::get()->check_credentials(get_client(), host_->get_sec_client())) { VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_stub::create_local_receiver: isn't allowed" << " to create a server endpoint due to credential check failed!"; @@ -1666,56 +1598,71 @@ void routing_manager_stub::create_local_receiver() { #endif local_receiver_ = std::static_pointer_cast( host_->get_endpoint_manager())->create_local_server(shared_from_this()); - local_receiver_->start(); + + if (local_receiver_) + local_receiver_->start(); } bool routing_manager_stub::send_ping(client_t _client) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (!its_endpoint) { - return false; - } - { + bool has_sent(false); + + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) { std::lock_guard its_lock(pinged_clients_mutex_); if (pinged_clients_.find(_client) != pinged_clients_.end()) { // client was already pinged: don't ping again and wait for answer // or timeout of previous ping. - return true; - } - - boost::system::error_code ec; - pinged_clients_timer_.cancel(ec); - if (ec) { - VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " - "timer failed: " << ec.message(); - } - const std::chrono::steady_clock::time_point now( - std::chrono::steady_clock::now()); + has_sent = true; + } else { + boost::system::error_code ec; + pinged_clients_timer_.cancel(ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " + "timer failed: " << ec.message(); + } + const std::chrono::steady_clock::time_point now( + std::chrono::steady_clock::now()); - std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); - for (const auto &tp : pinged_clients_) { - const std::chrono::milliseconds its_clients_timeout = - std::chrono::duration_cast( - now - tp.second); - if (next_timeout > its_clients_timeout) { - next_timeout = its_clients_timeout; + std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); + for (const auto &tp : pinged_clients_) { + const std::chrono::milliseconds its_clients_timeout = + std::chrono::duration_cast( + now - tp.second); + if (next_timeout > its_clients_timeout) { + next_timeout = its_clients_timeout; + } } - } - pinged_clients_[_client] = now; + pinged_clients_[_client] = now; - ec.clear(); - pinged_clients_timer_.expires_from_now(next_timeout, ec); - if (ec) { - VSOMEIP_ERROR<< "routing_manager_stub::send_ping setting " - "expiry time of timer failed: " << ec.message(); + ec.clear(); + pinged_clients_timer_.expires_from_now(next_timeout, ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping setting " + "expiry time of timer failed: " << ec.message(); + } + pinged_clients_timer_.async_wait( + std::bind(&routing_manager_stub::on_ping_timer_expired, this, + std::placeholders::_1)); + + protocol::ping_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + has_sent = its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } - pinged_clients_timer_.async_wait( - std::bind(&routing_manager_stub::on_ping_timer_expired, this, - std::placeholders::_1)); - return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size())); } + + return (has_sent); } void routing_manager_stub::on_ping_timer_expired( @@ -1821,19 +1768,33 @@ bool routing_manager_stub::is_registered(client_t _client) const { } void routing_manager_stub::update_registration(client_t _client, - registration_type_e _type) { + registration_type_e _type, + const boost::asio::ip::address &_address, port_t _port) { + + std::stringstream its_client; + its_client << std::hex << std::setw(4) << std::setfill('0') + << _client; + + if (_port > 0 && _port < ILLEGAL_PORT) { + its_client << " @ " << _address.to_string() << ":" << std::dec << _port; + } VSOMEIP_INFO << "Application/Client " - << std::hex << std::setw(4) << std::setfill('0') << _client + << its_client.str() << " is " << (_type == registration_type_e::REGISTER ? "registering." : "deregistering."); if (_type != registration_type_e::REGISTER) { - security::get()->remove_client_to_uid_gid_mapping(_client); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); + } else { + if (_port > 0 && _port < ILLEGAL_PORT) + host_->add_guest(_client, _address, _port); } if (_type == registration_type_e::DEREGISTER) { + host_->remove_guest(_client); + // If we receive a DEREGISTER client command // the endpoint error handler is not longer needed // as the client is going down anyways. @@ -1868,15 +1829,15 @@ client_t routing_manager_stub::get_client() const { return host_->get_client(); } -void routing_manager_stub::handle_credentials(const client_t _client, std::set& _requests) { +void routing_manager_stub::handle_credentials(const client_t _client, std::set &_requests) { if (!_requests.size()) { return; } std::lock_guard its_guard(routing_info_mutex_); std::set> its_credentials; - std::pair its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) { + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_requester_sec_client)) { // determine credentials of offering clients using current routing info std::set its_offering_clients; @@ -1891,65 +1852,79 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid))); + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(its_offering_client, its_sec_client)) { + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS + && !utility::compare(its_sec_client, its_requester_sec_client)) { + + its_credentials.insert(std::make_pair( + its_sec_client.client.uds_client.user, its_sec_client.client.uds_client.group)); } } } // send credentials to clients - if (!its_credentials.empty()) { - create_client_credentials_info(_client); - insert_client_credentials_info(_client, its_credentials); - send_client_credentials_info(_client); - } + if (!its_credentials.empty()) + send_client_credentials(_client, its_credentials); } } -void routing_manager_stub::handle_requests(const client_t _client, std::set& _requests) { - if (!_requests.size()) { +void routing_manager_stub::handle_requests(const client_t _client, std::set &_requests) { + + if (_requests.empty()) return; - } - bool service_available(false); + + boost::asio::ip::address its_address; + port_t its_port; + + std::vector its_entries; std::lock_guard its_guard(routing_info_mutex_); - create_client_routing_info(_client); + for (auto request : _requests) { service_requests_[_client][request.service_][request.instance_] - = std::make_pair(request.major_, request.minor_); + = std::make_pair(request.major_, request.minor_); if (request.instance_ == ANY_INSTANCE) { std::set its_clients = host_->find_local_clients(request.service_, request.instance_); - // insert VSOMEIP_ROUTING_CLIENT to check wether service is remotely offered + // insert VSOMEIP_ROUTING_CLIENT to check whether service is remotely offered its_clients.insert(VSOMEIP_ROUTING_CLIENT); for (const client_t c : its_clients) { if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { const auto found_client = routing_info_.find(c); if (found_client != routing_info_.end()) { const auto found_service = found_client->second.second.find(request.service_); if (found_service != found_client->second.second.end()) { for (auto instance : found_service->second) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, instance.first, - instance.second.first, instance.second.second); + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, instance.first, + instance.second.first, instance.second.second }); + its_entries.emplace_back(its_entry); } } } @@ -1963,38 +1938,46 @@ void routing_manager_stub::handle_requests(const client_t _client, std::setsecond.second.end()) { const auto found_instance = found_service->second.find(request.instance_); if (found_instance != found_service->second.end()) { - if (c != VSOMEIP_ROUTING_CLIENT && - c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, request.instance_, - found_instance->second.first, - found_instance->second.second); + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, request.instance_, + found_instance->second.first, found_instance->second.second }); + its_entries.emplace_back(its_entry); } } } } } } - if (service_available) { - send_client_routing_info(_client); - } + + if (!its_entries.empty()) + send_client_routing_info(_client, std::move(its_entries)); } void routing_manager_stub::on_client_id_timer_expired(boost::system::error_code const &_error) { @@ -2029,34 +2012,37 @@ void routing_manager_stub::print_endpoint_status() const { if (local_receiver_) { local_receiver_->print_status(); } - if (endpoint_) { - endpoint_->print_status(); + if (root_) { + root_->print_status(); } } -bool routing_manager_stub::send_provided_event_resend_request(client_t _client, - pending_remote_offer_id_t _id) { +bool routing_manager_stub::send_provided_event_resend_request( + client_t _client, pending_remote_offer_id_t _id) { + std::shared_ptr its_endpoint = host_->find_local(_client); if (its_endpoint) { - byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS; - const client_t routing_client(VSOMEIP_ROUTING_CLIENT); - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &routing_client, - sizeof(routing_client)); - std::uint32_t its_size = sizeof(pending_remote_offer_id_t); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id, - sizeof(pending_remote_offer_id_t)); - return its_endpoint->send(its_command, sizeof(its_command)); + + protocol::resend_provided_events_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_remote_offer_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); } else { VSOMEIP_WARNING << __func__ << " Couldn't send provided event resend " "request to local client: 0x" << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; } + + return (false); } +#ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_stub::is_policy_cached(uint32_t _uid) { { std::lock_guard its_lock(updated_security_policies_mutex_); @@ -2089,11 +2075,16 @@ void routing_manager_stub::policy_cache_remove(uint32_t _uid) { bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id, uint32_t _uid, const std::shared_ptr& _payload) { (void)_uid; + std::shared_ptr its_endpoint = host_->find_local(_client); if (its_endpoint) { std::vector its_command; // command - its_command.push_back(VSOMEIP_UPDATE_SECURITY_POLICY); + its_command.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_ID)); + + // version + its_command.push_back(0x00); + its_command.push_back(0x00); // client ID for (uint32_t i = 0; i < sizeof(client_t); ++i) { @@ -2123,89 +2114,74 @@ bool routing_manager_stub::send_update_security_policy_request(client_t _client, } bool routing_manager_stub::send_cached_security_policies(client_t _client) { - std::vector its_command; - std::size_t its_size(0); - std::lock_guard its_lock(updated_security_policies_mutex_); - uint32_t its_policy_count = uint32_t(updated_security_policies_.size()); + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) { - if (!its_policy_count) { - return true; - } - VSOMEIP_INFO << __func__ << " Distributing [" - << std::dec << its_policy_count - << "] security policy updates to registering client: " - << std::hex << _client; + std::lock_guard its_lock(updated_security_policies_mutex_); + if (!updated_security_policies_.empty()) { - // command - its_command.push_back(VSOMEIP_DISTRIBUTE_SECURITY_POLICIES); + VSOMEIP_INFO << __func__ << " Distributing [" + << std::dec << updated_security_policies_.size() + << "] security policy updates to registering client: " + << std::hex << _client; - // client ID - client_t its_client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&its_client)[i]); - } + protocol::distribute_security_policies_command its_command; + its_command.set_client(get_client()); + its_command.set_payloads(updated_security_policies_); - //overall size (placeholder - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(0x00); - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // number of policies contained in message - for (uint32_t i = 0; i < sizeof(its_policy_count); ++i) { - its_command.push_back( - reinterpret_cast(&its_policy_count)[i]); - } + if (its_error == protocol::error_e::ERROR_OK) + return its_endpoint->send(its_buffer.data(), uint32_t(its_buffer.size())); - for (const auto& its_uid_gid : updated_security_policies_) { - // policy payload length including gid and uid - std::uint32_t its_length = uint32_t(its_uid_gid.second->get_length()); - for (uint32_t i = 0; i < sizeof(its_length); ++i) { - its_command.push_back( - reinterpret_cast(&its_length)[i]); + VSOMEIP_ERROR << __func__ + << ": serializing distribute security policies (" + << static_cast(its_error) + << ")"; } - // payload - its_command.insert(its_command.end(), its_uid_gid.second->get_data(), - its_uid_gid.second->get_data() + its_uid_gid.second->get_length()); - } - // File overall size - its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); + } else + VSOMEIP_WARNING << __func__ + << ": could not send cached security policies to registering client: 0x" + << std::hex << std::setw(4) << std::setfill('0') << _client; + + return (false); +} + +bool routing_manager_stub::send_remove_security_policy_request( + client_t _client, pending_security_update_id_t _update_id, + uint32_t _uid, uint32_t _gid) { + + protocol::remove_security_policy_command its_command; + its_command.set_client(_client); + its_command.set_update_id(_update_id); + its_command.set_uid(_uid); + its_command.set_gid(_gid); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); + else + VSOMEIP_ERROR << __func__ + << ": cannot find local client endpoint for client " + << std::hex << std::setw(4) << std::setfill('0') + << _client; + } else + VSOMEIP_ERROR << __func__ + << ": remove security policy command serialization failed (" + << std::dec << static_cast(its_error) + << ")"; - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - return its_endpoint->send(its_command.data(), uint32_t(its_command.size())); - } else { - VSOMEIP_WARNING << __func__ << " Couldn't send cached security policies " - " to registering client: 0x" - << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; - } -} + return (false); -bool routing_manager_stub::send_remove_security_policy_request( client_t _client, pending_security_update_id_t _update_id, - uint32_t _uid, uint32_t _gid) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(client_t)); - std::uint32_t its_size = sizeof(_update_id) + sizeof(_uid) + sizeof(_gid); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_uid, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_gid, - sizeof(uint32_t)); - return its_endpoint->send(its_command, sizeof(its_command)); - } else { - return false; - } } bool @@ -2219,7 +2195,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, if (found_gid != found_uid->second.end()) { found_gid->second.insert(_policies.begin(), _policies.end()); } else { - found_uid->second.insert(std::make_pair(_gid, _policies)); + found_uid->second[_gid] = _policies; } } else { requester_policies_[_uid][_gid] = _policies; @@ -2228,7 +2204,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, // Check whether clients with uid/gid are already registered. // If yes, update their policy std::unordered_set its_clients; - security::get()->get_clients(_uid, _gid, its_clients); + policy_manager_impl::get()->get_clients(_uid, _gid, its_clients); if (!its_clients.empty()) return send_requester_policies(its_clients, _policies); @@ -2263,7 +2239,7 @@ routing_manager_stub::get_requester_policies(uid_t _uid, gid_t _gid, void routing_manager_stub::add_pending_security_update_handler( - pending_security_update_id_t _id, security_update_handler_t _handler) { + pending_security_update_id_t _id, const security_update_handler_t &_handler) { std::lock_guard its_lock(security_update_handlers_mutex_); security_update_handlers_[_id] = _handler; @@ -2304,7 +2280,13 @@ routing_manager_stub::send_requester_policies(const std::unordered_set std::vector its_policy_data; if (p->serialize(its_policy_data)) { std::vector its_message; - its_message.push_back(VSOMEIP_UPDATE_SECURITY_POLICY_INT); + its_message.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_INT_ID)); + + // version + its_message.push_back(0); + its_message.push_back(0); + + // client identifier its_message.push_back(0); its_message.push_back(0); @@ -2322,7 +2304,7 @@ routing_manager_stub::send_requester_policies(const std::unordered_set its_message.insert(its_message.end(), its_policy_data.begin(), its_policy_data.end()); - for (const auto& c : _clients) { + for (const auto c : _clients) { std::shared_ptr its_endpoint = host_->find_local(c); if (its_endpoint) its_endpoint->send(&its_message[0], static_cast(its_message.size())); @@ -2401,11 +2383,11 @@ bool routing_manager_stub::update_security_policy_configuration( policy_cache_add(_uid, _payload); // update security policy from configuration - security::get()->update_security_policy(_uid, _gid, _policy); + policy_manager_impl::get()->update_security_policy(_uid, _gid, _policy); // Build requester policies for the services offered by the new policy std::set > its_requesters; - security::get()->get_requester_policies(_policy, its_requesters); + policy_manager_impl::get()->get_requester_policies(_policy, its_requesters); // and add them to the requester policy cache add_requester_policies(_uid, _gid, its_requesters); @@ -2464,7 +2446,7 @@ bool routing_manager_stub::remove_security_policy_configuration( // remove security policy from configuration (only if there was a updateACL call before) if (is_policy_cached(_uid)) { - if (!security::get()->remove_security_policy(_uid, _gid)) { + if (!policy_manager_impl::get()->remove_security_policy(_uid, _gid)) { _handler(security_update_state_e::SU_UNKNOWN_USER_ID); ret = false; } else { @@ -2611,13 +2593,33 @@ void routing_manager_stub::on_security_update_response( } } } +#endif // !VSOMEIP_DISABLE_SECURITY void routing_manager_stub::send_suspend() const { - static const std::vector its_suspend( - { VSOMEIP_SUSPEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + protocol::suspend_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - broadcast(its_suspend); + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": suspend command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void +routing_manager_stub::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + (void)_local_port; + (void)_remote_address; + (void)_remote_port; + // dummy method to implement routing_host interface } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp index 324fcd7be..fcdcbd8f8 100644 --- a/implementation/routing/src/serviceinfo.cpp +++ b/implementation/routing/src/serviceinfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,8 +10,7 @@ namespace vsomeip_v3 { serviceinfo::serviceinfo(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl, bool _is_local) - : group_(0), - service_(_service), + : service_(_service), instance_(_instance), major_(_major), minor_(_minor), @@ -26,7 +25,6 @@ serviceinfo::serviceinfo(service_t _service, instance_t _instance, } serviceinfo::serviceinfo(const serviceinfo& _other) : - group_(_other.group_), service_(_other.service_), instance_(_other.instance_), major_(_other.major_), @@ -42,14 +40,6 @@ serviceinfo::serviceinfo(const serviceinfo& _other) : serviceinfo::~serviceinfo() { } -servicegroup * serviceinfo::get_group() const { - return group_; -} - -void serviceinfo::set_group(servicegroup *_group) { - group_ = _group; -} - service_t serviceinfo::get_service() const { return service_; } diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index 37df9493f..5dc9ef8b9 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -40,7 +41,8 @@ class application_impl: public application, public routing_manager_host, public std::enable_shared_from_this { public: - VSOMEIP_EXPORT application_impl(const std::string &_name); + VSOMEIP_EXPORT application_impl(const std::string &_name, + const std::string &_path); VSOMEIP_EXPORT ~application_impl(); VSOMEIP_EXPORT bool init(); @@ -84,6 +86,9 @@ class application_impl: public application, VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, event_t _event); + VSOMEIP_EXPORT void subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter); VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -103,23 +108,28 @@ class application_impl: public application, event_t _event, std::shared_ptr _payload, client_t _client, bool _force) const; - VSOMEIP_EXPORT void register_state_handler(state_handler_t _handler); + VSOMEIP_EXPORT void register_state_handler(const state_handler_t &_handler); VSOMEIP_EXPORT void unregister_state_handler(); VSOMEIP_EXPORT void register_message_handler(service_t _service, - instance_t _instance, method_t _method, message_handler_t _handler); + instance_t _instance, method_t _method, const message_handler_t &_handler); VSOMEIP_EXPORT void unregister_message_handler(service_t _service, instance_t _instance, method_t _method); VSOMEIP_EXPORT void register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, + major_version_t _major, minor_version_t _minor); + VSOMEIP_EXPORT void register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void unregister_availability_handler(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void register_subscription_handler(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, subscription_handler_t _handler); + instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_t &_handler); + VSOMEIP_EXPORT void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_ext_t &_handler); VSOMEIP_EXPORT void unregister_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -129,19 +139,20 @@ class application_impl: public application, VSOMEIP_EXPORT const std::string & get_name() const; VSOMEIP_EXPORT client_t get_client() const; VSOMEIP_EXPORT void set_client(const client_t &_client); - VSOMEIP_EXPORT session_t get_session(); + VSOMEIP_EXPORT session_t get_session(bool _is_request); + VSOMEIP_EXPORT const vsomeip_sec_client_t *get_sec_client() const; VSOMEIP_EXPORT diagnosis_t get_diagnosis() const; VSOMEIP_EXPORT std::shared_ptr get_configuration() const; VSOMEIP_EXPORT std::shared_ptr get_public_configuration() const; - VSOMEIP_EXPORT boost::asio::io_service & get_io(); + VSOMEIP_EXPORT boost::asio::io_context &get_io(); VSOMEIP_EXPORT void on_state(state_type_e _state); VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor); + availability_state_e _state, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void on_message(std::shared_ptr &&_message); VSOMEIP_EXPORT void on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed, - std::function _accepted_cb); + eventgroup_t _eventgroup, client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, const std::function &_accepted_cb); VSOMEIP_EXPORT void on_subscription_status(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error); VSOMEIP_EXPORT void register_subscription_status_handler(service_t _service, @@ -161,14 +172,17 @@ class application_impl: public application, VSOMEIP_EXPORT void clear_all_handler(); - VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler); + VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, const offered_services_handler_t &_handler); VSOMEIP_EXPORT void on_offered_services_info(std::vector> &_services); - VSOMEIP_EXPORT void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval); + VSOMEIP_EXPORT void set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval); VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, async_subscription_handler_t _handler); + instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_t &_handler); + + VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_ext_t &_handler); VSOMEIP_EXPORT void set_sd_acceptance_required(const remote_info_t& _remote, const std::string& _path, bool _enable); @@ -177,12 +191,12 @@ class application_impl: public application, VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required(); - VSOMEIP_EXPORT void register_sd_acceptance_handler(sd_acceptance_handler_t _handler); + VSOMEIP_EXPORT void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler); - VSOMEIP_EXPORT void register_reboot_notification_handler(reboot_notification_handler_t _handler); + VSOMEIP_EXPORT void register_reboot_notification_handler(const reboot_notification_handler_t &_handler); - VSOMEIP_EXPORT void register_routing_ready_handler(routing_ready_handler_t _handler); - VSOMEIP_EXPORT void register_routing_state_handler(routing_state_handler_t _handler); + VSOMEIP_EXPORT void register_routing_ready_handler(const routing_ready_handler_t &_handler); + VSOMEIP_EXPORT void register_routing_state_handler(const routing_state_handler_t &_handler); VSOMEIP_EXPORT bool update_service_configuration(service_t _service, instance_t _instance, @@ -195,10 +209,22 @@ class application_impl: public application, uint32_t _gid, std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler); + const security_update_handler_t &_handler); VSOMEIP_EXPORT void remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler); + const security_update_handler_t &_handler); + + VSOMEIP_EXPORT void register_message_acceptance_handler(const message_acceptance_handler_t &_handler); + + VSOMEIP_EXPORT std::map + get_additional_data(const std::string &_plugin_name); + + VSOMEIP_EXPORT void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler); + VSOMEIP_EXPORT void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler); private: // @@ -217,7 +243,7 @@ class application_impl: public application, struct sync_handler { - sync_handler(std::function _handler) : + sync_handler(const std::function &_handler) : handler_(_handler), service_id_(ANY_SERVICE), instance_id_(ANY_INSTANCE), @@ -247,7 +273,7 @@ class application_impl: public application, }; struct message_handler { - message_handler(message_handler_t _handler) : + message_handler(const message_handler_t &_handler) : handler_(_handler) {} bool operator<(const message_handler& _other) const { @@ -260,14 +286,15 @@ class application_impl: public application, // // Methods // - bool is_available_unlocked(service_t _service, instance_t _instance, + availability_state_e is_available_unlocked(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const; - bool are_available_unlocked(available_t &_available, + availability_state_e are_available_unlocked(available_t &_available, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const; - void do_register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + + void register_availability_handler_unlocked(service_t _service, + instance_t _instance, availability_state_handler_t _handler, major_version_t _major, minor_version_t _minor); @@ -303,6 +330,8 @@ class application_impl: public application, void watchdog_cbk(boost::system::error_code const &_error); + bool is_local_endpoint(const boost::asio::ip::address &_unicast, port_t _port); + // // Attributes // @@ -315,11 +344,13 @@ class application_impl: public application, bool is_initialized_; std::string name_; + + std::string path_; std::shared_ptr configuration_; - boost::asio::io_service io_; + boost::asio::io_context io_; std::set > io_threads_; - std::shared_ptr work_; + std::shared_ptr work_; // Proxy to or the Routing Manager itself std::shared_ptr routing_; @@ -344,19 +375,25 @@ class application_impl: public application, mutable std::mutex members_mutex_; // Availability handlers - typedef std::map>> availability_major_minor_t; + using availability_major_minor_t = + std::map>>; std::map> availability_; - mutable std::recursive_mutex availability_mutex_; + mutable std::mutex availability_mutex_; // Availability - mutable available_t available_; + using available_instance_t = + std::map>>; + using available_ext_t = std::map; + mutable available_ext_t available_; // Subscription handlers std::map>>> subscription_; + std::pair > > > subscription_; mutable std::mutex subscription_mutex_; std::map, - subscription_state_e> subscription_state_; + std::map + > + > + > subscription_state_; std::mutex watchdog_timer_mutex_; boost::asio::steady_timer watchdog_timer_; @@ -432,12 +474,9 @@ class application_impl: public application, std::map, std::deque > > availability_handlers_; - uid_t own_uid_; - gid_t own_gid_; + vsomeip_sec_client_t sec_client_; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG bool has_session_handling_; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG }; } // namespace vsomeip_v3 diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp index ec49a4276..b618ec473 100644 --- a/implementation/runtime/include/runtime_impl.hpp +++ b/implementation/runtime/include/runtime_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,8 @@ class runtime_impl: public runtime { std::shared_ptr create_application( const std::string &_name); + std::shared_ptr create_application( + const std::string &_name, const std::string &_path); std::shared_ptr create_message(bool _reliable) const; std::shared_ptr create_request(bool _reliable) const; diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 467bca2c6..e854958c4 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,9 +8,11 @@ #include #include +#include +#include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include #endif @@ -28,14 +30,14 @@ #include "../../configuration/include/configuration.hpp" #include "../../configuration/include/configuration_plugin.hpp" #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS +#include "../../endpoints/include/endpoint.hpp" #include "../../message/include/serializer.hpp" -#include "../../routing/include/routing_manager_impl.hpp" -#include "../../routing/include/routing_manager_proxy.hpp" -#include "../../utility/include/utility.hpp" -#include "../../tracing/include/connector_impl.hpp" #include "../../plugin/include/plugin_manager_impl.hpp" -#include "../../endpoints/include/endpoint.hpp" +#include "../../routing/include/routing_manager_impl.hpp" +#include "../../routing/include/routing_manager_client.hpp" #include "../../security/include/security.hpp" +#include "../../tracing/include/connector_impl.hpp" +#include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -46,12 +48,14 @@ configuration::~configuration() {} uint32_t application_impl::app_counter__ = 0; std::mutex application_impl::app_counter_mutex__; -application_impl::application_impl(const std::string &_name) +application_impl::application_impl(const std::string &_name, const std::string &_path) : runtime_(runtime::get()), client_(VSOMEIP_CLIENT_UNSET), session_(0), - is_initialized_(false), name_(_name), - work_(std::make_shared(io_)), + is_initialized_(false), + name_(_name), + path_(_path), + work_(std::make_shared(io_)), routing_(0), state_(state_type_e::ST_DEREGISTERED), security_mode_(security_mode_e::SM_OFF), @@ -67,17 +71,9 @@ application_impl::application_impl(const std::string &_name) is_routing_manager_host_(false), stopped_called_(false), watchdog_timer_(io_), - client_side_logging_(false) -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , has_session_handling_(true) -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG + client_side_logging_(false), + has_session_handling_(true) { - own_uid_ = ANY_UID; - own_gid_ = ANY_GID; -#ifndef _WIN32 - own_uid_ = getuid(); - own_gid_ = getgid(); -#endif } application_impl::~application_impl() { @@ -143,19 +139,19 @@ bool application_impl::init() { auto its_configuration_plugin = std::dynamic_pointer_cast(its_plugin); if (its_configuration_plugin) { - configuration_ = its_configuration_plugin->get_configuration(name_); + configuration_ = its_configuration_plugin->get_configuration(name_, path_); VSOMEIP_INFO << "Configuration module loaded."; } else { std::cerr << "Invalid configuration module!" << std::endl; std::exit(EXIT_FAILURE); } } else { - std::cerr << "Configuration module could not be loaded!" << std::endl; + std::cerr << "1 Configuration module could not be loaded!" << std::endl; std::exit(EXIT_FAILURE); } #else configuration_ = std::dynamic_pointer_cast( - std::make_shared()); + std::make_shared(configuration_path)); if (configuration_path.length()) { configuration_->set_configuration_path(configuration_path); } @@ -163,14 +159,31 @@ bool application_impl::init() { #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } + if (configuration_->is_local_routing()) { + sec_client_.client_type = VSOMEIP_CLIENT_UDS; +#ifdef __unix__ + sec_client_.client.uds_client.user = getuid(); + sec_client_.client.uds_client.group = getgid(); +#else + sec_client_.client.uds_client.user = ANY_UID; + sec_client_.client.uds_client.group = ANY_GID; +#endif + } else { + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + } + // Set security mode - auto its_security = security::get(); - if (its_security->is_enabled()) { - if (its_security->is_audit()) { + if (configuration_->is_security_enabled()) { + if (configuration_->is_security_audit()) { security_mode_ = security_mode_e::SM_AUDIT; } else { security_mode_ = security_mode_e::SM_ON; } + + if (security::load()) { + VSOMEIP_INFO << "Using external security implementation!"; + security::initialize(); + } } else { security_mode_ = security_mode_e::SM_OFF; } @@ -234,18 +247,16 @@ bool application_impl::init() { max_dispatchers_ = its_configuration->get_max_dispatchers(name_) + 1; max_dispatch_time_ = its_configuration->get_max_dispatch_time(name_); -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG has_session_handling_ = its_configuration->has_session_handling(name_); if (!has_session_handling_) VSOMEIP_INFO << "application: " << name_ << " has session handling switched off!"; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - std::string its_routing_host = its_configuration->get_routing_host(); + std::string its_routing_host = its_configuration->get_routing_host_name(); if (its_routing_host != "") { is_routing_manager_host_ = (its_routing_host == name_); if (is_routing_manager_host_ && - !utility::is_routing_manager(configuration_)) { + !utility::is_routing_manager(configuration_->get_network())) { #ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS VSOMEIP_ERROR << "application: " << name_ << " configured as " "routing but other routing manager present. Won't " @@ -257,7 +268,11 @@ bool application_impl::init() { #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } } else { - is_routing_manager_host_ = utility::is_routing_manager(configuration_); + auto its_routing_address = its_configuration->get_routing_host_address(); + auto its_routing_port = its_configuration->get_routing_host_port(); + if (its_routing_address.is_unspecified() + || is_local_endpoint(its_routing_address, its_routing_port)) + is_routing_manager_host_ = utility::is_routing_manager(configuration_->get_network()); } if (is_routing_manager_host_) { @@ -271,10 +286,9 @@ bool application_impl::init() { routing_ = std::make_shared(this); } else { VSOMEIP_INFO << "Instantiating routing manager [Proxy]."; - routing_ = std::make_shared(this, client_side_logging_, client_side_logging_filter_); + routing_ = std::make_shared(this, client_side_logging_, client_side_logging_filter_); } - routing_->set_client(client_); routing_->init(); #ifdef USE_DLT @@ -343,7 +357,7 @@ bool application_impl::init() { } void application_impl::start() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (getpid() != static_cast(syscall(SYS_gettid))) { // only set threadname if calling thread isn't the main thread std::stringstream s; @@ -382,7 +396,7 @@ void application_impl::start() { VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\" (" << std::hex << std::setw(4) << std::setfill('0') << client_ << ") using " << std::dec << io_thread_count << " threads" -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " I/O nice " << io_thread_nice_level #endif ; @@ -411,11 +425,11 @@ void application_impl::start() { << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) - #endif +#endif ; - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -426,7 +440,7 @@ void application_impl::start() { if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); } - #endif +#endif try { io_.run(); } catch (const std::exception &e) { @@ -458,11 +472,11 @@ void application_impl::start() { VSOMEIP_INFO << "io thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); } @@ -546,9 +560,7 @@ void application_impl::stop() { if (block) { std::unique_lock block_stop_lock(block_stop_mutex_); - while (!block_stopping_) { - block_stop_cv_.wait(block_stop_lock); - } + block_stop_cv_.wait(block_stop_lock, [this] { return block_stopping_; }); block_stopping_ = false; } } @@ -603,8 +615,9 @@ void application_impl::subscribe(service_t _service, instance_t _instance, } if (check_subscription_state(_service, _instance, _eventgroup, _event)) { - routing_->subscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _major, - _event); + routing_->subscribe(client_, &sec_client_, + _service, _instance, _eventgroup, _major, + _event, nullptr); } } } @@ -613,45 +626,45 @@ void application_impl::unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup) { remove_subscription(_service, _instance, _eventgroup, ANY_EVENT); if (routing_) - routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, ANY_EVENT); + routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, ANY_EVENT); } void application_impl::unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { remove_subscription(_service, _instance, _eventgroup, _event); if (routing_) - routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _event); + routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, _event); } bool application_impl::is_available( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - std::lock_guard its_lock(availability_mutex_); - return is_available_unlocked(_service, _instance, _major, _minor); + std::lock_guard its_lock(availability_mutex_); + return (is_available_unlocked(_service, _instance, _major, _minor) + == availability_state_e::AS_AVAILABLE); } -bool application_impl::is_available_unlocked( +availability_state_e +application_impl::is_available_unlocked( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - bool is_available(false); + availability_state_e its_state(availability_state_e::AS_UNKNOWN); - auto check_major_minor = [&](const std::map>::const_iterator &_found_instance) { + auto check_major_minor = [&](const available_instance_t::const_iterator &_found_instance) { auto found_major = _found_instance->second.find(_major); if (found_major != _found_instance->second.end()) { - if (_minor <= found_major->second || _minor == ANY_MINOR + if (_minor <= found_major->second.first || _minor == ANY_MINOR || _minor == DEFAULT_MINOR) { - is_available = true; + its_state = found_major->second.second; } } else if ((_major == DEFAULT_MAJOR || _major == ANY_MAJOR)) { for (const auto &found_major : _found_instance->second) { if (_minor == DEFAULT_MINOR || _minor == ANY_MINOR) { - is_available = true; + its_state = found_major.second.second; break; - } else if (_minor <= found_major.second) { - is_available = true; + } else if (_minor <= found_major.second.first) { + its_state = found_major.second.second; break; } } @@ -666,7 +679,7 @@ bool application_impl::is_available_unlocked( for (auto it = found_service->second.cbegin(); it != found_service->second.cend(); it++) { check_major_minor(it); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } @@ -676,49 +689,53 @@ bool application_impl::is_available_unlocked( auto found_instance = found_service.second.find(_instance); if (found_instance != found_service.second.end()) { check_major_minor(found_instance); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } else if (_instance == ANY_INSTANCE) { for (auto it = found_service.second.cbegin(); it != found_service.second.cend(); it++) { check_major_minor(it); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } } - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } } - return is_available; + return (its_state); } bool application_impl::are_available( available_t &_available, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - std::lock_guard its_lock(availability_mutex_); - return are_available_unlocked(_available, _service, _instance, _major, _minor); + std::lock_guard its_lock(availability_mutex_); + return (are_available_unlocked(_available, _service, _instance, _major, _minor) + == availability_state_e::AS_AVAILABLE); } -bool application_impl::are_available_unlocked(available_t &_available, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) const { +availability_state_e +application_impl::are_available_unlocked(available_t &_available, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) const { //find available services if(_service == ANY_SERVICE) { //add all available services for(auto its_available_services_it = available_.begin(); its_available_services_it != available_.end(); - ++its_available_services_it) + ++its_available_services_it) { _available[its_available_services_it->first]; + } } else { // check if specific service is available - if(available_.find(_service) != available_.end()) + if(available_.find(_service) != available_.end()) { _available[_service]; + } } //find available instances @@ -733,11 +750,13 @@ bool application_impl::are_available_unlocked(available_t &_available, //add all available instances for(auto its_available_instances_it = found_available_service->second.begin(); its_available_instances_it != found_available_service->second.end(); - ++its_available_instances_it) + ++its_available_instances_it) { _available[its_available_services_it->first][its_available_instances_it->first]; + } } else { - if(found_available_service->second.find(_instance) != found_available_service->second.end()) + if(found_available_service->second.find(_instance) != found_available_service->second.end()) { _available[its_available_services_it->first][_instance]; + } } } } @@ -761,11 +780,13 @@ bool application_impl::are_available_unlocked(available_t &_available, //add all major versions for(auto its_available_major_it = found_available_instance->second.begin(); its_available_major_it != found_available_instance->second.end(); - ++its_available_major_it) + ++its_available_major_it) { _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first]; + } } else { - if(found_available_instance->second.find(_major) != found_available_instance->second.end()) + if(found_available_instance->second.find(_major) != found_available_instance->second.end()) { _available[its_available_services_it->first][its_available_instances_it->first][_major]; + } } } } @@ -793,11 +814,13 @@ bool application_impl::are_available_unlocked(available_t &_available, ++its_available_major_it) { //get available major version auto found_available_major = found_available_instance->second.find(its_available_major_it->first); - if(found_available_major != found_available_instance->second.end()) { - if(_minor == ANY_MINOR || _minor == DEFAULT_MINOR - || _minor <= found_available_major->second) { + if (found_available_major != found_available_instance->second.end()) { + if ((_minor == ANY_MINOR || _minor == DEFAULT_MINOR + || _minor <= found_available_major->second.first) + && availability_state_e::AS_AVAILABLE == found_available_major->second.second) { //add minor version - _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first] = found_available_major->second; + _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first] + = found_available_major->second.first; found_minor = true; } } @@ -811,11 +834,12 @@ bool application_impl::are_available_unlocked(available_t &_available, its_available_services_it = _available.erase(its_available_services_it); } - if(_available.empty()) { + if (_available.empty()) { _available[_service][_instance][_major] = _minor ; - return false; + + return (availability_state_e::AS_UNAVAILABLE); } - return true; + return (availability_state_e::AS_AVAILABLE); } void application_impl::send(std::shared_ptr _message) { @@ -840,15 +864,16 @@ void application_impl::send(std::shared_ptr _message) { // in case of requests set the request-id (client-id|session-id) if (is_request) { _message->set_client(client_); - _message->set_session(get_session()); + _message->set_session(get_session(true)); } // Always increment the session-id - (void)routing_->send(client_, _message); + (void)routing_->send(client_, _message, false); } } void application_impl::notify(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, bool _force) const { + if (routing_) routing_->notify(_service, _instance, _event, _payload, _force); } @@ -866,7 +891,7 @@ void application_impl::notify_one(service_t _service, instance_t _instance, } } -void application_impl::register_state_handler(state_handler_t _handler) { +void application_impl::register_state_handler(const state_handler_t &_handler) { std::lock_guard its_lock(state_handler_mutex_); handler_ = _handler; } @@ -877,45 +902,62 @@ void application_impl::unregister_state_handler() { } void application_impl::register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, major_version_t _major, minor_version_t _minor) { - std::lock_guard availability_lock(availability_mutex_); - if (state_ == state_type_e::ST_REGISTERED) { - do_register_availability_handler(_service, _instance, - _handler, _major, _minor); - } else { - availability_[_service][_instance][_major][_minor] = std::make_pair( - _handler, false); - } + + std::lock_guard availability_lock(availability_mutex_); + auto its_handler_ext = [_handler](service_t _service, instance_t _instance, + availability_state_e _state) { + _handler(_service, _instance, + (_state == availability_state_e::AS_AVAILABLE)); + }; + + register_availability_handler_unlocked(_service, _instance, + its_handler_ext, _major, _minor); } -void application_impl::do_register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, +void application_impl::register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor) { - available_t available; - bool are_available = are_available_unlocked(available, _service, _instance, _major, _minor); - availability_[_service][_instance][_major][_minor] = std::make_pair( - _handler, true); - std::lock_guard handlers_lock(handlers_mutex_); + std::lock_guard availability_lock(availability_mutex_); + register_availability_handler_unlocked(_service, _instance, + _handler, _major, _minor); +} - std::shared_ptr its_sync_handler - = std::make_shared([_handler, are_available, available]() { - for(const auto& available_services_it : available) - for(const auto& available_instances_it : available_services_it.second) - _handler(available_services_it.first, available_instances_it.first, are_available); - }); - its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; - its_sync_handler->service_id_ = _service; - its_sync_handler->instance_id_ = _instance; - handlers_.push_back(its_sync_handler); +void application_impl::register_availability_handler_unlocked(service_t _service, + instance_t _instance, availability_state_handler_t _handler, + major_version_t _major, minor_version_t _minor) { + + if (state_ == state_type_e::ST_REGISTERED) { + available_t its_available; + auto are_available = are_available_unlocked(its_available, _service, _instance, _major, _minor); + availability_[_service][_instance][_major][_minor] + = std::make_pair(_handler, true); + + std::lock_guard handlers_lock(handlers_mutex_); + + std::shared_ptr its_sync_handler + = std::make_shared([_handler, are_available, its_available]() { + for(const auto& available_services_it : its_available) + for(const auto& available_instances_it : available_services_it.second) + _handler(available_services_it.first, available_instances_it.first, are_available); + }); + its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; + its_sync_handler->service_id_ = _service; + its_sync_handler->instance_id_ = _instance; + handlers_.push_back(its_sync_handler); - dispatcher_condition_.notify_one(); + dispatcher_condition_.notify_one(); + } else { + availability_[_service][_instance][_major][_minor] + = std::make_pair(_handler, false); + } } void application_impl::unregister_availability_handler(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { - std::lock_guard its_lock(availability_mutex_); + std::lock_guard its_lock(availability_mutex_); auto found_service = availability_.find(_service); if (found_service != availability_.end()) { auto found_instance = found_service->second.find(_instance); @@ -941,11 +983,14 @@ void application_impl::unregister_availability_handler(service_t _service, } } -void application_impl::on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, - bool _subscribed, std::function _accepted_cb) { +void application_impl::on_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, + const std::function &_accepted_cb) { + bool handler_found = false; - std::pair its_handlers; + std::pair its_handlers; { std::lock_guard its_lock(subscription_mutex_); auto found_service = subscription_.find(_service); @@ -964,10 +1009,10 @@ void application_impl::on_subscription(service_t _service, instance_t _instance, if (handler_found) { if(auto its_handler = its_handlers.first) { // "normal" subscription handler exists - _accepted_cb(its_handler(_client, _uid, _gid, _subscribed)); + _accepted_cb(its_handler(_client, _sec_client, _env, _subscribed)); } else if(auto its_handler = its_handlers.second) { // async subscription handler exists - its_handler(_client, _uid, _gid, _subscribed, _accepted_cb); + its_handler(_client, _sec_client, _env, _subscribed, _accepted_cb); } } else { _accepted_cb(true); @@ -976,12 +1021,59 @@ void application_impl::on_subscription(service_t _service, instance_t _instance, void application_impl::register_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - subscription_handler_t _handler) { + const subscription_handler_t &_handler) { + + subscription_handler_ext_t its_handler_ext + = [_handler](client_t _client, uid_t _uid, gid_t _gid, + const std::string &_env, bool _is_subscribed) { + + (void)_env; // compatibility + return _handler(_client, _uid, _gid, _is_subscribed); + }; + + register_subscription_handler(_service, _instance, _eventgroup, + its_handler_ext); +} + +void application_impl::register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_ext_t &_handler) { + + subscription_handler_sec_t its_handler_sec = [_handler]( + client_t _client, + const vsomeip_sec_client_t* _sec_client, + const std::string& _env, + bool _is_subscribed + ){ + uid_t its_uid{ANY_UID}; + gid_t its_gid{ANY_GID}; + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } + + return _handler( + _client, + its_uid, + its_gid, + _env, + _is_subscribed + ); + }; + + register_subscription_handler(_service, _instance, _eventgroup, its_handler_sec); +} + +void application_impl::register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler) { std::lock_guard its_lock(subscription_mutex_); subscription_[_service][_instance][_eventgroup] = std::make_pair(_handler, nullptr); } + void application_impl::unregister_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup) { std::lock_guard its_lock(subscription_mutex_); @@ -997,40 +1089,49 @@ void application_impl::unregister_subscription_handler(service_t _service, } } -void application_impl::on_subscription_status(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - uint16_t _error) { +void application_impl::on_subscription_status( + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event, uint16_t _error) { + bool entry_found(false); { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_subscription_state = subscription_state_.find(its_tuple); - if (its_subscription_state == subscription_state_.end()) { - its_tuple = std::make_tuple(_service, _instance, _eventgroup, ANY_EVENT); - auto its_any_subscription_state = subscription_state_.find(its_tuple); - if (its_any_subscription_state == subscription_state_.end()) { - VSOMEIP_TRACE << std::hex << get_client( ) - << " application_impl::on_subscription_status: " - << "Received a subscription status without subscribe for " - << std::hex << _service << "/" << _instance << "/" - << _eventgroup << "/" << _event << "/error=" << _error; - } else { - entry_found = true; - } - } else { - entry_found = true; - } - if (entry_found) { - if (_error) { - subscription_state_[its_tuple] = - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; - } else { - subscription_state_[its_tuple] = - subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED; + auto its_service = subscription_state_.find(_service); + if (its_service == subscription_state_.end()) + its_service = subscription_state_.find(ANY_SERVICE); + + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance == its_service->second.end()) + its_instance = its_service->second.find(ANY_INSTANCE); + + if (its_instance != its_service->second.end()) { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup == its_instance->second.end()) + its_eventgroup = its_instance->second.find(ANY_EVENTGROUP); + + if (its_eventgroup != its_instance->second.end()) { + auto its_event = its_eventgroup->second.find(_event); + if (its_event == its_eventgroup->second.end()) + its_event = its_eventgroup->second.find(ANY_EVENT); + + if (its_event != its_eventgroup->second.end()) { + entry_found = true; + its_event->second = (_error ? + subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED : + subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED); + } + auto its_any_event = its_eventgroup->second.find(ANY_EVENT); + if (its_any_event != its_eventgroup->second.end()) { + entry_found = true; + its_any_event->second = (_error ? + subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED : + subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED); + } + } } } } - if (entry_found) { deliver_subscription_state(_service, _instance, _eventgroup, _event, _error); } @@ -1038,6 +1139,7 @@ void application_impl::on_subscription_status(service_t _service, void application_impl::deliver_subscription_state(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error) { + std::vector handlers; { std::lock_guard its_lock(subscription_status_handlers_mutex_); @@ -1052,12 +1154,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1071,12 +1187,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1093,12 +1223,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1112,12 +1256,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1191,7 +1349,7 @@ void application_impl::unregister_subscription_status_handler(service_t _service } void application_impl::register_message_handler(service_t _service, - instance_t _instance, method_t _method, message_handler_t _handler) { + instance_t _instance, method_t _method, const message_handler_t &_handler) { std::lock_guard its_lock(members_mutex_); members_[_service][_instance][_method] = _handler; } @@ -1218,12 +1376,33 @@ void application_impl::offer_event(service_t _service, instance_t _instance, bool _update_on_change, const epsilon_change_func_t &_epsilon_change_func, reliability_type_e _reliability) { - if (routing_) + if (routing_) { + + if (_cycle == std::chrono::milliseconds::zero() + && _change_resets_cycle == false + && _update_on_change == true) { + + configuration_->get_event_update_properties( + _service, _instance, _notifier, + _cycle, _change_resets_cycle, _update_on_change); + + VSOMEIP_INFO << __func__ + << ": Event [" + << std::hex << std::setw(4) << std::setfill('0') + << _service << "." + << std::hex << std::setw(4) << std::setfill('0') + << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') + << _notifier << "] uses configured cycle time " + << std::dec << _cycle.count() << "ms"; + } + routing_->register_event(client_, _service, _instance, _notifier, _eventgroups, _type, _reliability, _cycle, _change_resets_cycle, _update_on_change, _epsilon_change_func, true); + } } void application_impl::stop_offer_event(service_t _service, instance_t _instance, @@ -1263,12 +1442,10 @@ void application_impl::set_client(const client_t &_client) { client_ = _client; } -session_t application_impl::get_session() { +session_t application_impl::get_session(bool _is_request) { -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - if (!has_session_handling_) + if (!has_session_handling_ && !_is_request) return (0); -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG std::lock_guard its_lock(session_mutex_); if (0 == ++session_) { @@ -1279,6 +1456,11 @@ session_t application_impl::get_session() { return session_; } +const vsomeip_sec_client_t *application_impl::get_sec_client() const { + + return &sec_client_; +} + std::shared_ptr application_impl::get_configuration() const { return configuration_; } @@ -1287,13 +1469,13 @@ diagnosis_t application_impl::get_diagnosis() const { return configuration_->get_diagnosis_address(); } -boost::asio::io_service & application_impl::get_io() { +boost::asio::io_context &application_impl::get_io() { return io_; } void application_impl::on_state(state_type_e _state) { { - std::lock_guard availability_lock(availability_mutex_); + std::lock_guard availability_lock(availability_mutex_); if (state_ != _state) { state_ = _state; if (state_ == state_type_e::ST_REGISTERED) { @@ -1302,7 +1484,7 @@ void application_impl::on_state(state_type_e _state) { for (const auto &its_major : its_instance.second) { for (const auto &its_minor : its_major.second) { if (!its_minor.second.second) { - do_register_availability_handler( + register_availability_handler_unlocked( its_service.first, its_instance.first, its_minor.second.first, @@ -1312,17 +1494,6 @@ void application_impl::on_state(state_type_e _state) { } } } - } else { - // Call on_availability callback on each service - for (const auto &its_service : availability_) { - for (const auto &its_instance : its_service.second) { - for (const auto &its_major : its_instance.second) { - for (const auto &its_minor : its_major.second) { - on_availability(its_service.first, its_instance.first, false, its_major.first, its_minor.first); - } - } - } - } } } } @@ -1348,16 +1519,17 @@ void application_impl::on_state(state_type_e _state) { } void application_impl::on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) { - std::vector its_handlers; + availability_state_e _state, major_version_t _major, minor_version_t _minor) { + + std::vector its_handlers; { - std::lock_guard availability_lock(availability_mutex_); - if (_is_available == is_available_unlocked(_service, _instance, _major, _minor)) { + std::lock_guard availability_lock(availability_mutex_); + if (_state == is_available_unlocked(_service, _instance, _major, _minor)) { return; } - if (_is_available) { - available_[_service][_instance][_major] = _minor; + if (_state != availability_state_e::AS_UNAVAILABLE) { + available_[_service][_instance][_major] = std::make_pair(_minor, _state); } else { auto found_available_service = available_.find(_service); if (found_available_service != available_.end()) { @@ -1365,7 +1537,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance, if( found_instance != found_available_service->second.end()) { auto found_major = found_instance->second.find(_major); if( found_major != found_instance->second.end() ){ - if( _minor == found_major->second) + if(_minor == found_major->second.first) found_available_service->second.erase(_instance); } } @@ -1429,9 +1601,9 @@ void application_impl::on_availability(service_t _service, instance_t _instance, for (const auto &handler : its_handlers) { std::shared_ptr its_sync_handler = std::make_shared( - [handler, _service, _instance, _is_available]() + [handler, _service, _instance, _state]() { - handler(_service, _instance, _is_available); + handler(_service, _instance, _state); }); its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; its_sync_handler->service_id_ = _service; @@ -1440,7 +1612,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } } } - if (!_is_available) { + if (_state == availability_state_e::AS_UNAVAILABLE) { { std::lock_guard its_lock(subscriptions_mutex_); auto found_service = subscriptions_.find(_service); @@ -1457,11 +1629,16 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } { std::lock_guard its_lock(subscriptions_state_mutex_); - for (auto &its_subscription_state : subscription_state_) { - if (std::get<0>(its_subscription_state.first) == _service && - std::get<1>(its_subscription_state.first) == _instance) { - its_subscription_state.second = - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + for (auto &its_eventgroup : its_instance->second) { + for (auto &its_event : its_eventgroup.second) { + its_event.second + = subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; + } + } } } } @@ -1481,10 +1658,11 @@ void application_impl::on_message(std::shared_ptr &&_message) { if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) { if (!check_for_active_subscription(its_service, its_instance, static_cast(its_method))) { - VSOMEIP_ERROR << "application_impl::on_message [" + VSOMEIP_INFO << "application_impl::on_message [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_method << "]"; + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]" + << ": blocked as the subscription is already inactive."; return; } } @@ -1569,7 +1747,7 @@ routing_manager * application_impl::get_routing_manager() const { } void application_impl::main_dispatch() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -1581,7 +1759,7 @@ void application_impl::main_dispatch() { VSOMEIP_INFO << "main dispatch thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << its_id -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; @@ -1591,9 +1769,10 @@ void application_impl::main_dispatch() { // Cancel other waiting dispatcher dispatcher_condition_.notify_all(); // Wait for new handlers to execute - while (is_dispatching_ && (handlers_.empty() || !is_active_dispatcher(its_id))) { - dispatcher_condition_.wait(its_lock); - } + dispatcher_condition_.wait(its_lock, [this, &its_id] { + return !(is_dispatching_ + && (handlers_.empty() || !is_active_dispatcher(its_id))); + }); } else { std::shared_ptr its_handler; while (is_dispatching_ && is_active_dispatcher(its_id) @@ -1622,7 +1801,7 @@ void application_impl::main_dispatch() { } void application_impl::dispatch() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -1634,14 +1813,15 @@ void application_impl::dispatch() { VSOMEIP_INFO << "dispatch thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << its_id -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; std::unique_lock its_lock(handlers_mutex_); while (is_active_dispatcher(its_id)) { if (is_dispatching_ && handlers_.empty()) { - dispatcher_condition_.wait(its_lock); + dispatcher_condition_.wait(its_lock, + [this, &its_id] { return !is_active_dispatcher(its_id); }); // Maybe woken up from main dispatcher if (handlers_.empty() && !is_active_dispatcher(its_id)) { if (!is_dispatching_) { @@ -1775,7 +1955,9 @@ void application_impl::invoke_handler(std::shared_ptr &_handler) { << get_client() << " is shutting down"; } } else { - VSOMEIP_ERROR << "Maximum number of dispatchers exceeded."; + VSOMEIP_ERROR << "Maximum number of dispatchers exceeded. Configuration: " + << " Max dispatchers: " << std::dec << max_dispatchers_ + << " Max dispatch time: " << std::dec << max_dispatch_time_; } dispatcher_mutex_.unlock(); break; @@ -1889,7 +2071,7 @@ void application_impl::clear_all_handler() { } { - std::lock_guard availability_lock(availability_mutex_); + std::lock_guard availability_lock(availability_mutex_); availability_.clear(); } @@ -1917,11 +2099,11 @@ void application_impl::shutdown() { VSOMEIP_INFO << "shutdown thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) boost::asio::detail::posix_signal_blocker blocker; { std::stringstream s; @@ -1933,9 +2115,7 @@ void application_impl::shutdown() { { std::unique_lock its_lock(start_stop_mutex_); - while(!stopped_) { - stop_cv_.wait(its_lock); - } + stop_cv_.wait(its_lock, [this] {return stopped_; }); } { std::lock_guard its_handler_lock(handlers_mutex_); @@ -2102,9 +2282,28 @@ void application_impl::remove_subscription(service_t _service, event_t _event) { { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); std::lock_guard its_lock(subscriptions_state_mutex_); - subscription_state_.erase(its_tuple); + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + if (_event == ANY_EVENT) { + its_instance->second.erase(_eventgroup); + } else { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup != its_instance->second.end()) { + its_eventgroup->second.erase(_event); + if (its_eventgroup->second.empty()) { + its_instance->second.erase(_eventgroup); + } + } + } + if (its_instance->second.empty()) + its_service->second.erase(its_instance); + } + if (its_service->second.empty()) + subscription_state_.erase(its_service); + } } std::lock_guard its_lock(subscriptions_mutex_); @@ -2157,7 +2356,7 @@ bool application_impl::check_for_active_subscription(service_t _service, std::shared_ptr its_event = routing_->find_event( _service, _instance, _event); if (its_event) { - for (const auto& eg : its_event->get_eventgroups()) { + for (const auto eg : its_event->get_eventgroups()) { auto found_eventgroup = found_any_event->second.find(eg); if (found_eventgroup != found_any_event->second.end()) { // set the flag for initial event received to true @@ -2183,25 +2382,39 @@ bool application_impl::check_for_active_subscription(service_t _service, bool application_impl::check_subscription_state(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + bool is_acknowledged(false); bool should_subscribe(true); { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); + bool has_found(false); + std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_subscription_state = subscription_state_.find(its_tuple); - if (its_subscription_state != subscription_state_.end()) { - if (its_subscription_state->second != - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) { - // only return true if subscription is NACK - // as only then we need to subscribe! - should_subscribe = false; - if (its_subscription_state->second == - subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) { - is_acknowledged = true; + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup != its_instance->second.end()) { + auto its_event = its_eventgroup->second.find(_event); + if (its_event != its_eventgroup->second.end()) { + if (its_event->second != subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) { + has_found = true; + + // only return true if subscription is NACK + // as only then we need to subscribe! + should_subscribe = false; + if (its_event->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) { + is_acknowledged = true; + } + } + } } } - } else { - subscription_state_[its_tuple] = subscription_state_e::IS_SUBSCRIBING; + } + + if (!has_found) { + subscription_state_[_service][_instance][_eventgroup][_event] + = subscription_state_e::IS_SUBSCRIBING; } } @@ -2257,7 +2470,8 @@ void application_impl::print_blocking_call(const std::shared_ptr& } -void application_impl::get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) { +void application_impl::get_offered_services_async(offer_type_e _offer_type, + const offered_services_handler_t &_handler) { { std::lock_guard its_lock(offered_services_handler_mutex_); offered_services_handler_ = _handler; @@ -2343,7 +2557,7 @@ void application_impl::watchdog_cbk(boost::system::error_code const &_error) { } } -void application_impl::set_watchdog_handler(watchdog_handler_t _handler, +void application_impl::set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval) { if (_handler && std::chrono::seconds::zero() != _interval) { std::lock_guard its_lock(watchdog_timer_mutex_); @@ -2362,14 +2576,63 @@ void application_impl::set_watchdog_handler(watchdog_handler_t _handler, void application_impl::register_async_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - async_subscription_handler_t _handler) { + const async_subscription_handler_t &_handler) { + + async_subscription_handler_ext_t its_handler_ext + = [_handler](client_t _client, uid_t _uid, gid_t _gid, + const std::string &_env, bool _is_subscribed, + const std::function< void (const bool) > &_cb) { + + (void)_env; // compatibility + _handler(_client, _uid, _gid, _is_subscribed, _cb); + }; + + register_async_subscription_handler(_service, _instance, _eventgroup, + its_handler_ext); +} + +void application_impl::register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_ext_t &_handler) { + + async_subscription_handler_sec_t its_handler_sec = [_handler]( + client_t _client, + const vsomeip_sec_client_t* _sec_client, + const std::string& _env, + bool _is_subscribed, + const std::function &_cb + ){ + uid_t its_uid{ANY_UID}; + gid_t its_gid{ANY_GID}; + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } + + _handler( + _client, + its_uid, + its_gid, + _env, + _is_subscribed, + _cb + ); + }; + + register_async_subscription_handler(_service, _instance, _eventgroup, its_handler_sec); +} + +void application_impl::register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler) { std::lock_guard its_lock(subscription_mutex_); - subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler);; + subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler); } void application_impl::register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) { + const sd_acceptance_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_sd_acceptance_handler(_handler); @@ -2377,7 +2640,7 @@ void application_impl::register_sd_acceptance_handler( } void application_impl::register_reboot_notification_handler( - reboot_notification_handler_t _handler) { + const reboot_notification_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_reboot_notification_handler(_handler); @@ -2519,7 +2782,7 @@ application_impl::get_sd_acceptance_required() { } void application_impl::register_routing_ready_handler( - routing_ready_handler_t _handler) { + const routing_ready_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_routing_ready_handler(_handler); @@ -2527,7 +2790,7 @@ void application_impl::register_routing_ready_handler( } void application_impl::register_routing_state_handler( - routing_state_handler_t _handler) { + const routing_state_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_routing_state_handler(_handler); @@ -2565,7 +2828,14 @@ void application_impl::update_security_policy_configuration(uint32_t _uid, uint32_t _gid, ::std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler) { + const security_update_handler_t &_handler) { +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_uid; + (void)_gid; + (void)_policy; + (void)_payload; + (void)_handler; +#else if (!is_routing()) { VSOMEIP_ERROR << __func__ << " is only intended to be called by " "application acting as routing manager host"; @@ -2577,11 +2847,17 @@ void application_impl::update_security_policy_configuration(uint32_t _uid, rm_impl->update_security_policy_configuration(_uid, _gid, _policy, _payload, _handler); } } +#endif // VSOMEIP_DISABLE_SECURITY } void application_impl::remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler) { + const security_update_handler_t &_handler) { +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_uid; + (void)_gid; + (void)_handler; +#else if (!is_routing()) { VSOMEIP_ERROR << __func__ << " is only intended to be called by " "application acting as routing manager host"; @@ -2593,6 +2869,65 @@ void application_impl::remove_security_policy_configuration(uint32_t _uid, rm_impl->remove_security_policy_configuration(_uid, _gid, _handler); } } +#endif // !VSOMEIP_DISABLE_SECURITY +} + +void application_impl::subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter) { + + if (routing_) { + bool send_back_cached(false); + bool send_back_cached_group(false); + check_send_back_cached_event(_service, _instance, _event, _eventgroup, + &send_back_cached, &send_back_cached_group); + + if (send_back_cached) { + send_back_cached_event(_service, _instance, _event); + } else if(send_back_cached_group) { + send_back_cached_eventgroup(_service, _instance, _eventgroup); + } + + if (check_subscription_state(_service, _instance, _eventgroup, _event)) { + + auto its_filter = std::make_shared(_filter); + routing_->subscribe(client_, get_sec_client(), + _service, _instance, _eventgroup, _major, + _event, its_filter); + } + } +} + +bool +application_impl::is_local_endpoint(const boost::asio::ip::address &_unicast, + port_t _port) { + + try { + boost::asio::ip::tcp::endpoint its_endpoint(_unicast, _port); + boost::asio::ip::tcp::socket its_socket(io_, its_endpoint); + its_socket.close(); + + return (true); + } catch (...) { + } + + return (false); +} + +void application_impl::register_message_acceptance_handler( + const message_acceptance_handler_t &_handler) { + if (is_routing() && routing_) { + const auto rm_impl = std::dynamic_pointer_cast(routing_); + rm_impl->register_message_acceptance_handler(_handler); + } +} + +std::map +application_impl::get_additional_data(const std::string &_plugin_name) { + if (configuration_) { + return configuration_->get_additional_data(name_, _plugin_name); + } + return std::map(); } } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime.cpp b/implementation/runtime/src/runtime.cpp index 40bb45563..b2fab889e 100644 --- a/implementation/runtime/src/runtime.cpp +++ b/implementation/runtime/src/runtime.cpp @@ -1,15 +1,11 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include -#include #include "../include/runtime_impl.hpp" -#include "../../endpoints/include/endpoint.hpp" -#include "../../endpoints/include/client_endpoint.hpp" -#include "../../configuration/include/configuration_plugin.hpp" namespace vsomeip_v3 { @@ -25,19 +21,4 @@ std::shared_ptr runtime::get() { return runtime_impl::get(); } -// non-inline destructors to make typeinfo of the type visible outside the shared library boundary -#ifdef ANDROID -plugin::~plugin() { -} - -endpoint::~endpoint() { -} - -client_endpoint::~client_endpoint() { -} - -configuration_plugin::~configuration_plugin() { -} -#endif - } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp index fc23ced70..cf74b2fd3 100644 --- a/implementation/runtime/src/runtime_impl.cpp +++ b/implementation/runtime/src/runtime_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -35,15 +35,22 @@ runtime_impl::~runtime_impl() { std::shared_ptr runtime_impl::create_application( const std::string &_name) { + + return (create_application(_name, "")); +} + +std::shared_ptr runtime_impl::create_application( + const std::string &_name, const std::string &_path) { static std::uint32_t postfix_id = 0; std::lock_guard its_lock(applications_mutex_); - std::string its_name_ = _name; + std::string its_name = _name; auto found_application = applications_.find(_name); if( found_application != applications_.end()) { - its_name_ += "_" + std::to_string(postfix_id++); + its_name += "_" + std::to_string(postfix_id++); } - std::shared_ptr application = std::make_shared(its_name_); - applications_[its_name_] = application; + std::shared_ptr application + = std::make_shared(its_name, _path); + applications_[its_name] = application; return application; } diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp index 82f3eb94f..3c9760c70 100644 --- a/implementation/security/include/policy.hpp +++ b/implementation/security/include/policy.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/security/include/policy_manager_impl.hpp b/implementation/security/include/policy_manager_impl.hpp index a5a30ea09..4dd3a8654 100644 --- a/implementation/security/include/policy_manager_impl.hpp +++ b/implementation/security/include/policy_manager_impl.hpp @@ -1,29 +1,48 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ -#define VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ +#ifndef VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ +#define VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ -#include +#include #include +#include +#include -#include +#include +#include +#include + +#include #include +#include #include "../include/policy.hpp" -#include "../../configuration/include/configuration_element.hpp" namespace vsomeip_v3 { -class policy_manager_impl - : public policy_manager { +struct configuration_element; + +class VSOMEIP_IMPORT_EXPORT policy_manager_impl +#ifndef VSOMEIP_DISABLE_SECURITY + : public policy_manager +#endif // !VSOMEIP_DISABLE_SECURITY +{ public: - static std::shared_ptr get(); + enum class policy_loaded_e : std::uint8_t { + POLICY_PATH_FOUND_AND_LOADED = 0x0, + POLICY_PATH_FOUND_AND_NOT_LOADED = 0x1, + POLICY_PATH_INEXISTENT = 0x2 + }; - virtual ~policy_manager_impl(); + static std::shared_ptr get(); + policy_manager_impl(); + +#ifndef VSOMEIP_DISABLE_SECURITY + // policy_manager interface std::shared_ptr create_policy() const; void print_policy(const std::shared_ptr &_policy) const; @@ -36,8 +55,144 @@ class policy_manager_impl bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const; bool is_policy_removal_allowed(uint32_t _uid) const; + + // extension + void load(const configuration_element &_element, + const bool _lazy_load = false); + + void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy); + bool remove_security_policy(uint32_t _uid, uint32_t _gid); + + void add_security_credentials(uint32_t _uid, uint32_t _gid, + const std::shared_ptr& _credentials_policy, client_t _client); + + void get_requester_policies(const std::shared_ptr _policy, + std::set > &_requesters) const; + void get_clients(uid_t _uid, gid_t _gid, std::unordered_set &_clients) const; + + bool is_policy_extension(const std::string &_path) const; + std::string get_policy_extension_path(const std::string &_client_host) const; + + void set_policy_extension_base_path(const std::string &_path); + std::string get_security_config_folder(const std::string &its_folder) const; + std::string get_policy_extension_path_unlocked(const std::string &_client_host) const; + + policy_loaded_e is_policy_extension_loaded(const std::string &_client_host) const; + void set_is_policy_extension_loaded(const std::string &_client_host, const bool _loaded); + +private: + + // Configuration + void load_policies(const configuration_element &_element); + void load_policy(const boost::property_tree::ptree &_tree); + void load_policy_body(std::shared_ptr &_policy, + const boost::property_tree::ptree::const_iterator &_tree); + void load_credential(const boost::property_tree::ptree &_tree, + boost::icl::interval_map > &_ids); + bool load_routing_credentials(const configuration_element &_element); + template + void load_interval_set(const boost::property_tree::ptree &_tree, + boost::icl::interval_set &_range, bool _exclude_margins = false); + void load_security_update_whitelist(const configuration_element &_element); + void load_security_policy_extensions(const configuration_element &_element); +#endif // !VSOMEIP_DISABLE_SECURITY + +public: + bool is_enabled() const; + bool is_audit() const; + + bool check_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client); + bool check_routing_credentials( + const vsomeip_sec_client_t *_sec_client) const; + void set_routing_credentials(uint32_t _uid, uint32_t _gid, + const std::string &_name); + + bool is_client_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, method_t _method, + bool _is_request_service = false) const; + bool is_offer_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance) const; + + bool get_sec_client_to_clients_mapping(const vsomeip_sec_client_t *_sec_client, + std::set &_clients); + bool remove_client_to_sec_client_mapping(client_t _client); + + bool get_client_to_sec_client_mapping(client_t _client, vsomeip_sec_client_t &_sec_client); + bool store_client_to_sec_client_mapping(client_t _client, const vsomeip_sec_client_t *_sec_client); + void store_sec_client_to_client_mapping(const vsomeip_sec_client_t *_sec_client, client_t _client); + +private: +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4251) +#endif +#ifndef VSOMEIP_DISABLE_SECURITY + mutable boost::shared_mutex any_client_policies_mutex_; + std::vector > any_client_policies_; + + mutable boost::shared_mutex is_client_allowed_cache_mutex_; + mutable std::map, + std::set > + > is_client_allowed_cache_; + + bool policy_enabled_; + bool check_credentials_; + bool allow_remote_clients_; + bool check_whitelist_; + + mutable std::mutex service_interface_whitelist_mutex_; + boost::icl::interval_set service_interface_whitelist_; + + mutable std::mutex uid_whitelist_mutex_; + boost::icl::interval_set uid_whitelist_; + + mutable std::mutex policy_base_path_mutex_; + std::string policy_base_path_; + + mutable boost::shared_mutex policy_extension_paths_mutex_; + //map[hostname, pair[path, map[complete path with UID/GID, control loading]] + std::map>> policy_extension_paths_; +#endif // !VSOMEIP_DISABLE_SECURITY + + bool is_configured_; + bool check_routing_credentials_; + + mutable std::mutex routing_credentials_mutex_; + std::pair routing_credentials_; + + mutable std::mutex ids_mutex_; + std::map ids_; + + struct vsomeip_sec_client_comparator_t { + bool operator()(const vsomeip_sec_client_t &_lhs, const vsomeip_sec_client_t &_rhs) const { + if (_lhs.client_type < _rhs.client_type) { + return true; + } else if (_lhs.client_type == _rhs.client_type) { + switch (_lhs.client_type) { + case VSOMEIP_CLIENT_UDS: + return ((_lhs.client.uds_client.user < _rhs.client.uds_client.user) + || ((_lhs.client.uds_client.user == _rhs.client.uds_client.user) + && (_lhs.client.uds_client.group < _rhs.client.uds_client.group))); + case VSOMEIP_CLIENT_TCP: + return ((_lhs.client.ip_client.ip < _rhs.client.ip_client.ip) + || ((_lhs.client.ip_client.ip == _rhs.client.ip_client.ip) + && (_lhs.client.ip_client.port < _rhs.client.ip_client.port))); + default: + ; + } + } + return false; + } + }; + + mutable std::mutex sec_client_to_clients_mutex_; + std::map, vsomeip_sec_client_comparator_t> sec_client_to_clients_; +#ifdef _WIN32 +#pragma warning(pop) +#endif }; } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ +#endif // VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ diff --git a/implementation/security/include/security.hpp b/implementation/security/include/security.hpp index 03406c67d..1affb0c45 100644 --- a/implementation/security/include/security.hpp +++ b/implementation/security/include/security.hpp @@ -1,65 +1,34 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_SECURITY_SECURITY_HPP_ -#define VSOMEIP_V3_SECURITY_SECURITY_HPP_ +#ifndef VSOMEIP_V3_SECURITY_HPP_ +#define VSOMEIP_V3_SECURITY_HPP_ -#include -#include - -#include -#include +#include +#include namespace vsomeip_v3 { -struct configuration_element; - -class security { +class VSOMEIP_IMPORT_EXPORT security { public: - VSOMEIP_EXPORT static std::shared_ptr get(); - - virtual ~security() {}; - - virtual void load(const configuration_element &_element) = 0; - - virtual bool is_enabled() const = 0; - virtual bool is_audit() const = 0; - - virtual bool check_credentials(client_t _client, uid_t _uid, gid_t _gid) = 0; - virtual bool check_routing_credentials(client_t _client, - uint32_t _uid, uint32_t _gid) const = 0; - - virtual bool is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service = false) const = 0; - virtual bool is_remote_client_allowed() const = 0; - virtual bool is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance) const = 0; - - virtual void update_security_policy(uint32_t _uid, uint32_t _gid, - const std::shared_ptr& _policy) = 0; - virtual bool remove_security_policy(uint32_t _uid, uint32_t _gid) = 0; - - virtual bool get_uid_gid_to_client_mapping(std::pair _uid_gid, - std::set &_clients) = 0; - virtual bool remove_client_to_uid_gid_mapping(client_t _client) = 0; - - virtual bool get_client_to_uid_gid_mapping(client_t _client, - std::pair &_uid_gid) = 0; - - virtual bool store_client_to_uid_gid_mapping(client_t _client, - uint32_t _uid, uint32_t _gid) = 0; - virtual void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, - client_t _client) = 0; - - virtual void get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const = 0; - virtual void get_clients(uid_t _uid, gid_t _gid, - std::unordered_set &_clients) const = 0; + static bool load(); + + static decltype(&vsomeip_sec_policy_initialize) initialize; + static decltype(&vsomeip_sec_policy_authenticate_router) authenticate_router; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_offer) is_client_allowed_to_offer; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_request) is_client_allowed_to_request; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_access_member) is_client_allowed_to_access_member; + +private: + static decltype(vsomeip_sec_policy_initialize) default_initialize; + static decltype(vsomeip_sec_policy_authenticate_router) default_authenticate_router; + static decltype(vsomeip_sec_policy_is_client_allowed_to_offer) default_is_client_allowed_to_offer; + static decltype(vsomeip_sec_policy_is_client_allowed_to_request) default_is_client_allowed_to_request; + static decltype(vsomeip_sec_policy_is_client_allowed_to_access_member) default_is_client_allowed_to_access_member; }; } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_SECURITY_SECURITY_HPP_ +#endif // VSOMEIP_V3_SECURITY_HPP_ diff --git a/implementation/security/include/security_impl.hpp b/implementation/security/include/security_impl.hpp deleted file mode 100644 index dfeea6bd9..000000000 --- a/implementation/security/include/security_impl.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_V3_SECURITY_IMPL_HPP_ -#define VSOMEIP_V3_SECURITY_IMPL_HPP_ - -#include -#include -#include - -#include - -#include "../include/policy.hpp" -#include "../include/security.hpp" - -namespace vsomeip_v3 { - -class security_impl : - public security { -public: - static std::shared_ptr get(); - - security_impl(); - - void load(const configuration_element &_element); - - bool is_enabled() const; - bool is_audit() const; - - bool check_credentials(client_t _client, uid_t _uid, gid_t _gid); - bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; - - bool is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service = false) const; - bool is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance) const; - - void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy); - bool remove_security_policy(uint32_t _uid, uint32_t _gid); - - void add_security_credentials(uint32_t _uid, uint32_t _gid, - const std::shared_ptr& _credentials_policy, client_t _client); - - bool is_remote_client_allowed() const; - - bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const; - - bool is_policy_removal_allowed(uint32_t _uid) const; - - bool parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const; - - bool get_uid_gid_to_client_mapping(std::pair _uid_gid, std::set &_clients); - bool remove_client_to_uid_gid_mapping(client_t _client); - - bool get_client_to_uid_gid_mapping(client_t _client, std::pair &_uid_gid); - bool store_client_to_uid_gid_mapping(client_t _client, uint32_t _uid, uint32_t _gid); - void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, client_t _client); - - void get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const; - void get_clients(uid_t _uid, gid_t _gid, std::unordered_set &_clients) const; - -private: - - // Configuration - void load_policies(const configuration_element &_element); - void load_policy(const boost::property_tree::ptree &_tree); - void load_policy_body(std::shared_ptr &_policy, - const boost::property_tree::ptree::const_iterator &_tree); - void load_credential(const boost::property_tree::ptree &_tree, - boost::icl::interval_map > &_ids); - bool load_routing_credentials(const configuration_element &_element); - template - void load_interval_set(const boost::property_tree::ptree &_tree, - boost::icl::interval_set &_range, bool _exclude_margins = false); - void load_security_update_whitelist(const configuration_element &_element); - -private: - client_t routing_client_; - - mutable std::mutex ids_mutex_; - mutable std::mutex uid_to_clients_mutex_; - - std::vector > any_client_policies_; - - mutable std::mutex any_client_policies_mutex_; - std::map > ids_; - std::map, std::set > uid_to_clients_; - - bool policy_enabled_; - bool check_credentials_; - bool check_routing_credentials_; - bool allow_remote_clients_; - bool check_whitelist_; - - mutable std::mutex service_interface_whitelist_mutex_; - boost::icl::interval_set service_interface_whitelist_; - - mutable std::mutex uid_whitelist_mutex_; - boost::icl::interval_set uid_whitelist_; - - mutable std::mutex routing_credentials_mutex_; - std::pair routing_credentials_; - - bool is_configured_; -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_SECURITY_IMPL_HPP_ diff --git a/implementation/security/src/policy.cpp b/implementation/security/src/policy.cpp index 260198ab2..b58271229 100644 --- a/implementation/security/src/policy.cpp +++ b/implementation/security/src/policy.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -175,7 +175,7 @@ policy::deserialize_ids(const byte_t * &_data, uint32_t &_size, if (its_result == false) return (false); - for (const auto& i : its_instances) + for (const auto i : its_instances) its_ids += std::make_pair(i, its_methods); its_array_length -= (its_current_size - _size); @@ -202,7 +202,8 @@ policy::deserialize_id_item_list(const byte_t * &_data, uint32_t &_size, uint32_t its_current_size(_size); - uint16_t its_low, its_high; + uint16_t its_low = 0; + uint16_t its_high = 0; its_result = deserialize_id_item(_data, _size, its_low, its_high); if (its_result == false) return (false); @@ -378,7 +379,7 @@ policy::serialize_interval_set( uint32_t its_interval_set_size(0); serialize_u32(its_interval_set_size, _data); - for (const auto& i : _intervals) + for (const auto i : _intervals) serialize_interval(i, _data); its_interval_set_size = static_cast(_data.size() diff --git a/implementation/security/src/policy_manager.cpp b/implementation/security/src/policy_manager.cpp index beae85c67..ad1b52e49 100644 --- a/implementation/security/src/policy_manager.cpp +++ b/implementation/security/src/policy_manager.cpp @@ -5,13 +5,13 @@ #include "../include/policy_manager_impl.hpp" +#ifndef VSOMEIP_DISABLE_SECURITY namespace vsomeip_v3 { std::shared_ptr policy_manager::get() { - static std::shared_ptr the_policy_manager - = std::make_shared(); - return the_policy_manager; + return policy_manager_impl::get(); } } // namespace vsomeip_v3 +#endif diff --git a/implementation/security/src/policy_manager_impl.cpp b/implementation/security/src/policy_manager_impl.cpp index a8167143c..849a36bf8 100644 --- a/implementation/security/src/policy_manager_impl.cpp +++ b/implementation/security/src/policy_manager_impl.cpp @@ -1,15 +1,1281 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../include/policy.hpp" +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include + #include +#endif + +#include +#include + #include "../include/policy_manager_impl.hpp" -#include "../include/security_impl.hpp" +#include "../../configuration/include/configuration_element.hpp" +#ifdef ANDROID +#include "../../configuration/include/internal_android.hpp" +#else +#include "../../configuration/include/internal.hpp" +#endif // ANDROID +#include "../../utility/include/utility.hpp" namespace vsomeip_v3 { -policy_manager_impl::~policy_manager_impl() { +template +void read_data(const std::string &_in, T_ &_out) { + std::stringstream its_converter; + + if (_in.size() > 2 + && _in[0] == '0' + && (_in[1] == 'x' || _in[1] == 'X')) + its_converter << std::hex << _in; + else + its_converter << std::dec << _in; + + its_converter >> _out; +} + +policy_manager_impl::policy_manager_impl() + : +#ifndef VSOMEIP_DISABLE_SECURITY + policy_enabled_(false), + check_credentials_(false), + allow_remote_clients_(true), + check_whitelist_(false), + policy_base_path_(""), +#endif // !VSOMEIP_DISABLE_SECURITY + is_configured_(false), + check_routing_credentials_(false) +{ +} + +bool +policy_manager_impl::is_enabled() const { +#ifdef VSOMEIP_DISABLE_SECURITY + return (false); +#else + return (policy_enabled_); +#endif +} + +bool +policy_manager_impl::is_audit() const { +#ifdef VSOMEIP_DISABLE_SECURITY + return (false); +#else + return (!check_credentials_); +#endif +} + +bool +policy_manager_impl::check_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_client; + (void)_sec_client; + + return (true); +#else + if (!policy_enabled_) + return (true); + + if (!_sec_client) + return (true); + + if (_sec_client->client_type != VSOMEIP_CLIENT_UDS) + return (true); + + uid_t its_uid(_sec_client->client.uds_client.user); + gid_t its_gid(_sec_client->client.uds_client.group); + + bool has_id(false); + + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + + std::lock_guard its_policy_lock(p->mutex_); + + bool has_uid, has_gid(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + has_id = (has_uid && has_gid); + + if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { + if (!store_client_to_sec_client_mapping(_client, _sec_client)) { + std::string security_mode_text = "!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client + << " with UID/GID=" << std::dec << its_uid << "/" << its_gid + << " : Check credentials failed as existing credentials would be overwritten" + << security_mode_text; + return !check_credentials_; + } + store_sec_client_to_client_mapping(_sec_client, _client); + return true; + } + } + + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client + << " with UID/GID=" << std::dec << its_uid << "/" << its_gid + << " : Check credentials failed" << security_mode_text; + + return !check_credentials_; +#endif // VSOMEIP_DISABLE_SECURITY +} + +bool +policy_manager_impl::check_routing_credentials( + const vsomeip_sec_client_t *_sec_client) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + + return (true); +#else + uid_t its_uid(0); + gid_t its_gid(0); + bool is_known_uid_gid(false); + + std::lock_guard its_lock(routing_credentials_mutex_); + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + + if (routing_credentials_.first == its_uid + && routing_credentials_.second == its_gid) { + + return (true); + } + + is_known_uid_gid = true; + } + + std::string security_mode_text = "!"; + if (!check_routing_credentials_) { + + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << (is_known_uid_gid ? std::to_string(its_uid) : "n/a") + << "." + << (is_known_uid_gid ? std::to_string(its_gid) : "n/a") + << " : Check routing credentials failed as " + << "configured routing manager credentials " + << "do not match with routing manager credentials" + << security_mode_text; + + return (!check_routing_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +void +policy_manager_impl::set_routing_credentials(uint32_t _uid, uint32_t _gid, + const std::string &_name) { + + if (is_configured_) { + VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." + << " Ignoring definition from " << _name; + } else { + routing_credentials_ = std::make_pair(_uid, _gid); + is_configured_ = true; + } +} + +bool +policy_manager_impl::is_client_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, method_t _method, + bool _is_request_service) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + (void)_service; + (void)_instance; + (void)_method; + (void)_is_request_service; + + return (true); +#else + if (!policy_enabled_) { + return true; + } + + uid_t its_uid(ANY_UID); + gid_t its_gid(ANY_GID); + if (_sec_client) { + if (_sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } else { + return true; + } + } else { + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: uid/gid " + << std::dec << its_uid << "/" << its_gid << " is not valid." + << "Therefore it isn't allowed to communicate to service/instance " + << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); + } + + // Check cache + auto its_credentials = std::make_pair(its_uid, its_gid); + auto its_key = std::make_tuple(_service, _instance, _method); + { + boost::shared_lock its_cache_lock(is_client_allowed_cache_mutex_); + const auto its_iter = is_client_allowed_cache_.find(its_credentials); + if (its_iter != is_client_allowed_cache_.end()) { + if (its_iter->second.find(its_key) != its_iter->second.end()) { + return (true); + } + } + } + + + // Check policies + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + std::lock_guard its_policy_lock(p->mutex_); + bool has_uid, has_gid(false); + bool is_matching(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + const auto found_service = p->requests_.find(_service); + if (found_service != p->requests_.end()) { + const auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + if (!_is_request_service) { + const auto found_method = found_instance->second.find(_method); + is_matching = (found_method != found_instance->second.end()); + } else { + // handle VSOMEIP_REQUEST_SERVICE + is_matching = true; + } + } + } + + if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { + if (p->allow_what_) { + // allow policy + if (is_matching) { + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_[its_credentials].insert(its_key); + return (true); + } + } else { + // deny policy + // allow client if the service / instance / !ANY_METHOD was not found + if ((!is_matching && (_method != ANY_METHOD)) + // allow client if the service / instance / ANY_METHOD was not found + // and it is a "deny nothing" policy + || (!is_matching && (_method == ANY_METHOD) && p->requests_.empty())) { + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_[its_credentials].insert(its_key); + return (true); + } + } + } + } + + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << std::dec << its_uid << "/" << its_gid + << " : Isn't allowed to communicate with service/instance/(method / event) " + << std::hex << _service << "/" << _instance << "/" << _method + << security_mode_text; + + return (!check_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +bool +policy_manager_impl::is_offer_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + (void)_service; + (void)_instance; + + return (true); +#else + if (!policy_enabled_) + return true; + + uint32_t its_uid(ANY_UID), its_gid(ANY_GID); + if (_sec_client) { + if (_sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } else { + return true; + } + } else { + std::string security_mode_text = " ~> Skip offer!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: uid/gid " + << std::dec << its_uid << "/" << its_gid << " is not valid." + << "Therefore it isn't allowed to offer service/instance " + << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); + } + + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + std::lock_guard its_policy_lock(p->mutex_); + bool has_uid, has_gid(false), has_offer(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + const auto found_service = p->offers_.find(_service); + if (found_service != p->offers_.end()) { + const auto found_instance = found_service->second.find(_instance); + has_offer = (found_instance != found_service->second.end()); + } + + if ((has_uid && has_gid && p->allow_who_) + || ((!has_uid || !has_gid) && !p->allow_who_)) { + if (p->allow_what_ == has_offer) { + return (true); + } + } + } + + std::string security_mode_text = " ~> Skip offer!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << std::dec << its_uid << "/" << its_gid + << " isn't allowed to offer service/instance " + << std::hex << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +#ifndef VSOMEIP_DISABLE_SECURITY +void +policy_manager_impl::load(const configuration_element &_element, const bool _lazy_load) { + + load_policies(_element); + if (!_lazy_load) { + + load_security_update_whitelist(_element); + load_security_policy_extensions(_element); + load_routing_credentials(_element); + + if (policy_enabled_ && check_credentials_) + VSOMEIP_INFO << "Security configuration is active."; + + if (policy_enabled_ && !check_credentials_) + VSOMEIP_INFO << "Security configuration is active but in audit mode (allow all)"; + } +} + +bool +policy_manager_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { + boost::unique_lock its_lock(any_client_policies_mutex_); + bool was_removed(false); + if (!any_client_policies_.empty()) { + std::vector>::iterator p_it = any_client_policies_.begin(); + while (p_it != any_client_policies_.end()) { + bool is_matching(false); + { + std::lock_guard its_policy_lock((*p_it)->mutex_); + bool has_uid(false), has_gid(false); + const auto found_uid = (*p_it)->credentials_.find(_uid); + has_uid = (found_uid != (*p_it)->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + // only remove "credentials allow" policies to prevent removal of + // blacklist configured in file + if (has_uid && has_gid && (*p_it)->allow_who_) { + is_matching = true; + } + } + if (is_matching) { + was_removed = true; + p_it = any_client_policies_.erase(p_it); + } else { + ++p_it; + } + + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_.erase(std::make_pair(_uid, _gid)); + } + } + return (was_removed); +} + +void +policy_manager_impl::update_security_policy(uint32_t _uid, uint32_t _gid, + const std::shared_ptr &_policy) { + + boost::unique_lock its_lock(any_client_policies_mutex_); + std::shared_ptr its_matching_policy; + for (auto p : any_client_policies_) { + std::lock_guard its_guard(p->mutex_); + if (p->credentials_.size() == 1) { + const auto its_uids = *(p->credentials_.begin()); + if (its_uids.first.lower() == _uid + && its_uids.first.upper() == _uid) { + if (its_uids.second.size() == 1) { + const auto its_gids = *(its_uids.second.begin()); + if (its_gids.lower() == _gid + && its_gids.upper() == _gid) { + if (p->allow_who_ == _policy->allow_who_) { + its_matching_policy = p; + break; + } + } + } + } + } + } + + if (its_matching_policy) { + std::lock_guard its_guard{its_matching_policy->mutex_}; + for (const auto &r : _policy->requests_) { + service_t its_lower, its_upper; + get_bounds(r.first, its_lower, its_upper); + for (auto s = its_lower; s <= its_upper; s++) { + boost::icl::discrete_interval its_service(s, s, + boost::icl::interval_bounds::closed()); + its_matching_policy->requests_ += std::make_pair(its_service, r.second); + } + } + for (const auto &o : _policy->offers_) { + service_t its_lower, its_upper; + get_bounds(o.first, its_lower, its_upper); + for (auto s = its_lower; s <= its_upper; s++) { + boost::icl::discrete_interval its_service(s, s, + boost::icl::interval_bounds::closed()); + its_matching_policy->offers_ += std::make_pair(its_service, o.second); + } + } + } else { + any_client_policies_.push_back(_policy); + } + + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_.erase(std::make_pair(_uid, _gid)); +} + +void +policy_manager_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, + const std::shared_ptr &_policy, client_t _client) { + + bool was_found(false); + boost::unique_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + bool has_uid(false), has_gid(false); + + std::lock_guard its_policy_lock(p->mutex_); + const auto found_uid = p->credentials_.find(_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + if (has_uid && has_gid && p->allow_who_) { + was_found = true; + break; + } + } + + // Do not add the new (credentials-only-policy) if a allow + // credentials policy with same credentials was found + if (!was_found) { + any_client_policies_.push_back(_policy); + VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" + << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; + } +} + +bool +policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { + + bool is_uid_allowed(false); + { + std::lock_guard its_lock(uid_whitelist_mutex_); + const auto found_uid = uid_whitelist_.find(_uid); + is_uid_allowed = (found_uid != uid_whitelist_.end()); + } + + if (is_uid_allowed && _policy) { + std::lock_guard its_lock(service_interface_whitelist_mutex_); + std::lock_guard its_policy_lock(_policy->mutex_); + for (const auto &its_request : _policy->requests_) { + bool has_service(false); + + service_t its_service(0); + for (its_service = its_request.first.lower(); + its_service <= its_request.first.upper(); + its_service++) { + + const auto found_service = service_interface_whitelist_.find(its_service); + has_service = (found_service != service_interface_whitelist_.end()); + if (!has_service) + break; + } + + if (!has_service) { + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: " + << std::hex << its_service + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: " + << std::hex << its_service + << " is not allowed! -> ignore update"; + } + return (!check_whitelist_); + } + } + return (true); + } else { + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid + << " is not allowed! -> ignore update"; + } + return (!check_whitelist_); + } +} + +bool +policy_manager_impl::is_policy_removal_allowed(uint32_t _uid) const { + std::lock_guard its_lock(uid_whitelist_mutex_); + for (auto its_uid_range : uid_whitelist_) { + if (its_uid_range.lower() <= _uid && _uid <= its_uid_range.upper()) { + return (true); + } + } + + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " + << std::dec << _uid + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " + << std::dec << _uid + << " is not allowed! -> ignore removal"; + } + return (!check_whitelist_); +} + +bool +policy_manager_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, + uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { + + bool is_valid = _policy->deserialize(_buffer, _buffer_size); + if (is_valid) + is_valid = _policy->get_uid_gid(_uid, _gid); + return is_valid; +} + +/////////////////////////////////////////////////////////////////////////////// +// Configuration +/////////////////////////////////////////////////////////////////////////////// +void +policy_manager_impl::load_policies(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("security"); + if (!optional) { + return; + } + policy_enabled_ = true; + auto found_policy = _element.tree_.get_child("security"); + for (auto its_security = found_policy.begin(); + its_security != found_policy.end(); ++its_security) { + if (its_security->first == "check_credentials") { + if (its_security->second.data() == "true") { + check_credentials_ = true; + } else { + check_credentials_ = false; + } + } else if (its_security->first == "allow_remote_clients") { + if (its_security->second.data() == "true") { + allow_remote_clients_ = true; + } else { + allow_remote_clients_ = false; + } + } else if (its_security->first == "policies") { + for (auto its_policy = its_security->second.begin(); + its_policy != its_security->second.end(); ++its_policy) { + load_policy(its_policy->second); + } + } + } + } catch (...) { + } +} + +void +policy_manager_impl::load_policy(const boost::property_tree::ptree &_tree) { + + std::shared_ptr policy(std::make_shared()); + bool allow_deny_set(false); + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + if (i->first == "credentials") { + boost::icl::interval_set its_uid_interval_set; + boost::icl::interval_set its_gid_interval_set; + boost::icl::discrete_interval its_uid_interval; + boost::icl::discrete_interval its_gid_interval; + + bool has_uid(false), has_gid(false); + bool has_uid_range(false), has_gid_range(false); + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + std::string its_key(n->first); + std::string its_value(n->second.data()); + if (its_key == "uid") { + if(n->second.data().empty()) { + load_interval_set(n->second, its_uid_interval_set); + has_uid_range = true; + } else { + if (its_value != "any") { + uint32_t its_uid; + read_data(its_value, its_uid); + its_uid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + its_uid, its_uid, + boost::icl::interval_bounds::closed()); + } else { + its_uid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + std::numeric_limits::min(), + std::numeric_limits::max(), + boost::icl::interval_bounds::closed()); + } + has_uid = true; + } + } else if (its_key == "gid") { + if(n->second.data().empty()) { + load_interval_set(n->second, its_gid_interval_set); + has_gid_range = true; + } else { + if (its_value != "any") { + uint32_t its_gid; + read_data(its_value, its_gid); + its_gid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + its_gid, its_gid, + boost::icl::interval_bounds::closed()); + } else { + its_gid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + std::numeric_limits::min(), + std::numeric_limits::max(), + boost::icl::interval_bounds::closed()); + } + has_gid = true; + } + } else if (its_key == "allow" || its_key == "deny") { + policy->allow_who_ = (its_key == "allow"); + load_credential(n->second, policy->credentials_); + } + } + + if (has_uid && has_gid) { + its_gid_interval_set.insert(its_gid_interval); + + policy->credentials_ += std::make_pair(its_uid_interval, its_gid_interval_set); + policy->allow_who_ = true; + } + if (has_uid_range && has_gid_range) { + for (const auto u : its_uid_interval_set) + policy->credentials_ += std::make_pair(u, its_gid_interval_set); + policy->allow_who_ = true; + } + } else if (i->first == "allow") { + if (allow_deny_set) { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides " + << "already set \"deny\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_what_ = true; + load_policy_body(policy, i); + } else if (i->first == "deny") { + if (allow_deny_set) { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides " + << "already set \"allow\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_what_ = false; + load_policy_body(policy, i); + } + } + boost::unique_lock its_lock(any_client_policies_mutex_); + any_client_policies_.push_back(policy); +} + +void +policy_manager_impl::load_policy_body(std::shared_ptr &_policy, + const boost::property_tree::ptree::const_iterator &_tree) { + + for (auto l = _tree->second.begin(); l != _tree->second.end(); ++l) { + if (l->first == "requests") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t its_service = 0x0; + instance_t its_instance = 0x0; + boost::icl::interval_map > its_instance_method_intervals; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + if (k->first == "service") { + read_data(k->second.data(), its_service); + } else if (k->first == "instance") { // legacy definition for instances + boost::icl::interval_set its_instance_interval_set; + boost::icl::interval_set its_method_interval_set; + boost::icl::discrete_interval all_instances(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + + std::string its_value(k->second.data()); + if (its_value != "any") { + read_data(its_value, its_instance); + if (its_instance != 0x0) { + its_instance_interval_set.insert(its_instance); + its_method_interval_set.insert(all_methods); + } + } else { + its_instance_interval_set.insert(all_instances); + its_method_interval_set.insert(all_methods); + } + for (const auto i : its_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_method_interval_set); + } + } else if (k->first == "instances") { // new instances definition + for (auto p = k->second.begin(); p != k->second.end(); ++p) { + boost::icl::interval_set its_instance_interval_set; + boost::icl::interval_set its_method_interval_set; + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + for (auto m = p->second.begin(); m != p->second.end(); ++m) { + if (m->first == "ids") { + load_interval_set(m->second, its_instance_interval_set); + } else if (m->first == "methods") { + load_interval_set(m->second, its_method_interval_set); + } + } + if (its_method_interval_set.empty()) + its_method_interval_set.insert(all_methods); + for (const auto i : its_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_method_interval_set); + } + } + + if (its_instance_method_intervals.empty()) { + boost::icl::interval_set its_legacy_instance_interval_set; + boost::icl::interval_set its_legacy_method_interval_set; + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + its_legacy_method_interval_set.insert(all_methods); + + // try to only load instance ranges with any method to be allowed + load_interval_set(k->second, its_legacy_instance_interval_set); + for (const auto i : its_legacy_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_legacy_method_interval_set); + } + } + } + } + if (its_service != 0x0 && !its_instance_method_intervals.empty()) { + _policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + its_service, its_service, + boost::icl::interval_bounds::closed()), + its_instance_method_intervals); + } + } + } else if (l->first == "offers") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t its_service(0x0); + instance_t its_instance(0x0); + boost::icl::interval_set its_instance_interval_set; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + if (k->first == "service") { + read_data(k->second.data(), its_service); + } else if (k->first == "instance") { // legacy definition for instances + std::string its_value(k->second.data()); + if (its_value != "any") { + read_data(its_value, its_instance); + if (its_instance != 0x0) { + its_instance_interval_set.insert(its_instance); + } + } else { + its_instance_interval_set.insert( + boost::icl::discrete_interval( + 0x0001, 0xFFFF)); + } + } else if (k->first == "instances") { // new instances definition + load_interval_set(k->second, its_instance_interval_set); + } + } + if (its_service != 0x0 && !its_instance_interval_set.empty()) { + _policy->offers_ + += std::make_pair( + boost::icl::discrete_interval( + its_service, its_service, + boost::icl::interval_bounds::closed()), + its_instance_interval_set); + } + } + } + } +} + + +void +policy_manager_impl::load_credential( + const boost::property_tree::ptree &_tree, + boost::icl::interval_map > &_credentials) { + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + boost::icl::interval_set its_uid_interval_set; + boost::icl::interval_set its_gid_interval_set; + + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + std::string its_key(j->first); + if (its_key == "uid") { + load_interval_set(j->second, its_uid_interval_set); + } else if (its_key == "gid") { + load_interval_set(j->second, its_gid_interval_set); + } else { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " + << "Malformed credential (contains illegal key \"" + << its_key << "\")"; + } + } + + for (const auto its_uid_interval : its_uid_interval_set) { + _credentials + += std::make_pair(its_uid_interval, its_gid_interval_set); + } + } +} + +bool +policy_manager_impl::load_routing_credentials(const configuration_element &_element) { + try { + auto its_routing_cred = _element.tree_.get_child("routing-credentials"); + if (is_configured_) { + VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." + << " Ignoring definition from " << _element.name_; + } else { + for (auto i = its_routing_cred.begin(); + i != its_routing_cred.end(); + ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if (its_key == "uid") { + uint32_t its_uid(0); + read_data(its_value, its_uid); + std::lock_guard its_lock(routing_credentials_mutex_); + std::get<0>(routing_credentials_) = its_uid; + } else if (its_key == "gid") { + uint32_t its_gid(0); + read_data(its_value, its_gid); + std::lock_guard its_lock(routing_credentials_mutex_); + std::get<1>(routing_credentials_) = its_gid; + } + } + check_routing_credentials_ = true; + is_configured_ = true; + } + } catch (...) { + return false; + } + return true; +} + + +void +policy_manager_impl::load_security_update_whitelist(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("security-update-whitelist"); + if (!optional) { + return; + } + auto found_whitelist = _element.tree_.get_child("security-update-whitelist"); + for (auto its_whitelist = found_whitelist.begin(); + its_whitelist != found_whitelist.end(); ++its_whitelist) { + + if (its_whitelist->first == "uids") { + { + std::lock_guard its_lock(uid_whitelist_mutex_); + load_interval_set(its_whitelist->second, uid_whitelist_); + } + } else if (its_whitelist->first == "services") { + { + std::lock_guard its_lock(service_interface_whitelist_mutex_); + load_interval_set(its_whitelist->second, service_interface_whitelist_); + } + } else if (its_whitelist->first == "check-whitelist") { + if (its_whitelist->second.data() == "true") { + check_whitelist_ = true; + } else { + check_whitelist_ = false; + } + } + } + } catch (...) { + } +} + +void +policy_manager_impl::load_security_policy_extensions(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("container_policy_extensions"); + if (!optional) { + return; + } + auto found_policy_extensions = _element.tree_.get_child("container_policy_extensions"); + boost::filesystem::path its_base_path; + { + boost::unique_lock its_lock(policy_extension_paths_mutex_); + its_base_path = boost::filesystem::path(policy_base_path_); + } + + for (auto i = found_policy_extensions.begin(); + i != found_policy_extensions.end(); ++i) { + boost::filesystem::path its_canonical_path; + std::string its_client_host(""); + std::string its_path(""); + auto its_data = i->second; + for (auto j = its_data.begin(); j != its_data.end(); ++j) { + std::string its_key(j->first); + std::string its_value(j->second.data()); + if (its_key == "container") { + if(its_value != "") { + its_client_host = its_value; + } + } else if (its_key == "path") { + if(its_value != "") { + its_path = its_value; + } + } + } + + std::string str = VSOMEIP_DEFAULT_CONFIGURATION_FOLDER; + std::string its_filesystem_path = str.substr(0, str.find_last_of("\\/")) + + its_path.erase(0, its_path.find_first_of("\\/")); + + if (!utility::is_folder(its_filesystem_path)) { + VSOMEIP_DEBUG << __func__ << ": The path " + << its_filesystem_path + << " is not valid"; + } + std::map empty_map; + policy_extension_paths_[its_client_host] = std::make_pair(its_filesystem_path, empty_map); + + VSOMEIP_INFO << __func__ << ": Insert policy extension path: [" << its_filesystem_path + << "] for hostname: [" << its_client_host << "]"; + } + } catch (...) { + } +} + +template +void policy_manager_impl::load_interval_set( + const boost::property_tree::ptree &_tree, + boost::icl::interval_set &_intervals, bool _exclude_margins) { + + boost::icl::interval_set its_intervals; + T_ its_min = std::numeric_limits::min(); + T_ its_max = std::numeric_limits::max(); + + if (_exclude_margins) { + its_min++; + its_max--; + } + + const std::string its_key(_tree.data()); + if (its_key == "any") { + its_intervals.insert(boost::icl::discrete_interval::closed( + its_min, its_max)); + } else { + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + auto its_data = i->second; + if (!its_data.data().empty()) { + T_ its_id; + read_data(its_data.data(), its_id); + if (its_id >= its_min && its_id <= its_max) + its_intervals.insert(its_id); + } else { + T_ its_first, its_last; + bool has_first(false), has_last(false); + for (auto j = its_data.begin(); j != its_data.end(); ++j) { + std::string its_key(j->first); + std::string its_value(j->second.data()); + if (its_key == "first") { + if (its_value == "min") { + its_first = its_min; + } else { + read_data(its_value, its_first); + } + has_first = true; + } else if (its_key == "last") { + if (its_value == "max") { + its_last = its_max; + } else { + read_data(its_value, its_last); + } + has_last = true; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " + << " Malformed range. Contains illegal key (" + << its_key << ")"; + } + } + if (has_first && has_last && its_first <= its_last) { + its_intervals.insert( + boost::icl::discrete_interval::closed(its_first, its_last)); + } + } + } + } + + _intervals = its_intervals; +} + +void +policy_manager_impl::get_requester_policies(const std::shared_ptr _policy, + std::set > &_requesters) const { + + std::lock_guard its_lock(_policy->mutex_); + for (const auto &o : _policy->offers_) { + boost::unique_lock its_policies_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + if (p == _policy) + continue; + + std::lock_guard its_lock(p->mutex_); + + auto its_policy = std::make_shared(); + its_policy->credentials_ = p->credentials_; + + for (const auto &r : p->requests_) { + // o represents an offer by a service interval and its instances + // (a set of intervals) + // r represents a request by a service interval and its instances + // and methods (instance intervals mapped to interval sets of methods) + // + // Thus, r matches o if their service identifiers as well as their + // instances overlap. If r and o match, a new policy must be + // created that contains the overlapping services/instances mapping + // of r and o together with the methods from r + service_t its_o_lower, its_o_upper, its_r_lower, its_r_upper; + get_bounds(o.first, its_o_lower, its_o_upper); + get_bounds(r.first, its_r_lower, its_r_upper); + + if (its_o_lower <= its_r_upper && its_r_lower <= its_o_upper) { + auto its_service_min = std::max(its_o_lower, its_r_lower); + auto its_service_max = std::min(its_r_upper, its_o_upper); + + for (const auto &i : o.second) { + for (const auto &j : r.second) { + for (const auto &k : j.second) { + instance_t its_i_lower, its_i_upper, its_k_lower, its_k_upper; + get_bounds(i, its_i_lower, its_i_upper); + get_bounds(k, its_k_lower, its_k_upper); + + if (its_i_lower <= its_k_upper && its_k_lower <= its_i_upper) { + auto its_instance_min = std::max(its_i_lower, its_k_lower); + auto its_instance_max = std::min(its_i_upper, its_k_upper); + + boost::icl::interval_map > its_instances_methods; + its_instances_methods += std::make_pair( + boost::icl::interval::closed( + its_instance_min, its_instance_max), + j.second); + + its_policy->requests_ += std::make_pair( + boost::icl::interval::closed( + its_service_min, its_service_max), + its_instances_methods); + } + } + } + } + } + } + + if (!its_policy->requests_.empty()) { + _requesters.insert(its_policy); + its_policy->print(); + } + } + } +} + +void +policy_manager_impl::get_clients(uid_t _uid, gid_t _gid, + std::unordered_set &_clients) const { + + std::lock_guard its_lock(ids_mutex_); + for (const auto &i : ids_) { + if (i.second.client_type == VSOMEIP_CLIENT_UDS + && i.second.client.uds_client.user == _uid + && i.second.client.uds_client.group == _gid) + _clients.insert(i.first); + } +} + +bool +policy_manager_impl::is_policy_extension(const std::string &_path) const { + auto its_pos = _path.find("vsomeip_policy_extensions.json"); + if (its_pos != std::string::npos) { + return true; + } + return false; +} + +void +policy_manager_impl::set_policy_extension_base_path(const std::string &_path) { + auto its_pos = _path.find("vsomeip_policy_extensions.json"); + std::lock_guard its_lock(policy_base_path_mutex_); + policy_base_path_ = _path.substr(0, its_pos); +} + +std::string +policy_manager_impl::get_policy_extension_path(const std::string &_client_host) const { + boost::shared_lock lock(policy_extension_paths_mutex_); + return get_policy_extension_path_unlocked(_client_host); +} +//only be called after loading of the mutex +std::string +policy_manager_impl::get_policy_extension_path_unlocked(const std::string &_client_host) const { + std::string its_path(""); + + auto found_host = policy_extension_paths_.find(_client_host); + + if (found_host != policy_extension_paths_.end()) { + its_path = found_host->second.first; + } + return its_path; +} + +policy_manager_impl::policy_loaded_e +policy_manager_impl::is_policy_extension_loaded(const std::string &_client_host) const { + boost::shared_lock lock(policy_extension_paths_mutex_); + + auto found_host = policy_extension_paths_.find(_client_host); + if (found_host != policy_extension_paths_.end()) { + + auto found_complete_path = found_host->second.second.find( + get_security_config_folder(found_host->second.first)); + if (found_complete_path != found_host->second.second.end()) { + if (found_complete_path->second) { + return policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_LOADED; + } else { + return policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED; + } + } + } + + // we do not have a path to load + return policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT; +} + +void +policy_manager_impl::set_is_policy_extension_loaded(const std::string &_client_host, + const bool _loaded) { + boost::unique_lock lock(policy_extension_paths_mutex_); + auto found_host = policy_extension_paths_.find(_client_host); + + if (found_host != policy_extension_paths_.end()) { + std::string its_folder = get_policy_extension_path_unlocked(_client_host); + std::string its_complete_folder = get_security_config_folder(its_folder); + + // if the map key of complete path folder exist, will be updated + // if not will create an new entry + found_host->second.second[its_complete_folder] = _loaded; + } +} + +std::string +policy_manager_impl::get_security_config_folder(const std::string &its_folder) const +{ + std::stringstream its_security_config_folder; + its_security_config_folder << its_folder; + +#if defined(__linux__) || defined(ANDROID) + its_security_config_folder << "/" << getuid() << "_" << getgid(); +#endif + + if (utility::is_folder(its_security_config_folder.str())) { + return its_security_config_folder.str(); + } else { + VSOMEIP_INFO << __func__<< ": Invalid folder for " << its_security_config_folder.str(); + } + return std::string(""); } std::shared_ptr @@ -33,29 +1299,175 @@ policy_manager_impl::parse_uid_gid(const byte_t* &_buffer, && its_policy->deserialize_uid_gid(_buffer, _buffer_size, _uid, _gid)); } +#endif // !VSOMEIP_DISABLE_SECURITY + bool -policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { +policy_manager_impl::store_client_to_sec_client_mapping( + client_t _client, const vsomeip_sec_client_t *_sec_client) { + + if (_sec_client != nullptr && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // store the client -> sec_client mapping + std::lock_guard its_lock(ids_mutex_); + auto found_client = ids_.find(_client); + if (found_client != ids_.end()) { + if (!utility::compare(found_client->second, *_sec_client)) { + uid_t its_old_uid = found_client->second.client.uds_client.user; + gid_t its_old_gid = found_client->second.client.uds_client.group; + uid_t its_new_uid = _sec_client->client.uds_client.user; + gid_t its_new_gid = _sec_client->client.uds_client.group; + + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << _client << " with UID/GID=" + << std::dec << its_new_uid << "/" << its_new_gid + << " : Overwriting existing credentials UID/GID=" + << std::dec << its_old_uid << "/" << its_old_gid; - auto its_security = security_impl::get(); - return (its_security - && its_security->is_policy_update_allowed(_uid, _policy)); + found_client->second = *_sec_client; + return (true); + } + } else { + ids_[_client] = *_sec_client; + } + return (true); + } + + return (false); } bool -policy_manager_impl::is_policy_removal_allowed(uint32_t _uid) const { +policy_manager_impl::get_client_to_sec_client_mapping(client_t _client, + vsomeip_sec_client_t &_sec_client) { + { + // get the UID / GID of the client + std::lock_guard its_lock(ids_mutex_); + if (ids_.find(_client) != ids_.end()) { + _sec_client = ids_[_client]; + return (true); + } + return (false); + } +} - auto its_security = security_impl::get(); - return (its_security - && its_security->is_policy_removal_allowed(_uid)); +bool +policy_manager_impl::remove_client_to_sec_client_mapping(client_t _client) { + + vsomeip_sec_client_t its_sec_client; + bool is_client_removed(false); + bool is_sec_client_removed(false); + { + std::lock_guard its_lock(ids_mutex_); + auto found_client = ids_.find(_client); + if (found_client != ids_.end()) { + its_sec_client = found_client->second; + ids_.erase(found_client); + is_client_removed = true; + } + } + { + std::lock_guard its_lock(sec_client_to_clients_mutex_); + if (is_client_removed) { + auto found_sec_client = sec_client_to_clients_.find(its_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + auto its_client = found_sec_client->second.find(_client); + if (its_client != found_sec_client->second.end()) { + found_sec_client->second.erase(its_client); + if (found_sec_client->second.empty()) { + sec_client_to_clients_.erase(found_sec_client); + } + is_sec_client_removed = true; + } + } + } else { + for (auto it = sec_client_to_clients_.begin(); + it != sec_client_to_clients_.end(); ++it) { + auto its_client = it->second.find(_client); + if (its_client != it->second.end()) { + it->second.erase(its_client); + if (it->second.empty()) { + sec_client_to_clients_.erase(it); + } + is_sec_client_removed = true; + break; + } + } + } + } + + return (is_client_removed && is_sec_client_removed); +} + +void +policy_manager_impl::store_sec_client_to_client_mapping( + const vsomeip_sec_client_t *_sec_client, client_t _client) { + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // store the uid gid to clients mapping + std::lock_guard its_lock(sec_client_to_clients_mutex_); + auto found_sec_client = sec_client_to_clients_.find(*_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + found_sec_client->second.insert(_client); + } else { + std::set mapped_clients; + mapped_clients.insert(_client); + sec_client_to_clients_.insert(std::make_pair(*_sec_client, mapped_clients)); + } + } } bool -policy_manager_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { +policy_manager_impl::get_sec_client_to_clients_mapping( + const vsomeip_sec_client_t *_sec_client, + std::set &_clients) { + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // get the clients corresponding to uid, gid + std::lock_guard its_lock(sec_client_to_clients_mutex_); + auto found_sec_client = sec_client_to_clients_.find(*_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + _clients = found_sec_client->second; + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Manage the security object +//////////////////////////////////////////////////////////////////////////////// +static std::shared_ptr *the_policy_manager_ptr__(nullptr); +static std::mutex the_policy_manager_mutex__; + +std::shared_ptr +policy_manager_impl::get() { +#if defined(__linux__) || defined(ANDROID) + std::lock_guard its_lock(the_policy_manager_mutex__); +#endif + if(the_policy_manager_ptr__ == nullptr) { + the_policy_manager_ptr__ = new std::shared_ptr(); + } + if (the_policy_manager_ptr__ != nullptr) { + if (!(*the_policy_manager_ptr__)) { + *the_policy_manager_ptr__ = std::make_shared(); + } + return (*the_policy_manager_ptr__); + } + return (nullptr); +} - auto its_security = security_impl::get(); - return (its_security - && its_security->parse_policy(_buffer, _buffer_size, _uid, _gid, _policy)); +#if defined(__linux__) || defined(ANDROID) +static void security_teardown(void) __attribute__((destructor)); +static void security_teardown(void) +{ + if (the_policy_manager_ptr__ != nullptr) { + // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. + // Since this function only runs on the main thread, no mutex should be needed. Leaving a + // comment pending a refactor. + // std::lock_guard its_lock(the_policy_manager_mutex__); + the_policy_manager_ptr__->reset(); + delete the_policy_manager_ptr__; + the_policy_manager_ptr__ = nullptr; + } } +#endif } // namespace vsomeip_v3 diff --git a/implementation/security/src/security.cpp b/implementation/security/src/security.cpp index 7c7b3f4c1..e9a6381c0 100644 --- a/implementation/security/src/security.cpp +++ b/implementation/security/src/security.cpp @@ -1,15 +1,145 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../include/security_impl.hpp" +#include "../include/security.hpp" +#include "../include/policy_manager_impl.hpp" +#include +#ifdef ANDROID +#include "../../configuration/include/internal_android.hpp" +#else +#include "../../configuration/include/internal.hpp" +#endif +#include "../../plugin/include/plugin_manager.hpp" + +#include +#include + +#define VSOMEIP_SEC_SYMDEF(sym) symdef_t{\ + "vsomeip_sec_policy_"#sym, nullptr, reinterpret_cast(&sym) \ +} namespace vsomeip_v3 { +bool +security::load() { + using symdef_t = std::tuple; + std::array symbol_table{ + VSOMEIP_SEC_SYMDEF(initialize), + VSOMEIP_SEC_SYMDEF(authenticate_router), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_offer), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_request), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_access_member) + }; + + if (auto manager = plugin_manager::get()) { + if (auto lib = manager->load_library(VSOMEIP_SEC_LIBRARY)) { + // First we load the symbols into the 2nd tuple element + for (auto& symdef : symbol_table) { + auto name = std::get<0>(symdef); + auto& symbol = std::get<1>(symdef); + if (!(symbol = manager->load_symbol(lib, name))) { + VSOMEIP_ERROR << __func__ + << ": security library misses " + << std::quoted(name) + << " function."; + manager->unload_library(lib); + return false; + } + } + + // Now that we have all symbols loaded, + // assign the 2nd tuple element to the 3rd + for (auto& symdef : symbol_table) { + auto symbol = std::get<1>(symdef); + auto& stub = std::get<2>(symdef); + *stub = symbol; + } + + // Symbol loading complete, success! + return true; + } + } + + return false; +} + +decltype(security::initialize) +security::initialize = security::default_initialize; + +decltype(security::authenticate_router) +security::authenticate_router = security::default_authenticate_router; + +decltype(security::is_client_allowed_to_offer) +security::is_client_allowed_to_offer = security::default_is_client_allowed_to_offer; + +decltype(security::is_client_allowed_to_request) +security::is_client_allowed_to_request = security::default_is_client_allowed_to_request; + +decltype(security::is_client_allowed_to_access_member) +security::is_client_allowed_to_access_member = security::default_is_client_allowed_to_access_member; + +// +// Default interface implementation +// +vsomeip_sec_policy_result_t +security::default_initialize(void) { + return VSOMEIP_SEC_POLICY_OK; +} + +vsomeip_sec_acl_result_t +security::default_authenticate_router( + const vsomeip_sec_client_t *_server) { + if (_server && _server->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->check_routing_credentials(_server)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_offer( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->is_offer_allowed(_client, _service, _instance)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_request( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, 0x00, true)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_access_member( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance, + vsomeip_sec_member_id_t _member) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; -std::shared_ptr -security::get() { - return security_impl::get(); + if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, _member, false)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; } } // namespace vsomeip_v3 diff --git a/implementation/security/src/security_impl.cpp b/implementation/security/src/security_impl.cpp deleted file mode 100644 index 377e310ae..000000000 --- a/implementation/security/src/security_impl.cpp +++ /dev/null @@ -1,1196 +0,0 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #define NOMINMAX - #include - #include -#endif - -#include - -#include -#include "../include/security_impl.hpp" -#include "../../configuration/include/configuration_element.hpp" -#ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" -#else -#include "../../configuration/include/internal.hpp" -#endif // ANDROID - -namespace vsomeip_v3 { - -template -void read_data(const std::string &_in, T_ &_out) { - std::stringstream its_converter; - - if (_in.size() > 2 - && _in[0] == '0' - && (_in[1] == 'x' || _in[1] == 'X')) - its_converter << std::hex << _in; - else - its_converter << std::dec << _in; - - its_converter >> _out; -} - -security_impl::security_impl() - : policy_enabled_(false), - check_credentials_(false), - check_routing_credentials_(false), - allow_remote_clients_(true), - check_whitelist_(false), - is_configured_(false) { -} - -void -security_impl::load(const configuration_element &_element) { - load_policies(_element); - load_security_update_whitelist(_element); - load_routing_credentials(_element); - - if (policy_enabled_ && check_credentials_) - VSOMEIP_INFO << "Security configuration is active."; - - if (policy_enabled_ && !check_credentials_) - VSOMEIP_INFO << "Security configuration is active but in audit mode (allow all)"; -} - -bool -security_impl::is_enabled() const { - return policy_enabled_; -} - -bool -security_impl::is_audit() const { - return check_credentials_; -} - -bool -security_impl::check_credentials(client_t _client, - uid_t _uid, gid_t _gid) { - - if (!policy_enabled_) { - return true; - } - - std::vector > its_policies; - bool has_id(false); - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - - bool has_uid, has_gid(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - has_id = (has_uid && has_gid); - - if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { - if (!store_client_to_uid_gid_mapping(_client,_uid, _gid)) { - std::string security_mode_text = "!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed as existing credentials would be overwritten" - << security_mode_text; - return !check_credentials_; - } - store_uid_gid_to_client_mapping(_uid, _gid, _client); - return true; - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed" << security_mode_text; - - return !check_credentials_; -} - -bool -security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service) const { - - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(ANY_UID), its_gid(ANY_GID); - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - if (_uid != ANY_UID && _gid != ANY_GID) { - its_uid = _uid; - its_gid = _gid; - } else { - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: uid/gid " << std::dec << _uid << "/" << _gid - << " for client 0x" << std::hex << _client << " is not valid" - << ". Therefore it isn't allowed to communicate to service/instance " - << _service << "/" << _instance - << security_mode_text; - - return !check_credentials_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - - bool has_uid, has_gid(false); - bool is_matching(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - const auto found_service = p->requests_.find(_service); - if (found_service != p->requests_.end()) { - const auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - if (!_is_request_service) { - const auto found_method = found_instance->second.find(_method); - is_matching = (found_method != found_instance->second.end()); - } else { - // handle VSOMEIP_REQUEST_SERVICE - is_matching = true; - } - } - } - - if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_) { - // allow policy - if (is_matching) { - return (true); - } - } else { - // deny policy - // allow client if the service / instance / !ANY_METHOD was not found - if ((!is_matching && (_method != ANY_METHOD)) - // allow client if the service / instance / ANY_METHOD was not found - // and it is a "deny nothing" policy - || (!is_matching && (_method == ANY_METHOD) && p->requests_.empty())) { - return (true); - } - } - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << its_uid << "/" << its_gid - << " : Isn't allowed to communicate with service/instance/(method / event) " << std::hex - << _service << "/" << _instance << "/" << _method - << security_mode_text; - - return (!check_credentials_); -} - -bool -security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, service_t _service, - instance_t _instance) const { - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(ANY_UID), its_gid(ANY_GID); - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - if (_uid != ANY_UID - && _gid != ANY_GID) { - its_uid = _uid; - its_gid = _gid; - } else { - std::string security_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: uid/gid " << std::dec << _uid << "/" << _gid - << " for client 0x" << std::hex << _client << " is not valid" - << ". Therefore it isn't allowed to offer service/instance " - << _service << "/" << _instance - << security_mode_text; - - return !check_credentials_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - bool has_uid, has_gid(false), has_offer(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - const auto found_service = p->offers_.find(_service); - if (found_service != p->offers_.end()) { - const auto found_instance = found_service->second.find(_instance); - has_offer = (found_instance != found_service->second.end()); - } - - if ((has_uid && has_gid && p->allow_who_) - || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_ == has_offer) { - return (true); - } - } - } - - std::string security_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" - << std::hex << _client - << " with UID/GID=" - << std::dec << its_uid << "/" << its_gid - << " isn't allowed to offer service/instance " - << std::hex << _service << "/" << _instance - << security_mode_text; - - return (!check_credentials_); -} - -bool -security_impl::store_client_to_uid_gid_mapping( - client_t _client, uint32_t _uid, uint32_t _gid) { - { - // store the client -> (uid, gid) mapping - std::lock_guard its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - if (found_client->second != std::make_pair(_uid, _gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" - << std::hex << _client << " with UID/GID=" - << std::dec << _uid << "/" << _gid << " : Overwriting existing credentials UID/GID=" - << std::dec << std::get<0>(found_client->second) << "/" - << std::get<1>(found_client->second); - found_client->second = std::make_pair(_uid, _gid); - return true; - } - } else { - ids_[_client] = std::make_pair(_uid, _gid); - } - return true; - } -} - -bool -security_impl::get_client_to_uid_gid_mapping(client_t _client, std::pair &_uid_gid) { - { - // get the UID / GID of the client - std::lock_guard its_lock(ids_mutex_); - if (ids_.find(_client) != ids_.end()) { - _uid_gid = ids_[_client]; - return true; - } - return false; - } -} - -bool -security_impl::remove_client_to_uid_gid_mapping(client_t _client) { - std::pair its_uid_gid; - bool client_removed(false); - bool uid_gid_removed(false); - { - std::lock_guard its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - its_uid_gid = found_client->second; - ids_.erase(found_client); - client_removed = true; - } - } - { - std::lock_guard its_lock(uid_to_clients_mutex_); - if (client_removed) { - auto found_uid_gid = uid_to_clients_.find(its_uid_gid); - if (found_uid_gid != uid_to_clients_.end()) { - auto its_client = found_uid_gid->second.find(_client); - if (its_client != found_uid_gid->second.end()) { - found_uid_gid->second.erase(its_client); - if (found_uid_gid->second.empty()) { - uid_to_clients_.erase(found_uid_gid); - } - uid_gid_removed = true; - } - } - } else { - for (auto its_uid_gid = uid_to_clients_.begin(); - its_uid_gid != uid_to_clients_.end(); ++its_uid_gid) { - auto its_client = its_uid_gid->second.find(_client); - if (its_client != its_uid_gid->second.end()) { - its_uid_gid->second.erase(its_client); - if (its_uid_gid->second.empty()) { - uid_to_clients_.erase(its_uid_gid); - } - uid_gid_removed = true; - break; - } - } - } - } - return (client_removed && uid_gid_removed); -} - -void -security_impl::store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, - client_t _client) { - { - // store the uid gid to clients mapping - std::lock_guard its_lock(uid_to_clients_mutex_); - std::set mapped_clients; - if (uid_to_clients_.find(std::make_pair(_uid, _gid)) != uid_to_clients_.end()) { - mapped_clients = uid_to_clients_[std::make_pair(_uid, _gid)]; - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } else { - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } - } -} - -bool -security_impl::get_uid_gid_to_client_mapping(std::pair _uid_gid, - std::set &_clients) { - { - // get the clients corresponding to uid, gid - std::lock_guard its_lock(uid_to_clients_mutex_); - if (uid_to_clients_.find(_uid_gid) != uid_to_clients_.end()) { - _clients = uid_to_clients_[_uid_gid]; - return true; - } - return false; - } -} - -bool -security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { - std::lock_guard its_lock(any_client_policies_mutex_); - bool was_removed(false); - if (!any_client_policies_.empty()) { - std::vector>::iterator p_it = any_client_policies_.begin(); - while (p_it != any_client_policies_.end()) { - bool is_matching(false); - { - std::lock_guard its_policy_lock((*p_it)->mutex_); - bool has_uid(false), has_gid(false); - const auto found_uid = (*p_it)->credentials_.find(_uid); - has_uid = (found_uid != (*p_it)->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - // only remove "credentials allow" policies to prevent removal of - // blacklist configured in file - if (has_uid && has_gid && (*p_it)->allow_who_) { - is_matching = true; - } - } - if (is_matching) { - was_removed = true; - p_it = any_client_policies_.erase(p_it); - } else { - ++p_it; - } - } - } - return (was_removed); -} - -void -security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, - const std::shared_ptr &_policy) { - - std::lock_guard its_lock(any_client_policies_mutex_); - std::shared_ptr its_matching_policy; - for (auto p : any_client_policies_) { - if (p->credentials_.size() == 1) { - const auto its_uids = *(p->credentials_.begin()); - if (its_uids.first.lower() == _uid - && its_uids.first.upper() == _uid) { - if (its_uids.second.size() == 1) { - const auto its_gids = *(its_uids.second.begin()); - if (its_gids.lower() == _gid - && its_gids.upper() == _gid) { - if (p->allow_who_ == _policy->allow_who_) { - its_matching_policy = p; - break; - } - } - } - } - } - } - - if (its_matching_policy) { - for (const auto &r : _policy->requests_) { - service_t its_lower, its_upper; - get_bounds(r.first, its_lower, its_upper); - for (auto s = its_lower; s <= its_upper; s++) { - boost::icl::discrete_interval its_service(s, s, - boost::icl::interval_bounds::closed()); - its_matching_policy->requests_ += std::make_pair(its_service, r.second); - } - } - for (const auto &o : _policy->offers_) { - service_t its_lower, its_upper; - get_bounds(o.first, its_lower, its_upper); - for (auto s = its_lower; s <= its_upper; s++) { - boost::icl::discrete_interval its_service(s, s, - boost::icl::interval_bounds::closed()); - its_matching_policy->offers_ += std::make_pair(its_service, o.second); - } - } - } else { - any_client_policies_.push_back(_policy); - } -} - -void -security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, - const std::shared_ptr &_policy, client_t _client) { - - bool was_found(false); - std::lock_guard its_lock(any_client_policies_mutex_); - for (const auto &p : any_client_policies_) { - bool has_uid(false), has_gid(false); - - std::lock_guard its_policy_lock(p->mutex_); - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - if (has_uid && has_gid && p->allow_who_) { - was_found = true; - break; - } - } - - // Do not add the new (credentials-only-policy) if a allow - // credentials policy with same credentials was found - if (!was_found) { - any_client_policies_.push_back(_policy); - VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" - << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; - } -} - -bool -security_impl::is_remote_client_allowed() const { - if (!check_credentials_) { - return true; - } - return allow_remote_clients_; -} - -bool -security_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { - - bool is_uid_allowed(false); - { - std::lock_guard its_lock(uid_whitelist_mutex_); - const auto found_uid = uid_whitelist_.find(_uid); - is_uid_allowed = (found_uid != uid_whitelist_.end()); - } - - if (is_uid_allowed) { - std::lock_guard its_lock(service_interface_whitelist_mutex_); - std::lock_guard its_policy_lock(_policy->mutex_); - for (auto its_request : _policy->requests_) { - bool has_service(false); - - service_t its_service(0); - for (its_service = its_request.first.lower(); - its_service <= its_request.first.upper(); - its_service++) { - - const auto found_service = service_interface_whitelist_.find(its_service); - has_service = (found_service != service_interface_whitelist_.end()); - if (!has_service) - break; - } - - if (!has_service) { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_service - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_service - << " is not allowed! -> ignore update"; - } - return (!check_whitelist_); - } - } - return (true); - } else { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed! -> ignore update"; - } - return (!check_whitelist_); - } -} - -bool -security_impl::is_policy_removal_allowed(uint32_t _uid) const { - std::lock_guard its_lock(uid_whitelist_mutex_); - for (auto its_uid_range : uid_whitelist_) { - if (its_uid_range.lower() <= _uid && _uid <= its_uid_range.upper()) { - return (true); - } - } - - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " - << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " - << std::dec << _uid - << " is not allowed! -> ignore removal"; - } - return (!check_whitelist_); -} - -bool -security_impl::check_routing_credentials(client_t _client, - uint32_t _uid, uint32_t _gid) const { - - std::lock_guard its_lock(routing_credentials_mutex_); - if (routing_credentials_.first == _uid - && routing_credentials_.second == _gid) { - - return (true); - } - - std::string security_mode_text = "!"; - if (!check_routing_credentials_) { - - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" - << std::hex << _client << " and UID/GID=" - << std::dec << _uid << "/" << _gid - << " : Check routing credentials failed as " - << "configured routing manager credentials " - << "do not match with routing manager credentials" - << security_mode_text; - - return (!check_routing_credentials_); -} - -bool -security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { - - bool is_valid = _policy->deserialize(_buffer, _buffer_size); - if (is_valid) - is_valid = _policy->get_uid_gid(_uid, _gid); - return is_valid; -} - -/////////////////////////////////////////////////////////////////////////////// -// Configuration -/////////////////////////////////////////////////////////////////////////////// -void -security_impl::load_policies(const configuration_element &_element) { -#ifdef _WIN32 - return; -#endif - try { - auto optional = _element.tree_.get_child_optional("security"); - if (!optional) { - return; - } - policy_enabled_ = true; - auto found_policy = _element.tree_.get_child("security"); - for (auto its_security = found_policy.begin(); - its_security != found_policy.end(); ++its_security) { - if (its_security->first == "check_credentials") { - if (its_security->second.data() == "true") { - check_credentials_ = true; - } else { - check_credentials_ = false; - } - } else if (its_security->first == "allow_remote_clients") { - if (its_security->second.data() == "true") { - allow_remote_clients_ = true; - } else { - allow_remote_clients_ = false; - } - } else if (its_security->first == "policies") { - for (auto its_policy = its_security->second.begin(); - its_policy != its_security->second.end(); ++its_policy) { - load_policy(its_policy->second); - } - } - } - } catch (...) { - } -} - -void -security_impl::load_policy(const boost::property_tree::ptree &_tree) { - - std::shared_ptr policy(std::make_shared()); - bool allow_deny_set(false); - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - if (i->first == "credentials") { - boost::icl::interval_set its_uid_interval_set; - boost::icl::interval_set its_gid_interval_set; - boost::icl::discrete_interval its_uid_interval; - boost::icl::discrete_interval its_gid_interval; - - bool has_uid(false), has_gid(false); - bool has_uid_range(false), has_gid_range(false); - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - std::string its_key(n->first); - std::string its_value(n->second.data()); - if (its_key == "uid") { - if(n->second.data().empty()) { - load_interval_set(n->second, its_uid_interval_set); - has_uid_range = true; - } else { - if (its_value != "any") { - uint32_t its_uid; - read_data(its_value, its_uid); - its_uid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - its_uid, its_uid, - boost::icl::interval_bounds::closed()); - } else { - its_uid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - std::numeric_limits::min(), - std::numeric_limits::max(), - boost::icl::interval_bounds::closed()); - } - has_uid = true; - } - } else if (its_key == "gid") { - if(n->second.data().empty()) { - load_interval_set(n->second, its_gid_interval_set); - has_gid_range = true; - } else { - if (its_value != "any") { - uint32_t its_gid; - read_data(its_value, its_gid); - its_gid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - its_gid, its_gid, - boost::icl::interval_bounds::closed()); - } else { - its_gid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - std::numeric_limits::min(), - std::numeric_limits::max(), - boost::icl::interval_bounds::closed()); - } - has_gid = true; - } - } else if (its_key == "allow" || its_key == "deny") { - policy->allow_who_ = (its_key == "allow"); - load_credential(n->second, policy->credentials_); - } - } - - if (has_uid && has_gid) { - its_gid_interval_set.insert(its_gid_interval); - - policy->credentials_ += std::make_pair(its_uid_interval, its_gid_interval_set); - policy->allow_who_ = true; - } - if (has_uid_range && has_gid_range) { - for (const auto& u : its_uid_interval_set) - policy->credentials_ += std::make_pair(u, its_gid_interval_set); - policy->allow_who_ = true; - } - } else if (i->first == "allow") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides " - << "already set \"deny\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = true; - load_policy_body(policy, i); - } else if (i->first == "deny") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides " - << "already set \"allow\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = false; - load_policy_body(policy, i); - } - } - std::lock_guard its_lock(any_client_policies_mutex_); - any_client_policies_.push_back(policy); -} - -void -security_impl::load_policy_body(std::shared_ptr &_policy, - const boost::property_tree::ptree::const_iterator &_tree) { - - for (auto l = _tree->second.begin(); l != _tree->second.end(); ++l) { - if (l->first == "requests") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t its_service = 0x0; - instance_t its_instance = 0x0; - boost::icl::interval_map > its_instance_method_intervals; - for (auto k = n->second.begin(); k != n->second.end(); ++k) { - if (k->first == "service") { - read_data(k->second.data(), its_service); - } else if (k->first == "instance") { // legacy definition for instances - boost::icl::interval_set its_instance_interval_set; - boost::icl::interval_set its_method_interval_set; - boost::icl::discrete_interval all_instances(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - - std::string its_value(k->second.data()); - if (its_value != "any") { - read_data(its_value, its_instance); - if (its_instance != 0x0) { - its_instance_interval_set.insert(its_instance); - its_method_interval_set.insert(all_methods); - } - } else { - its_instance_interval_set.insert(all_instances); - its_method_interval_set.insert(all_methods); - } - for (const auto& i : its_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_method_interval_set); - } - } else if (k->first == "instances") { // new instances definition - for (auto p = k->second.begin(); p != k->second.end(); ++p) { - boost::icl::interval_set its_instance_interval_set; - boost::icl::interval_set its_method_interval_set; - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - for (auto m = p->second.begin(); m != p->second.end(); ++m) { - if (m->first == "ids") { - load_interval_set(m->second, its_instance_interval_set); - } else if (m->first == "methods") { - load_interval_set(m->second, its_method_interval_set); - } - } - if (its_method_interval_set.empty()) - its_method_interval_set.insert(all_methods); - for (const auto& i : its_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_method_interval_set); - } - } - - if (its_instance_method_intervals.empty()) { - boost::icl::interval_set its_legacy_instance_interval_set; - boost::icl::interval_set its_legacy_method_interval_set; - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - its_legacy_method_interval_set.insert(all_methods); - - // try to only load instance ranges with any method to be allowed - load_interval_set(k->second, its_legacy_instance_interval_set); - for (const auto& i : its_legacy_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_legacy_method_interval_set); - } - } - } - } - if (its_service != 0x0 && !its_instance_method_intervals.empty()) { - _policy->requests_ += std::make_pair( - boost::icl::discrete_interval( - its_service, its_service, - boost::icl::interval_bounds::closed()), - its_instance_method_intervals); - } - } - } else if (l->first == "offers") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t its_service(0x0); - instance_t its_instance(0x0); - boost::icl::interval_set its_instance_interval_set; - for (auto k = n->second.begin(); k != n->second.end(); ++k) { - if (k->first == "service") { - read_data(k->second.data(), its_service); - } else if (k->first == "instance") { // legacy definition for instances - std::string its_value(k->second.data()); - if (its_value != "any") { - read_data(its_value, its_instance); - if (its_instance != 0x0) { - its_instance_interval_set.insert(its_instance); - } - } else { - its_instance_interval_set.insert( - boost::icl::discrete_interval( - 0x0001, 0xFFFF)); - } - } else if (k->first == "instances") { // new instances definition - load_interval_set(k->second, its_instance_interval_set); - } - } - if (its_service != 0x0 && !its_instance_interval_set.empty()) { - _policy->offers_ - += std::make_pair( - boost::icl::discrete_interval( - its_service, its_service, - boost::icl::interval_bounds::closed()), - its_instance_interval_set); - } - } - } - } -} - - -void -security_impl::load_credential( - const boost::property_tree::ptree &_tree, - boost::icl::interval_map > &_credentials) { - - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - boost::icl::interval_set its_uid_interval_set; - boost::icl::interval_set its_gid_interval_set; - - for (auto j = i->second.begin(); j != i->second.end(); ++j) { - std::string its_key(j->first); - if (its_key == "uid") { - load_interval_set(j->second, its_uid_interval_set); - } else if (its_key == "gid") { - load_interval_set(j->second, its_gid_interval_set); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << "Malformed credential (contains illegal key \"" - << its_key << "\")"; - } - } - - for (const auto& its_uid_interval : its_uid_interval_set) { - _credentials - += std::make_pair(its_uid_interval, its_gid_interval_set); - } - } -} - -bool -security_impl::load_routing_credentials(const configuration_element &_element) { - try { - auto its_routing_cred = _element.tree_.get_child("routing-credentials"); - if (is_configured_) { - VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." - << " Ignoring definition from " << _element.name_; - } else { - for (auto i = its_routing_cred.begin(); - i != its_routing_cred.end(); - ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - if (its_key == "uid") { - uint32_t its_uid(0); - read_data(its_value, its_uid); - std::lock_guard its_lock(routing_credentials_mutex_); - std::get<0>(routing_credentials_) = its_uid; - } else if (its_key == "gid") { - uint32_t its_gid(0); - read_data(its_value, its_gid); - std::lock_guard its_lock(routing_credentials_mutex_); - std::get<1>(routing_credentials_) = its_gid; - } - } - check_routing_credentials_ = true; - is_configured_ = true; - } - } catch (...) { - return false; - } - return true; -} - - -void -security_impl::load_security_update_whitelist(const configuration_element &_element) { -#ifdef _WIN32 - return; -#endif - try { - auto optional = _element.tree_.get_child_optional("security-update-whitelist"); - if (!optional) { - return; - } - auto found_whitelist = _element.tree_.get_child("security-update-whitelist"); - for (auto its_whitelist = found_whitelist.begin(); - its_whitelist != found_whitelist.end(); ++its_whitelist) { - - if (its_whitelist->first == "uids") { - { - std::lock_guard its_lock(uid_whitelist_mutex_); - load_interval_set(its_whitelist->second, uid_whitelist_); - } - } else if (its_whitelist->first == "services") { - { - std::lock_guard its_lock(service_interface_whitelist_mutex_); - load_interval_set(its_whitelist->second, service_interface_whitelist_); - } - } else if (its_whitelist->first == "check-whitelist") { - if (its_whitelist->second.data() == "true") { - check_whitelist_ = true; - } else { - check_whitelist_ = false; - } - } - } - } catch (...) { - } -} - -template -void security_impl::load_interval_set( - const boost::property_tree::ptree &_tree, - boost::icl::interval_set &_intervals, bool _exclude_margins) { - - boost::icl::interval_set its_intervals; - T_ its_min = std::numeric_limits::min(); - T_ its_max = std::numeric_limits::max(); - - if (_exclude_margins) { - its_min++; - its_max--; - } - - const std::string its_key(_tree.data()); - if (its_key == "any") { - its_intervals.insert(boost::icl::discrete_interval::closed( - its_min, its_max)); - } else { - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - auto its_data = i->second; - if (!its_data.data().empty()) { - T_ its_id; - read_data(its_data.data(), its_id); - if (its_id >= its_min && its_id <= its_max) - its_intervals.insert(its_id); - } else { - T_ its_first, its_last; - bool has_first(false), has_last(false); - for (auto j = its_data.begin(); j != its_data.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "first") { - if (its_value == "min") { - its_first = its_min; - } else { - read_data(its_value, its_first); - } - has_first = true; - } else if (its_key == "last") { - if (its_value == "max") { - its_last = its_max; - } else { - read_data(its_value, its_last); - } - has_last = true; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << " Malformed range. Contains illegal key (" - << its_key << ")"; - } - } - if (has_first && has_last && its_first <= its_last) { - its_intervals.insert( - boost::icl::discrete_interval::closed(its_first, its_last)); - } - } - } - } - - _intervals = its_intervals; -} - -void -security_impl::get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const { - - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - std::lock_guard its_lock(_policy->mutex_); - for (const auto &o : _policy->offers_) { - for (const auto &p : its_policies) { - if (p == _policy) - continue; - - std::lock_guard its_lock(p->mutex_); - - auto its_policy = std::make_shared(); - its_policy->credentials_ = p->credentials_; - - for (const auto &r : p->requests_) { - // o represents an offer by a service interval and its instances - // (a set of intervals) - // r represents a request by a service interval and its instances - // and methods (instance intervals mapped to interval sets of methods) - // - // Thus, r matches o if their service identifiers as well as their - // instances overlap. If r and o match, a new policy must be - // created that contains the overlapping services/instances mapping - // of r and o together with the methods from r - service_t its_o_lower, its_o_upper, its_r_lower, its_r_upper; - get_bounds(o.first, its_o_lower, its_o_upper); - get_bounds(r.first, its_r_lower, its_r_upper); - - if (its_o_lower <= its_r_upper && its_r_lower <= its_o_upper) { - auto its_service_min = std::max(its_o_lower, its_r_lower); - auto its_service_max = std::min(its_r_upper, its_o_upper); - - for (const auto &i : o.second) { - for (const auto &j : r.second) { - for (const auto& k : j.second) { - instance_t its_i_lower, its_i_upper, its_k_lower, its_k_upper; - get_bounds(i, its_i_lower, its_i_upper); - get_bounds(k, its_k_lower, its_k_upper); - - if (its_i_lower <= its_k_upper && its_k_lower <= its_i_upper) { - auto its_instance_min = std::max(its_i_lower, its_k_lower); - auto its_instance_max = std::min(its_i_upper, its_k_upper); - - boost::icl::interval_map > its_instances_methods; - its_instances_methods += std::make_pair( - boost::icl::interval::closed( - its_instance_min, its_instance_max), - j.second); - - its_policy->requests_ += std::make_pair( - boost::icl::interval::closed( - its_service_min, its_service_max), - its_instances_methods); - } - } - } - } - } - } - - if (!its_policy->requests_.empty()) { - _requesters.insert(its_policy); - its_policy->print(); - } - } - } -} - -void -security_impl::get_clients(uid_t _uid, gid_t _gid, - std::unordered_set &_clients) const { - - std::lock_guard its_lock(ids_mutex_); - for (const auto &i : ids_) { - if (i.second.first == _uid && i.second.second == _gid) - _clients.insert(i.first); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Manage the security object -//////////////////////////////////////////////////////////////////////////////// -static std::shared_ptr *the_security_ptr__(nullptr); -static std::mutex the_security_mutex__; - -std::shared_ptr -security_impl::get() { -#ifndef _WIN32 - std::lock_guard its_lock(the_security_mutex__); -#endif - if(the_security_ptr__ == nullptr) { - the_security_ptr__ = new std::shared_ptr(); - } - if (the_security_ptr__ != nullptr) { - if (!(*the_security_ptr__)) { - *the_security_ptr__ = std::make_shared(); - } - return (*the_security_ptr__); - } - return (nullptr); -} - -#ifndef _WIN32 -static void security_teardown(void) __attribute__((destructor)); -static void security_teardown(void) -{ - if (the_security_ptr__ != nullptr) { - std::lock_guard its_lock(the_security_mutex__); - the_security_ptr__->reset(); - delete the_security_ptr__; - the_security_ptr__ = nullptr; - } -} -#endif - -} // namespace vsomeip_v3 diff --git a/implementation/service_discovery/include/configuration_option_impl.hpp b/implementation/service_discovery/include/configuration_option_impl.hpp index 567762d29..e1dde72cf 100644 --- a/implementation/service_discovery/include/configuration_option_impl.hpp +++ b/implementation/service_discovery/include/configuration_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,7 +25,7 @@ class configuration_option_impl: public option_impl { configuration_option_impl(); virtual ~configuration_option_impl(); - bool operator==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; void add_item(const std::string &_key, const std::string &_value); void remove_item(const std::string &_key); diff --git a/implementation/service_discovery/include/constants.hpp b/implementation/service_discovery/include/constants.hpp index c50fac145..3ebb259fe 100644 --- a/implementation/service_discovery/include/constants.hpp +++ b/implementation/service_discovery/include/constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/defines.hpp b/implementation/service_discovery/include/defines.hpp index b7e840bd5..b7642f122 100644 --- a/implementation/service_discovery/include/defines.hpp +++ b/implementation/service_discovery/include/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,7 @@ #define VSOMEIP_SOMEIP_SD_DATA_SIZE 12 #define VSOMEIP_SOMEIP_SD_ENTRY_LENGTH_SIZE 4 #define VSOMEIP_SOMEIP_SD_ENTRY_SIZE 16 -#define VSOMEIP_SOMEIP_SD_IPV4_OPTION_SIZE 12 +#define VSOMEIP_SOMEIP_SD_IPV3_OPTION_SIZE 12 #define VSOMEIP_SOMEIP_SD_IPV6_OPTION_SIZE 24 #define VSOMEIP_SOMEIP_SD_LOAD_BALANCING_OPTION_SIZE 8 #define VSOMEIP_SOMEIP_SD_PROTECTION_OPTION_SIZE 12 diff --git a/implementation/service_discovery/include/deserializer.hpp b/implementation/service_discovery/include/deserializer.hpp old mode 100755 new mode 100644 index 97ebcd404..866ebda3a --- a/implementation/service_discovery/include/deserializer.hpp +++ b/implementation/service_discovery/include/deserializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/entry_impl.hpp b/implementation/service_discovery/include/entry_impl.hpp old mode 100755 new mode 100644 index 39d54160a..ed22c8ffc --- a/implementation/service_discovery/include/entry_impl.hpp +++ b/implementation/service_discovery/include/entry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/enumeration_types.hpp b/implementation/service_discovery/include/enumeration_types.hpp index 63d037887..0b6c71b8a 100644 --- a/implementation/service_discovery/include/enumeration_types.hpp +++ b/implementation/service_discovery/include/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/eventgroupentry_impl.hpp b/implementation/service_discovery/include/eventgroupentry_impl.hpp old mode 100755 new mode 100644 index 08b25a613..efb9b07c3 --- a/implementation/service_discovery/include/eventgroupentry_impl.hpp +++ b/implementation/service_discovery/include/eventgroupentry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/ip_option_impl.hpp b/implementation/service_discovery/include/ip_option_impl.hpp index c83d745a9..842be8408 100644 --- a/implementation/service_discovery/include/ip_option_impl.hpp +++ b/implementation/service_discovery/include/ip_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,7 +19,7 @@ class ip_option_impl ip_option_impl(); ip_option_impl(const uint16_t _port, const bool _is_reliable); virtual ~ip_option_impl(); - virtual bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; uint16_t get_port() const; void set_port(uint16_t _port); diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp index 15c04b262..7e9707849 100644 --- a/implementation/service_discovery/include/ipv4_option_impl.hpp +++ b/implementation/service_discovery/include/ipv4_option_impl.hpp @@ -1,10 +1,10 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ -#define VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ +#ifndef VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ +#define VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ #include @@ -22,7 +22,7 @@ class ipv4_option_impl: public ip_option_impl { const uint16_t _port, const bool _is_reliable); virtual ~ipv4_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; const ipv4_address_t & get_address() const; void set_address(const ipv4_address_t &_address); @@ -38,5 +38,5 @@ class ipv4_option_impl: public ip_option_impl { } // namespace sd } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ +#endif // VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp index d896300d3..17a613b25 100644 --- a/implementation/service_discovery/include/ipv6_option_impl.hpp +++ b/implementation/service_discovery/include/ipv6_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,7 +23,7 @@ class ipv6_option_impl const uint16_t _port, const bool _is_reliable); virtual ~ipv6_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; const ipv6_address_t & get_address() const; void set_address(const ipv6_address_t &_address); diff --git a/implementation/service_discovery/include/load_balancing_option_impl.hpp b/implementation/service_discovery/include/load_balancing_option_impl.hpp old mode 100755 new mode 100644 index dafcfc723..15fa91798 --- a/implementation/service_discovery/include/load_balancing_option_impl.hpp +++ b/implementation/service_discovery/include/load_balancing_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,7 +17,7 @@ class load_balancing_option_impl: public option_impl { load_balancing_option_impl(); virtual ~load_balancing_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; priority_t get_priority() const; void set_priority(priority_t _priority); diff --git a/implementation/service_discovery/include/message_element_impl.hpp b/implementation/service_discovery/include/message_element_impl.hpp old mode 100755 new mode 100644 index 29b5d861f..2ce979b05 --- a/implementation/service_discovery/include/message_element_impl.hpp +++ b/implementation/service_discovery/include/message_element_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp old mode 100755 new mode 100644 index b9e858d81..faeb9d60f --- a/implementation/service_discovery/include/message_impl.hpp +++ b/implementation/service_discovery/include/message_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -36,7 +36,7 @@ class serviceentry_impl; class option_impl; class configuration_option_impl; -class ipv4_option_impl; +class ipv3_option_impl; class ipv6_option_impl; class load_balancing_option_impl; class protection_option_impl; @@ -45,8 +45,8 @@ class selective_option_impl; class message_impl : public vsomeip_v3::message, public vsomeip_v3::message_base_impl { public: - typedef std::vector> entries_t; - typedef std::vector> options_t; + using entries_t = std::vector>; + using options_t = std::vector>; struct forced_initial_events_t { std::shared_ptr target_; vsomeip_v3::service_t service_; @@ -104,6 +104,8 @@ class message_impl uid_t get_uid() const; gid_t get_gid() const; + vsomeip_sec_client_t get_sec_client() const; + std::string get_env() const; private: entry_impl * deserialize_entry(vsomeip_v3::deserializer *_from); diff --git a/implementation/service_discovery/include/option_impl.hpp b/implementation/service_discovery/include/option_impl.hpp index e171c741a..3c898b6f9 100644 --- a/implementation/service_discovery/include/option_impl.hpp +++ b/implementation/service_discovery/include/option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,8 +26,7 @@ class option_impl: public message_element_impl { option_impl(); virtual ~option_impl(); - virtual bool operator ==(const option_impl &_other) const; - bool equals(const std::shared_ptr &_other) const; + virtual bool equals(const option_impl &_other) const; uint16_t get_length() const; option_type_e get_type() const; diff --git a/implementation/service_discovery/include/primitive_types.hpp b/implementation/service_discovery/include/primitive_types.hpp index fd093e9bb..cf152c8c9 100644 --- a/implementation/service_discovery/include/primitive_types.hpp +++ b/implementation/service_discovery/include/primitive_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,15 +12,15 @@ namespace vsomeip_v3 { namespace sd { // Load balancing -typedef uint16_t priority_t; -typedef uint16_t weight_t; +using priority_t = std::uint16_t; +using weight_t = std::uint16_t; // Protection -typedef uint32_t alive_counter_t; -typedef uint32_t crc_t; +using alive_counter_t = std::uint32_t; +using crc_t = std::uint32_t; // -typedef uint8_t flags_t; +using flags_t = std::uint8_t; } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/include/protection_option_impl.hpp b/implementation/service_discovery/include/protection_option_impl.hpp old mode 100755 new mode 100644 index 792d7cce7..7e34eb50a --- a/implementation/service_discovery/include/protection_option_impl.hpp +++ b/implementation/service_discovery/include/protection_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,7 +17,7 @@ class protection_option_impl: public option_impl { protection_option_impl(); virtual ~protection_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; alive_counter_t get_alive_counter() const; void set_alive_counter(alive_counter_t _counter); diff --git a/implementation/service_discovery/include/remote_subscription_ack.hpp b/implementation/service_discovery/include/remote_subscription_ack.hpp index 1bc87927f..7b2b63576 100644 --- a/implementation/service_discovery/include/remote_subscription_ack.hpp +++ b/implementation/service_discovery/include/remote_subscription_ack.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/request.hpp b/implementation/service_discovery/include/request.hpp index 0e6e2ec32..4d4dba03f 100644 --- a/implementation/service_discovery/include/request.hpp +++ b/implementation/service_discovery/include/request.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/runtime.hpp b/implementation/service_discovery/include/runtime.hpp index 0772de420..fe9f27bfc 100644 --- a/implementation/service_discovery/include/runtime.hpp +++ b/implementation/service_discovery/include/runtime.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/runtime_impl.hpp b/implementation/service_discovery/include/runtime_impl.hpp index 0010de6f2..1b5bfa4ec 100644 --- a/implementation/service_discovery/include/runtime_impl.hpp +++ b/implementation/service_discovery/include/runtime_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/selective_option_impl.hpp b/implementation/service_discovery/include/selective_option_impl.hpp index 863408f50..b4d7bcb37 100644 --- a/implementation/service_discovery/include/selective_option_impl.hpp +++ b/implementation/service_discovery/include/selective_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,7 +25,7 @@ class selective_option_impl: public option_impl { selective_option_impl(); virtual ~selective_option_impl(); - bool operator==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; std::set get_clients() const; void set_clients(const std::set &_clients); diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 77b4258d1..cab33a8a2 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,6 @@ #ifndef VSOMEIP_V3_SD_SERVICE_DISCOVERY_HPP_ #define VSOMEIP_V3_SD_SERVICE_DISCOVERY_HPP_ -#include #include #include @@ -28,7 +27,7 @@ class service_discovery { virtual ~service_discovery() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual void init() = 0; virtual void start() = 0; @@ -51,14 +50,15 @@ class service_discovery { virtual void on_message(const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination) = 0; + bool _is_multicast) = 0; virtual void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr &_endpoint) = 0; virtual void offer_service(const std::shared_ptr &_info) = 0; - virtual void stop_offer_service(const std::shared_ptr &_info) = 0; + virtual bool stop_offer_service(const std::shared_ptr &_info, bool _send) = 0; + virtual bool send_collected_stop_offers(const std::vector> &_infos) = 0; virtual void set_diagnosis_mode(const bool _activate) = 0; @@ -68,9 +68,9 @@ class service_discovery { const std::shared_ptr &_subscription) = 0; virtual void register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) = 0; + const sd_acceptance_handler_t &_handler) = 0; virtual void register_reboot_notification_handler( - reboot_notification_handler_t _handler) = 0; + const reboot_notification_handler_t &_handler) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 0f992d795..09b5301c4 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,12 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include "../../routing/include/function_types.hpp" #include "../../routing/include/types.hpp" @@ -31,7 +36,7 @@ class service_discovery_host { virtual ~service_discovery_host() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual std::shared_ptr create_service_discovery_endpoint( const std::string &_address, uint16_t _port, bool _reliable) = 0; @@ -40,7 +45,8 @@ class service_discovery_host { virtual std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const = 0; - virtual bool send(client_t _client, std::shared_ptr _message) = 0; + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force) = 0; virtual bool send_via_sd(const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, uint16_t _sd_port) = 0; @@ -86,7 +92,7 @@ class service_discovery_host { virtual void on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _subscription_id, bool _simulated) = 0; + event_t _event, remote_subscription_id_t _subscription_id) = 0; virtual std::chrono::steady_clock::time_point expire_subscriptions(bool _force) = 0; diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index c4e38357b..b2270e1ab 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -44,11 +44,7 @@ class serviceentry_impl; class service_discovery_host; class subscription; -typedef std::map - > - > requests_t; +using requests_t = std::map>>; struct entry_data_t { std::shared_ptr entry_; @@ -63,7 +59,7 @@ class service_discovery_impl: public service_discovery, const std::shared_ptr& _configuration); virtual ~service_discovery_impl(); - boost::asio::io_service & get_io(); + boost::asio::io_context &get_io(); void init(); void start(); @@ -86,14 +82,15 @@ class service_discovery_impl: public service_discovery, void on_message(const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination); + bool _is_multicast); void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr &_endpoint); void offer_service(const std::shared_ptr &_info); - void stop_offer_service(const std::shared_ptr &_info); + bool stop_offer_service(const std::shared_ptr &_info, bool _send); + bool send_collected_stop_offers(const std::vector> &_infos); void set_diagnosis_mode(const bool _activate); @@ -103,16 +100,19 @@ class service_discovery_impl: public service_discovery, void update_remote_subscription( const std::shared_ptr &_subscription); - void register_sd_acceptance_handler(sd_acceptance_handler_t _handler); + void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler); void register_reboot_notification_handler( - reboot_notification_handler_t _handler); + const reboot_notification_handler_t &_handler); private: std::pair get_session(const boost::asio::ip::address &_address); void increment_session(const boost::asio::ip::address &_address); bool is_reboot(const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, - bool _reboot_flag, session_t _session); + bool _is_multicast, bool _reboot_flag, session_t _session); + + bool check_session_id_sequence(const boost::asio::ip::address &_sender, + const bool _is_multicast, const session_t &_session, + session_t &_missing_session); void insert_find_entries(std::vector > &_messages, const requests_t &_requests); @@ -120,12 +120,6 @@ class service_discovery_impl: public service_discovery, const services_t &_services, bool _ignore_phase); void insert_offer_service(std::vector > &_messages, const std::shared_ptr &_info); - enum remote_offer_type_e : std::uint8_t { - RELIABLE_UNRELIABLE, - RELIABLE, - UNRELIABLE, - UNKNOWN = 0xff - }; entry_data_t create_eventgroup_entry( service_t _service, instance_t _instance, eventgroup_t _eventgroup, @@ -138,7 +132,7 @@ class service_discovery_impl: public service_discovery, const std::shared_ptr &_target, const std::set &_clients); - typedef std::set> expired_ports_t; + using expired_ports_t = std::set>; struct sd_acceptance_state_t { explicit sd_acceptance_state_t(expired_ports_t& _expired_ports) : expired_ports_(_expired_ports), @@ -178,7 +172,7 @@ class service_discovery_impl: public service_discovery, const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const sd_acceptance_state_t& _sd_ac_state); void handle_eventgroup_subscription(service_t _service, @@ -215,7 +209,7 @@ class service_discovery_impl: public service_discovery, instance_t _instance, const std::shared_ptr& its_endpoint); - void start_ttl_timer(); + void start_ttl_timer(int _shift = 0); void stop_ttl_timer(); void check_ttl(const boost::system::error_code &_error); @@ -310,13 +304,13 @@ class service_discovery_impl: public service_discovery, void on_last_msg_received_timer_expired(const boost::system::error_code &_error); void stop_last_msg_received_timer(); - remote_offer_type_e get_remote_offer_type( + reliability_type_e get_remote_offer_type( service_t _service, instance_t _instance) const; - remote_offer_type_e get_remote_offer_type( + reliability_type_e get_remote_offer_type( const std::shared_ptr &_subscription) const; bool update_remote_offer_type(service_t _service, instance_t _instance, - remote_offer_type_e _offer_type, + reliability_type_e _offer_type, const boost::asio::ip::address &_reliable_address, std::uint16_t _reliable_port, const boost::asio::ip::address &_unreliable_address, @@ -362,7 +356,7 @@ class service_discovery_impl: public service_discovery, const std::shared_ptr& _subscription); private: - boost::asio::io_service &io_; + boost::asio::io_context &io_; service_discovery_host *host_; std::shared_ptr configuration_; @@ -463,7 +457,7 @@ class service_discovery_impl: public service_discovery, std::chrono::milliseconds last_msg_received_timer_timeout_; mutable std::mutex remote_offer_types_mutex_; - std::map, remote_offer_type_e> remote_offer_types_; + std::map, reliability_type_e> remote_offer_types_; std::map, std::set>>> remote_offers_by_ip_; @@ -479,4 +473,3 @@ class service_discovery_impl: public service_discovery, } // namespace vsomeip_v3 #endif // VSOMEIP_V3_SD_SERVICE_DISCOVERY_IMPL_ - diff --git a/implementation/service_discovery/include/serviceentry_impl.hpp b/implementation/service_discovery/include/serviceentry_impl.hpp index f7b2b92f9..8e1cf70fd 100644 --- a/implementation/service_discovery/include/serviceentry_impl.hpp +++ b/implementation/service_discovery/include/serviceentry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp index adbd66ceb..8c1e07473 100644 --- a/implementation/service_discovery/include/subscription.hpp +++ b/implementation/service_discovery/include/subscription.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/configuration_option_impl.cpp b/implementation/service_discovery/src/configuration_option_impl.cpp old mode 100755 new mode 100644 index 9666e5e18..c1f691763 --- a/implementation/service_discovery/src/configuration_option_impl.cpp +++ b/implementation/service_discovery/src/configuration_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ configuration_option_impl::~configuration_option_impl() { } bool -configuration_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +configuration_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const configuration_option_impl &its_other @@ -123,8 +123,6 @@ bool configuration_option_impl::deserialize(vsomeip_v3::deserializer *_from) { is_successful = false; } } - } else { - break; } } while (is_successful && _from->get_remaining() > 0); diff --git a/implementation/service_discovery/src/deserializer.cpp b/implementation/service_discovery/src/deserializer.cpp index 88ce3be9d..046a523cf 100644 --- a/implementation/service_discovery/src/deserializer.cpp +++ b/implementation/service_discovery/src/deserializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/entry_impl.cpp b/implementation/service_discovery/src/entry_impl.cpp old mode 100755 new mode 100644 index 1fa1c89ba..3873d0a34 --- a/implementation/service_discovery/src/entry_impl.cpp +++ b/implementation/service_discovery/src/entry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/eventgroupentry_impl.cpp b/implementation/service_discovery/src/eventgroupentry_impl.cpp old mode 100755 new mode 100644 index 28fdcec1d..f23fd740f --- a/implementation/service_discovery/src/eventgroupentry_impl.cpp +++ b/implementation/service_discovery/src/eventgroupentry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -118,8 +118,8 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, std::vector> its_options_current; std::vector> its_options_other; const std::size_t its_options_size = _options.size(); - for (const auto& option_run : {0,1}) { - for (const auto& option_index : options_[option_run]) { + for (const auto option_run : {0,1}) { + for (const auto option_index : options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: @@ -137,7 +137,7 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, } } } - for (const auto& option_index : _other.options_[option_run]) { + for (const auto option_index : _other.options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: @@ -165,7 +165,7 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, for (const auto& c : its_options_current) { bool found(false); for (const auto& o : its_options_other) { - if (*c == *o) { + if (c->equals(*o)) { switch (c->get_type()) { case option_type_e::IP4_ENDPOINT: if (static_cast(c.get())->get_address() @@ -212,8 +212,8 @@ std::shared_ptr eventgroupentry_impl::get_target( std::shared_ptr eventgroupentry_impl::get_selective_option() const { - for (const auto& i : {0, 1}) { - for (const auto& j : options_[i]) { + for (const auto i : {0, 1}) { + for (const auto j : options_[i]) { auto its_option = std::dynamic_pointer_cast< selective_option_impl>(owner_->get_option(j)); if (its_option) diff --git a/implementation/service_discovery/src/ip_option_impl.cpp b/implementation/service_discovery/src/ip_option_impl.cpp index 0f835117d..197013f95 100644 --- a/implementation/service_discovery/src/ip_option_impl.cpp +++ b/implementation/service_discovery/src/ip_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -29,8 +29,8 @@ ip_option_impl::~ip_option_impl() { } bool -ip_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +ip_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const ip_option_impl &its_other diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp index f3389e8c7..f2eef958a 100644 --- a/implementation/service_discovery/src/ipv4_option_impl.cpp +++ b/implementation/service_discovery/src/ipv4_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -31,8 +31,8 @@ ipv4_option_impl::~ipv4_option_impl() { } bool -ipv4_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(ip_option_impl::operator ==(_other)); +ipv4_option_impl::equals(const option_impl &_other) const { + bool is_equal(ip_option_impl::equals(_other)); if (is_equal) { const ipv4_option_impl &its_other = dynamic_cast(_other); diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp old mode 100755 new mode 100644 index 1baba0fff..e2bc30e43 --- a/implementation/service_discovery/src/ipv6_option_impl.cpp +++ b/implementation/service_discovery/src/ipv6_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -31,8 +31,8 @@ ipv6_option_impl::~ipv6_option_impl() { } bool -ipv6_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(ip_option_impl::operator ==(_other)); +ipv6_option_impl::equals(const option_impl &_other) const { + bool is_equal(ip_option_impl::equals(_other)); if (is_equal) { const ipv6_option_impl &its_other diff --git a/implementation/service_discovery/src/load_balancing_option_impl.cpp b/implementation/service_discovery/src/load_balancing_option_impl.cpp old mode 100755 new mode 100644 index a26509ecf..1e3078865 --- a/implementation/service_discovery/src/load_balancing_option_impl.cpp +++ b/implementation/service_discovery/src/load_balancing_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ load_balancing_option_impl::~load_balancing_option_impl() { } bool -load_balancing_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +load_balancing_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const load_balancing_option_impl &its_other diff --git a/implementation/service_discovery/src/message_element_impl.cpp b/implementation/service_discovery/src/message_element_impl.cpp old mode 100755 new mode 100644 index 281a0a7ca..afdb50790 --- a/implementation/service_discovery/src/message_element_impl.cpp +++ b/implementation/service_discovery/src/message_element_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp old mode 100755 new mode 100644 index a203ce709..c00da1916 --- a/implementation/service_discovery/src/message_impl.cpp +++ b/implementation/service_discovery/src/message_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -178,7 +178,7 @@ const message_impl::options_t & message_impl::get_options() const { std::shared_ptr message_impl::find_option(const std::shared_ptr &_option) const { for (auto its_option : options_) { - if (its_option->equals(_option)) + if (its_option->equals(*_option)) return its_option; } return nullptr; @@ -419,13 +419,24 @@ length_t message_impl::get_someip_length() const { } uid_t message_impl::get_uid() const { - return ANY_UID; + return (ANY_UID); } gid_t message_impl::get_gid() const { - return ANY_GID; + return (ANY_GID); } +vsomeip_sec_client_t message_impl::get_sec_client() const { + static vsomeip_sec_client_t its_dummy_sec_client{ + VSOMEIP_CLIENT_UDS, {vsomeip_sec_uds_client_credentials_t{ANY_UID, ANY_GID}} + }; + + return (its_dummy_sec_client); +} + +std::string message_impl::get_env() const { + return (""); +} } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp old mode 100755 new mode 100644 index eb92c1ad9..c055ff4ac --- a/implementation/service_discovery/src/option_impl.cpp +++ b/implementation/service_discovery/src/option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,9 @@ option_impl::option_impl() : option_impl::~option_impl() { } -bool option_impl::operator ==(const option_impl &_other) const { - return (type_ == _other.type_ && length_ == _other.length_); -} - bool -option_impl::equals(const std::shared_ptr &_other) const { - return (this->operator ==(*(_other.get()))); +option_impl::equals(const option_impl &_other) const { + return (type_ == _other.get_type() && length_ == _other.get_length()); } uint16_t option_impl::get_length() const { diff --git a/implementation/service_discovery/src/protection_option_impl.cpp b/implementation/service_discovery/src/protection_option_impl.cpp old mode 100755 new mode 100644 index 801ca88a1..6d79860a3 --- a/implementation/service_discovery/src/protection_option_impl.cpp +++ b/implementation/service_discovery/src/protection_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ protection_option_impl::~protection_option_impl() { } bool -protection_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +protection_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const protection_option_impl &its_other diff --git a/implementation/service_discovery/src/remote_subscription_ack.cpp b/implementation/service_discovery/src/remote_subscription_ack.cpp index 03270c981..45fa0576b 100644 --- a/implementation/service_discovery/src/remote_subscription_ack.cpp +++ b/implementation/service_discovery/src/remote_subscription_ack.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/request.cpp b/implementation/service_discovery/src/request.cpp index 819b1a542..ee6b10bd0 100644 --- a/implementation/service_discovery/src/request.cpp +++ b/implementation/service_discovery/src/request.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/runtime_impl.cpp b/implementation/service_discovery/src/runtime_impl.cpp index 75ce9863b..f0fa456e0 100644 --- a/implementation/service_discovery/src/runtime_impl.cpp +++ b/implementation/service_discovery/src/runtime_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/selective_option_impl.cpp b/implementation/service_discovery/src/selective_option_impl.cpp old mode 100755 new mode 100644 index 17063d98e..7fe62c9ef --- a/implementation/service_discovery/src/selective_option_impl.cpp +++ b/implementation/service_discovery/src/selective_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ selective_option_impl::~selective_option_impl() { } bool -selective_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +selective_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const selective_option_impl &its_other = dynamic_cast(_other); diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 74e509b87..19effad09 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -81,8 +81,7 @@ service_discovery_impl::service_discovery_impl( service_discovery_impl::~service_discovery_impl() { } -boost::asio::io_service & -service_discovery_impl::get_io() { +boost::asio::io_context &service_discovery_impl::get_io() { return io_; } @@ -164,11 +163,13 @@ service_discovery_impl::start() { i.second->set_sent_counter(0); } } + + // rejoin multicast group if (endpoint_ && !reliable_) { - auto its_endpoint = std::dynamic_pointer_cast< - udp_server_endpoint_impl>(endpoint_); - if (its_endpoint) - its_endpoint->join(sd_multicast_); + auto its_server_endpoint + = std::dynamic_pointer_cast(endpoint_); + if (its_server_endpoint) + its_server_endpoint->join(sd_multicast_); } } is_suspended_ = false; @@ -524,6 +525,7 @@ service_discovery_impl::unsubscribe_all( serialize_and_send(its_messages, its_address); } + void service_discovery_impl::unsubscribe_all_on_suspend() { @@ -616,12 +618,11 @@ service_discovery_impl::increment_session( bool service_discovery_impl::is_reboot( const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _reboot_flag, session_t _session) { bool result(false); auto its_received = sessions_received_.find(_sender); - bool is_multicast = _destination.is_multicast(); // Initialize both sessions with 0. Thus, the session identifier // for the session not being received from the network is stored @@ -632,7 +633,7 @@ service_discovery_impl::is_reboot( // received from the network will never trigger the reboot detection. bool its_multicast_reboot_flag(true), its_unicast_reboot_flag(true); - if (is_multicast) { + if (_is_multicast) { its_multicast_session = _session; its_multicast_reboot_flag = _reboot_flag; } else { @@ -648,14 +649,14 @@ service_discovery_impl::is_reboot( // Reboot detection: Either the flag has changed from false to true, // or the session identifier overrun while the flag is true. if (_reboot_flag - && ((is_multicast && !std::get<2>(its_received->second)) - || (!is_multicast && !std::get<3>(its_received->second)))) { + && ((_is_multicast && !std::get<2>(its_received->second)) + || (!_is_multicast && !std::get<3>(its_received->second)))) { result = true; } else { session_t its_old_session; bool its_old_reboot_flag; - if (is_multicast) { + if (_is_multicast) { its_old_session = std::get<0>(its_received->second); its_old_reboot_flag = std::get<2>(its_received->second); } else { @@ -671,7 +672,7 @@ service_discovery_impl::is_reboot( if (result == false) { // no reboot -> update session/flag - if (is_multicast) { + if (_is_multicast) { std::get<0>(its_received->second) = its_multicast_session; std::get<2>(its_received->second) = its_multicast_reboot_flag; } else { @@ -687,6 +688,27 @@ service_discovery_impl::is_reboot( return result; } +bool +service_discovery_impl::check_session_id_sequence(const boost::asio::ip::address &_sender, + const bool _is_multicast, const session_t &_session, + session_t &_missing_session) { + + using address_pair_t = std::pair; + static std::map session_peer; + address_pair_t peer_to_peer(_sender, _is_multicast); + std::map::iterator it = session_peer.find(peer_to_peer); + if (it != session_peer.end()) { + if ((_session > it->second) && (_session != (it->second+1))) { + _missing_session = static_cast(it->second+1); + session_peer[peer_to_peer] = _session; + return false; + } + } + + session_peer[peer_to_peer] = _session; + return true; +} + void service_discovery_impl::insert_find_entries( std::vector > &_messages, @@ -839,7 +861,7 @@ service_discovery_impl::create_eventgroup_entry( its_entry->set_ttl(_subscription->get_ttl()); its_data.entry_ = its_entry; - for (const auto& its_client : _subscription->get_clients()) { + for (const auto its_client : _subscription->get_clients()) { if (_subscription->get_state(its_client) == subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED) { its_other = std::make_shared(); @@ -890,7 +912,7 @@ service_discovery_impl::create_eventgroup_entry( its_data.entry_ = its_entry; } - for (const auto& its_client : _subscription->get_clients()) { + for (const auto its_client : _subscription->get_clients()) { if (_subscription->get_state(its_client) == subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED) { if (!its_other) { @@ -1043,7 +1065,7 @@ service_discovery_impl::send(bool _is_announcing) { std::lock_guard its_lock(offer_mutex_); services_t its_offers = host_->get_offered_services(); - insert_offer_entries(its_messages, its_offers, true); + insert_offer_entries(its_messages, its_offers, false); // Serialize and send return send(its_messages); @@ -1057,7 +1079,7 @@ void service_discovery_impl::on_message( const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination) { + bool _is_multicast) { #if 0 std::stringstream msg; msg << "sdi::on_message: "; @@ -1075,8 +1097,8 @@ service_discovery_impl::on_message( if (!check_source_address(_sender)) { return; } - const bool received_via_mcast = (_destination == sd_multicast_address_); - if (received_via_mcast) { + + if (_is_multicast) { static bool must_start_last_msg_received_timer(true); boost::system::error_code ec; @@ -1102,7 +1124,7 @@ service_discovery_impl::on_message( return; } // Expire all subscriptions / services in case of reboot - if (is_reboot(_sender, _destination, + if (is_reboot(_sender, _is_multicast, its_message->get_reboot_flag(), its_message->get_session())) { VSOMEIP_INFO << "Reboot detected: IP=" << _sender.to_string(); remove_remote_offer_type_by_ip(_sender); @@ -1121,6 +1143,23 @@ service_discovery_impl::on_message( } } + session_t start_missing_sessions; + if (!check_session_id_sequence(_sender, _is_multicast, its_message->get_session(), start_missing_sessions)) { + std::stringstream log; + log << "SD messages lost from " << _sender.to_string() << " to "; + if (_is_multicast) { + log << sd_multicast_address_.to_string(); + } else { + log << unicast_.to_string(); + } + log << " - session_id[" << start_missing_sessions; + if (its_message->get_session() - start_missing_sessions != 1) { + log << ":" << its_message->get_session() -1; + } + log << "]"; + VSOMEIP_WARNING << log.str(); + } + std::vector > its_options = its_message->get_options(); @@ -1171,7 +1210,7 @@ service_discovery_impl::on_message( bool its_unicast_flag = its_message->get_unicast_flag(); process_serviceentry(its_service_entry, its_options, its_unicast_flag, its_resubscribes, - received_via_mcast, accept_state); + _is_multicast, accept_state); } else { std::shared_ptr its_eventgroup_entry = std::dynamic_pointer_cast(*iter); @@ -1190,7 +1229,7 @@ service_discovery_impl::on_message( is_stop_subscribe_subscribe = check_stop_subscribe_subscribe(iter, its_end, its_options); process_eventgroupentry(its_eventgroup_entry, its_options, - its_acknowledgement, _sender, _destination, + its_acknowledgement, _sender, _is_multicast, is_stop_subscribe_subscribe, force_initial_events, accept_state); } @@ -1330,7 +1369,7 @@ service_discovery_impl::process_serviceentry( VSOMEIP_ERROR << __func__ << ": Unsupported service entry type"; } } else if (its_type != entry_type_e::FIND_SERVICE - && (!_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { + && (_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { // stop sending find service in repetition phase update_request(its_service, its_instance); @@ -1378,19 +1417,10 @@ service_discovery_impl::process_offerservice_serviceentry( // stop sending find service in repetition phase update_request(_service, _instance); - remote_offer_type_e offer_type(remote_offer_type_e::UNKNOWN); - if (_reliable_port != ILLEGAL_PORT - && _unreliable_port != ILLEGAL_PORT - && !_reliable_address.is_unspecified() - && !_unreliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::RELIABLE_UNRELIABLE; - } else if (_unreliable_port != ILLEGAL_PORT - && !_unreliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::UNRELIABLE; - } else if (_reliable_port != ILLEGAL_PORT - && !_reliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::RELIABLE; - } else { + const reliability_type_e offer_type = configuration_->get_reliability_type( + _reliable_address, _reliable_port, _unreliable_address,_unreliable_port); + + if (offer_type == reliability_type_e::RT_UNKNOWN) { VSOMEIP_WARNING << __func__ << ": Unknown remote offer type [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; @@ -1419,7 +1449,7 @@ service_discovery_impl::process_offerservice_serviceentry( // return if the registered sd_acceptance handler returned false // and for the provided port sd_acceptance is necessary switch (offer_type) { - case remote_offer_type_e::UNRELIABLE: + case reliability_type_e::RT_UNRELIABLE: if (!_sd_ac_state.accept_entries_ && configuration_->is_protected_port( _unreliable_address, _unreliable_port, false)) { @@ -1428,7 +1458,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::RELIABLE: + case reliability_type_e::RT_RELIABLE: if (!_sd_ac_state.accept_entries_ && configuration_->is_protected_port( _reliable_address, _reliable_port, true)) { @@ -1437,7 +1467,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: + case reliability_type_e::RT_BOTH: if (!_sd_ac_state.accept_entries_ && (configuration_->is_protected_port( _unreliable_address, _unreliable_port, false) @@ -1450,7 +1480,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::UNKNOWN: + case reliability_type_e::RT_UNKNOWN: default: break; } @@ -1470,36 +1500,21 @@ service_discovery_impl::process_offerservice_serviceentry( _service, _instance, eg); if (its_info) { if (its_info->is_reliability_auto_mode()) { - reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); - switch (offer_type) { - case remote_offer_type_e::RELIABLE: - its_reliability = reliability_type_e::RT_RELIABLE; - break; - case remote_offer_type_e::UNRELIABLE: - its_reliability = reliability_type_e::RT_UNRELIABLE; - break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: - its_reliability = reliability_type_e::RT_BOTH; - break; - default: - ; - } - if (its_reliability != reliability_type_e::RT_UNKNOWN - && its_reliability != its_info->get_reliability()) { + if (offer_type != reliability_type_e::RT_UNKNOWN + && offer_type != its_info->get_reliability()) { VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type changed [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << eg << "]" << " using reliability type: " - << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability; - its_info->set_reliability(its_reliability); + << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) offer_type; + its_info->set_reliability(offer_type); } } } } } - // No need to resubscribe for unicast offers if (_received_via_mcast) { std::lock_guard its_lock(subscribed_mutex_); @@ -1534,7 +1549,7 @@ service_discovery_impl::process_offerservice_serviceentry( if (its_data.entry_) { add_entry_data(_resubscribes, its_data); } - for (const auto& its_client : its_subscription->get_clients()) { + for (const auto its_client : its_subscription->get_clients()) { its_subscription->set_state(its_client, subscription_state_e::ST_NOT_ACKNOWLEDGED); } @@ -1770,7 +1785,7 @@ service_discovery_impl::process_eventgroupentry( const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const sd_acceptance_state_t& _sd_ac_state) { @@ -1835,8 +1850,8 @@ service_discovery_impl::process_eventgroupentry( return; } - if(its_type == entry_type_e::SUBSCRIBE_EVENTGROUP) { - if (_destination.is_multicast() ) { + if (its_type == entry_type_e::SUBSCRIBE_EVENTGROUP) { + if (_is_multicast) { boost::system::error_code ec; VSOMEIP_ERROR << __func__ << ": Received a SubscribeEventGroup entry on multicast address " @@ -1874,7 +1889,7 @@ service_discovery_impl::process_eventgroupentry( } if (_options.size() // cast is needed in order to get unsigned type since int will be promoted - // by the + operator on 16 bit or higher machines. + // by the + operator on 16 bit or higher machines. < static_cast>::size_type>( (_entry->get_num_options(1)) + (_entry->get_num_options(2)))) { boost::system::error_code ec; @@ -1916,10 +1931,7 @@ service_discovery_impl::process_eventgroupentry( std::shared_ptr < option_impl > its_option; try { its_option = _options.at(its_index); - } catch(const std::out_of_range& e) { -#ifdef _WIN32 - e; // silence MSVC warning C4101 -#endif + } catch(const std::out_of_range&) { boost::system::error_code ec; VSOMEIP_ERROR << __func__ << ": Fewer options in SD message than " @@ -2335,7 +2347,6 @@ service_discovery_impl::handle_eventgroup_subscription( // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); - boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target1: [" << its_reliable->get_address().to_string() @@ -2365,7 +2376,6 @@ service_discovery_impl::handle_eventgroup_subscription( // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); - boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target2 : [" << its_reliable->get_address().to_string() @@ -2456,10 +2466,10 @@ service_discovery_impl::handle_eventgroup_subscription_nack( auto found_eventgroup = found_instance->second.find(_eventgroup); if (found_eventgroup != found_instance->second.end()) { auto its_subscription = found_eventgroup->second; - for (const auto& its_client : _clients) { + for (const auto its_client : _clients) { host_->on_subscribe_nack(its_client, _service, _instance, _eventgroup, ANY_EVENT, - PENDING_SUBSCRIPTION_ID, false); // TODO: This is a dummy call... + PENDING_SUBSCRIPTION_ID); // TODO: This is a dummy call... } @@ -2491,7 +2501,7 @@ service_discovery_impl::handle_eventgroup_subscription_ack( if (found_instance != found_service->second.end()) { auto found_eventgroup = found_instance->second.find(_eventgroup); if (found_eventgroup != found_instance->second.end()) { - for (const auto& its_client : _clients) { + for (const auto its_client : _clients) { if (found_eventgroup->second->get_state(its_client) == subscription_state_e::ST_NOT_ACKNOWLEDGED) { found_eventgroup->second->set_state(its_client, @@ -2521,7 +2531,7 @@ bool service_discovery_impl::is_tcp_connected(service_t _service, auto its_reliable_server_endpoint = std::dynamic_pointer_cast< tcp_server_endpoint_impl>(its_info->get_endpoint(true)); if (its_reliable_server_endpoint - && its_reliable_server_endpoint->is_established(its_endpoint)) { + && its_reliable_server_endpoint->is_established_to(its_endpoint)) { is_connected = true; } } @@ -2538,7 +2548,7 @@ service_discovery_impl::send( std::pair its_session = get_session(unicast_); m->set_session(its_session.first); m->set_reboot_flag(its_session.second); - if (host_->send(VSOMEIP_SD_CLIENT, m)) { + if (host_->send(VSOMEIP_SD_CLIENT, m, true)) { increment_session(unicast_); } } else { @@ -2583,10 +2593,21 @@ service_discovery_impl::serialize_and_send( } void -service_discovery_impl::start_ttl_timer() { +service_discovery_impl::start_ttl_timer(int _shift) { + std::lock_guard its_lock(ttl_timer_mutex_); + + std::chrono::milliseconds its_timeout(ttl_timer_runtime_); + if (_shift > 0) { + if (its_timeout.count() > _shift) + its_timeout -= std::chrono::milliseconds(_shift); + + if (its_timeout.count() > VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT) + its_timeout = std::chrono::milliseconds(VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT); + } + boost::system::error_code ec; - ttl_timer_.expires_from_now(std::chrono::milliseconds(ttl_timer_runtime_), ec); + ttl_timer_.expires_from_now(its_timeout, ec); ttl_timer_.async_wait( std::bind(&service_discovery_impl::check_ttl, shared_from_this(), std::placeholders::_1)); @@ -2601,12 +2622,20 @@ service_discovery_impl::stop_ttl_timer() { void service_discovery_impl::check_ttl(const boost::system::error_code &_error) { + + static int its_counter(0); // count the times we were not able to call + // update_routing_info if (!_error) { { - std::lock_guard its_lock(check_ttl_mutex_); - host_->update_routing_info(ttl_timer_runtime_); + std::unique_lock its_lock(check_ttl_mutex_, std::try_to_lock); + if (its_lock.owns_lock()) { + its_counter = 0; + host_->update_routing_info(ttl_timer_runtime_); + } else { + its_counter++; + } } - start_ttl_timer(); + start_ttl_timer(its_counter * VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT); } } @@ -2684,11 +2713,11 @@ service_discovery_impl::check_ipv4_address( //Check unallowed ipv4 address bool is_valid = true; - const boost::asio::ip::address_v4::bytes_type its_unicast_address = + static const boost::asio::ip::address_v4::bytes_type its_unicast_address = unicast_.to_v4().to_bytes(); const boost::asio::ip::address_v4::bytes_type endpoint_address = its_address.to_v4().to_bytes(); - const boost::asio::ip::address_v4::bytes_type its_netmask = + static const boost::asio::ip::address_v4::bytes_type its_netmask = configuration_->get_netmask().to_v4().to_bytes(); //same address as unicast address of DUT not allowed @@ -2750,8 +2779,6 @@ service_discovery_impl::start_offer_debounce_timer(bool _first_start) { this, std::placeholders::_1)); } - - void service_discovery_impl::start_find_debounce_timer(bool _first_start) { std::lock_guard its_lock(find_debounce_timer_mutex_); @@ -2989,7 +3016,6 @@ service_discovery_impl::on_repetition_phase_timer_expired( } } - void service_discovery_impl::on_find_repetition_phase_timer_expired( const boost::system::error_code &_error, @@ -3033,7 +3059,6 @@ service_discovery_impl::on_find_repetition_phase_timer_expired( } } - void service_discovery_impl::move_offers_into_main_phase( const std::shared_ptr &_timer) { @@ -3051,9 +3076,9 @@ service_discovery_impl::move_offers_into_main_phase( } } -void +bool service_discovery_impl::stop_offer_service( - const std::shared_ptr &_info) { + const std::shared_ptr &_info, bool _send) { std::lock_guard its_lock(offer_mutex_); _info->set_ttl(0); const service_t its_service = _info->get_service(); @@ -3106,10 +3131,15 @@ service_discovery_impl::stop_offer_service( } } } - // Sent stop offer - if(_info->is_in_mainphase() || stop_offer_required) { - send_stop_offer(_info); + + if (!_send) { + // stop offer required + return (_info->is_in_mainphase() || stop_offer_required); + } else if(_info->is_in_mainphase() || stop_offer_required) { + // Send stop offer + return send_stop_offer(_info); } + return false; // sent out NACKs for all pending subscriptions // TODO: remote_subscription_not_acknowledge_all(its_service, its_instance); } @@ -3131,11 +3161,30 @@ service_discovery_impl::send_stop_offer(const std::shared_ptr &_inf return false; } +bool +service_discovery_impl::send_collected_stop_offers(const std::vector> &_infos) { + + std::vector > its_messages; + std::shared_ptr its_current_message( + std::make_shared()); + its_messages.push_back(its_current_message); + + // pack multiple stop offers together + for (auto its_info : _infos) { + if (its_info->get_endpoint(false) || its_info->get_endpoint(true)) { + insert_offer_service(its_messages, its_info); + } + } + + // Serialize and send + return send(its_messages); +} + void service_discovery_impl::start_main_phase_timer() { std::lock_guard its_lock(main_phase_timer_mutex_); boost::system::error_code ec; - main_phase_timer_.expires_from_now(cyclic_offer_delay_); + main_phase_timer_.expires_from_now(cyclic_offer_delay_, ec); if (ec) { VSOMEIP_ERROR<< "service_discovery_impl::start_main_phase_timer " "setting expiry time of timer failed: " << ec.message(); @@ -3249,7 +3298,6 @@ service_discovery_impl::update_acknowledgement( } } - void service_discovery_impl::update_subscription_expiration_timer( const std::vector > &_messages) { @@ -3426,10 +3474,12 @@ service_discovery_impl::on_last_msg_received_timer_expired( // Rejoin multicast group if (endpoint_ && !reliable_) { - auto its_endpoint = std::dynamic_pointer_cast< - udp_server_endpoint_impl>(endpoint_); - if (its_endpoint) - its_endpoint->join(sd_multicast_); + auto its_server_endpoint + = std::dynamic_pointer_cast(endpoint_); + if (its_server_endpoint) { + its_server_endpoint->leave(sd_multicast_); + its_server_endpoint->join(sd_multicast_); + } } { boost::system::error_code ec; @@ -3450,7 +3500,7 @@ service_discovery_impl::stop_last_msg_received_timer() { last_msg_received_timer_.cancel(ec); } -service_discovery_impl::remote_offer_type_e +reliability_type_e service_discovery_impl::get_remote_offer_type( service_t _service, instance_t _instance) const { std::lock_guard its_lock(remote_offer_types_mutex_); @@ -3458,10 +3508,10 @@ service_discovery_impl::get_remote_offer_type( if (found_si != remote_offer_types_.end()) { return found_si->second; } - return remote_offer_type_e::UNKNOWN; + return reliability_type_e::RT_UNKNOWN; } -service_discovery_impl::remote_offer_type_e +reliability_type_e service_discovery_impl::get_remote_offer_type( const std::shared_ptr &_subscription) const { bool has_reliable = (_subscription->get_endpoint(true) != nullptr); @@ -3469,18 +3519,18 @@ service_discovery_impl::get_remote_offer_type( return (has_reliable ? (has_unreliable ? - remote_offer_type_e::RELIABLE_UNRELIABLE : - remote_offer_type_e::RELIABLE) : + reliability_type_e::RT_BOTH : + reliability_type_e::RT_RELIABLE) : (has_unreliable ? - remote_offer_type_e::UNRELIABLE : - remote_offer_type_e::UNKNOWN)); + reliability_type_e::RT_UNRELIABLE : + reliability_type_e::RT_UNKNOWN)); } bool service_discovery_impl::update_remote_offer_type( service_t _service, instance_t _instance, - remote_offer_type_e _offer_type, + reliability_type_e _offer_type, const boost::asio::ip::address &_reliable_address, std::uint16_t _reliable_port, const boost::asio::ip::address &_unreliable_address, @@ -3498,26 +3548,26 @@ service_discovery_impl::update_remote_offer_type( remote_offer_types_[its_si_pair] = _offer_type; } switch (_offer_type) { - case remote_offer_type_e::UNRELIABLE: + case reliability_type_e::RT_UNRELIABLE: remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::RELIABLE: + case reliability_type_e::RT_RELIABLE: remote_offers_by_ip_[_reliable_address][std::make_pair(true, _reliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: + case reliability_type_e::RT_BOTH: remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert(its_si_pair); remote_offers_by_ip_[_unreliable_address][std::make_pair(true, _reliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::UNKNOWN: + case reliability_type_e::RT_UNKNOWN: default: VSOMEIP_WARNING << __func__ << ": unknown offer type [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]" - << _offer_type; + << static_cast(_offer_type); break; } return ret; @@ -3754,13 +3804,13 @@ service_discovery_impl::add_entry_data_to_remote_subscription_ack_msg( void service_discovery_impl::register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) { + const sd_acceptance_handler_t &_handler) { sd_acceptance_handler_ = _handler; } void service_discovery_impl::register_reboot_notification_handler( - reboot_notification_handler_t _handler) { + const reboot_notification_handler_t &_handler) { reboot_notification_handler_ = _handler; } @@ -3775,19 +3825,7 @@ reliability_type_e service_discovery_impl::get_eventgroup_reliability( && its_info->is_reliability_auto_mode()) { // fallback: determine how service is offered // and update reliability type of eventgroup - switch (get_remote_offer_type(_service, _instance)) { - case remote_offer_type_e::RELIABLE: - its_reliability = reliability_type_e::RT_RELIABLE; - break; - case remote_offer_type_e::UNRELIABLE: - its_reliability = reliability_type_e::RT_UNRELIABLE; - break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: - its_reliability = reliability_type_e::RT_BOTH; - break; - default: - ; - } + its_reliability = get_remote_offer_type(_service, _instance); VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine eventgroup reliability type for [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." @@ -3814,10 +3852,8 @@ reliability_type_e service_discovery_impl::get_eventgroup_reliability( << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } - return its_reliability; } - } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/src/serviceentry_impl.cpp b/implementation/service_discovery/src/serviceentry_impl.cpp old mode 100755 new mode 100644 index 9ea86b132..f3fc70da0 --- a/implementation/service_discovery/src/serviceentry_impl.cpp +++ b/implementation/service_discovery/src/serviceentry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp index 9a95bec4d..8ceaf1b7c 100644 --- a/implementation/service_discovery/src/subscription.cpp +++ b/implementation/service_discovery/src/subscription.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -100,7 +100,7 @@ std::set subscription::get_clients() const { std::set its_clients; { std::lock_guard its_lock(clients_mutex_); - for (const auto& its_item : clients_) + for (const auto its_item : clients_) its_clients.insert(its_item.first); } return its_clients; diff --git a/implementation/tracing/include/channel_impl.hpp b/implementation/tracing/include/channel_impl.hpp index cc2e5831a..a00d8c515 100644 --- a/implementation/tracing/include/channel_impl.hpp +++ b/implementation/tracing/include/channel_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,12 +12,13 @@ #include #include +#include "enumeration_types.hpp" #include namespace vsomeip_v3 { namespace trace { -typedef std::function filter_func_t; +using filter_func_t = std::function; class channel_impl : public channel { public: @@ -26,6 +27,10 @@ class channel_impl : public channel { std::string get_id() const; std::string get_name() const; + filter_id_t add_filter( + const match_t &_match, + filter_type_e _type); + filter_id_t add_filter( const match_t &_match, bool _is_positive); @@ -34,24 +39,32 @@ class channel_impl : public channel { const std::vector &_matches, bool _is_positive); + filter_id_t add_filter( + const std::vector &_matches, + filter_type_e _type); + filter_id_t add_filter( const match_t &_from, const match_t &_to, bool _is_positive); + filter_id_t add_filter( + const match_t &_from, const match_t &_to, + filter_type_e _type); + void remove_filter( filter_id_t _id); - bool matches(service_t _service, instance_t _instance, method_t _method); + std::pair matches(service_t _service, instance_t _instance, method_t _method); private: - filter_id_t add_filter_intern(const filter_func_t& _func, bool _is_positive); + filter_id_t add_filter_intern(const filter_func_t& _func, filter_type_e _type); std::string id_; std::string name_; std::atomic current_filter_id_; - std::map positive_; + std::map> positive_; std::map negative_; std::mutex mutex_; // protects positive_ & negative_ }; diff --git a/implementation/tracing/include/connector_impl.hpp b/implementation/tracing/include/connector_impl.hpp index 8274b9fa8..e5c90d2ad 100644 --- a/implementation/tracing/include/connector_impl.hpp +++ b/implementation/tracing/include/connector_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -7,8 +7,10 @@ #define VSOMEIP_V3_TRACE_CONNECTOR_HPP_ #ifdef USE_DLT +#ifndef ANDROID #include #endif +#endif #include #include @@ -58,7 +60,7 @@ class connector_impl : public connector { VSOMEIP_EXPORT std::shared_ptr get_channel(const std::string &_id) const; VSOMEIP_EXPORT void trace(const byte_t *_header, uint16_t _header_size, - const byte_t *_data, uint16_t _data_size); + const byte_t *_data, uint32_t _data_size); private: bool is_enabled_; @@ -67,10 +69,14 @@ class connector_impl : public connector { std::map> channels_; mutable std::mutex channels_mutex_; + std::shared_ptr get_channel_impl(const std::string &_id) const; + #ifdef USE_DLT +#ifndef ANDROID std::map> contexts_; mutable std::mutex contexts_mutex_; #endif +#endif }; diff --git a/implementation/tracing/include/defines.hpp b/implementation/tracing/include/defines.hpp index 022f42fb4..fd5e8f804 100644 --- a/implementation/tracing/include/defines.hpp +++ b/implementation/tracing/include/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/tracing/include/enumeration_types.hpp b/implementation/tracing/include/enumeration_types.hpp index 3f8358695..9f5f6e805 100644 --- a/implementation/tracing/include/enumeration_types.hpp +++ b/implementation/tracing/include/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,8 @@ namespace trace { enum class filter_type_e : uint8_t { NEGATIVE = 0x00, - POSITIVE = 0x01 + POSITIVE = 0x01, + HEADER_ONLY = 0x02 }; } // namespace trace diff --git a/implementation/tracing/include/header.hpp b/implementation/tracing/include/header.hpp index e3dc4c1a1..190a15fe3 100644 --- a/implementation/tracing/include/header.hpp +++ b/implementation/tracing/include/header.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/tracing/src/channel_impl.cpp b/implementation/tracing/src/channel_impl.cpp index c0bc39185..26dccd348 100644 --- a/implementation/tracing/src/channel_impl.cpp +++ b/implementation/tracing/src/channel_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,14 @@ std::string channel_impl::get_name() const { filter_id_t channel_impl::add_filter( const match_t &_match, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_match, its_filter_type)); +} + +filter_id_t channel_impl::add_filter( + const match_t &_match, filter_type_e _type) { // Create a filter function std::function its_filter_func; @@ -86,11 +94,19 @@ filter_id_t channel_impl::add_filter( } } - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); } filter_id_t channel_impl::add_filter( const std::vector &_matches, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_matches, its_filter_type)); +} + +filter_id_t channel_impl::add_filter( + const std::vector &_matches, filter_type_e _type) { bool has_service(false); bool has_instance(false); bool has_method(false); @@ -197,11 +213,11 @@ filter_id_t channel_impl::add_filter( } } - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); } filter_id_t channel_impl::add_filter( - const match_t &_from, const match_t &_to, bool _is_positive) { + const match_t &_from, const match_t &_to, filter_type_e _type) { // Check usage of ANY_* which is forbidden here if (std::get<0>(_from) == ANY_SERVICE || @@ -222,7 +238,15 @@ filter_id_t channel_impl::add_filter( && std::get<2>(_from) <= _m && _m <= std::get<2>(_to)); }; - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); +} + +filter_id_t channel_impl::add_filter( + const match_t &_from, const match_t &_to, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_from, _to, its_filter_type)); } void channel_impl::remove_filter(filter_id_t _id) { @@ -231,42 +255,52 @@ void channel_impl::remove_filter(filter_id_t _id) { negative_.erase(_id); } -filter_id_t channel_impl::add_filter_intern(const filter_func_t& _func, bool _is_positive) { +filter_id_t channel_impl::add_filter_intern(const filter_func_t& _func, filter_type_e _type) { filter_id_t its_id = current_filter_id_.fetch_add(1); std::lock_guard its_lock(mutex_); - if (_is_positive) - positive_[its_id] = _func; - else - negative_[its_id] = _func; + switch(_type) { + case (filter_type_e::NEGATIVE) : + negative_[its_id] = _func; + break; + case (filter_type_e::HEADER_ONLY) : + positive_[its_id] = std::make_pair(_func, false); + break; + default : + positive_[its_id] = std::make_pair(_func, true); + } return its_id; } -bool channel_impl::matches( +std::pair channel_impl::matches( service_t _service, instance_t _instance, method_t _method) { std::lock_guard its_lock(mutex_); // If a negative filter matches --> drop! for (auto &its_filter : negative_) { - if (its_filter.second(_service, _instance, _method)) { - return false; - } + if (its_filter.second(_service, _instance, _method)) + return std::make_pair(false, false); } - // If no positive filter is defined --> forward! - if (positive_.size() == 0) - return true; - - // If a positive filter matches --> forward! + // If a positive/header-only filter matches --> forward! + bool has_positive(false); for (auto &its_filter : positive_) { - if (its_filter.second(_service, _instance, _method)) { - return true; - } + if (its_filter.second.first(_service, _instance, _method)) + return std::make_pair(true, its_filter.second.second); + + // If we have a positive filter that is no header-only + // filter, set the flag + if (its_filter.second.second) + has_positive = true; } - // drop! - return false; + // If no positive filter is defined --> forward! + if (!has_positive) + return std::make_pair(true, true); + + // Default --> Drop! + return std::make_pair(false, false); } } // namespace trace diff --git a/implementation/tracing/src/connector_impl.cpp b/implementation/tracing/src/connector_impl.cpp index f71c92eb5..2f93bd098 100644 --- a/implementation/tracing/src/connector_impl.cpp +++ b/implementation/tracing/src/connector_impl.cpp @@ -1,10 +1,16 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include +#include +#include +#include +#include +#include #include "../include/channel_impl.hpp" #include "../include/connector_impl.hpp" @@ -12,6 +18,20 @@ #include "../../configuration/include/trace.hpp" #include "../../utility/include/byteorder.hpp" +#ifdef ANDROID +#include + +#ifdef ALOGI +#undef ALOGI +#endif + +#define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGI ALOGI +#endif + +#endif + namespace vsomeip_v3 { namespace trace { @@ -30,6 +50,7 @@ connector_impl::connector_impl() : = std::make_shared(VSOMEIP_TC_DEFAULT_CHANNEL_ID, VSOMEIP_TC_DEFAULT_CHANNEL_NAME); #ifdef USE_DLT +#ifndef ANDROID std::shared_ptr its_default_context = std::make_shared(); @@ -38,6 +59,7 @@ connector_impl::connector_impl() : VSOMEIP_TC_DEFAULT_CHANNEL_ID, VSOMEIP_TC_DEFAULT_CHANNEL_NAME, DLT_LOG_INFO, DLT_TRACE_STATUS_ON); #endif +#endif } connector_impl::~connector_impl() { @@ -60,14 +82,14 @@ void connector_impl::configure(const std::shared_ptr &_configuration for (auto &its_filter : _configuration->filters_) { for (auto &its_channel : its_filter->channels_) { - std::shared_ptr its_channel_ptr = get_channel(its_channel); + auto its_channel_ptr = get_channel_impl(its_channel); if (its_channel_ptr) { if (its_filter->is_range_) { its_channel_ptr->add_filter(its_filter->matches_[0], - its_filter->matches_[1], its_filter->is_positive_); + its_filter->matches_[1], its_filter->ftype_); } else { its_channel_ptr->add_filter(its_filter->matches_, - its_filter->is_positive_); + its_filter->ftype_); } } } @@ -82,8 +104,10 @@ void connector_impl::configure(const std::shared_ptr &_configuration void connector_impl::reset() { #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); contexts_.clear(); +#endif #endif // reset to default std::lock_guard its_lock_channels(channels_mutex_); @@ -131,11 +155,13 @@ std::shared_ptr connector_impl::add_channel( // register context #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); std::shared_ptr its_context = std::make_shared(); contexts_[_id] = its_context; DLT_REGISTER_CONTEXT_LL_TS(*(its_context.get()), _id.c_str(), _name.c_str(), DLT_LOG_INFO, DLT_TRACE_STATUS_ON); +#endif #endif return its_channel; @@ -152,11 +178,13 @@ bool connector_impl::remove_channel(const trace_channel_t &_id) { if (has_removed) { // unregister context #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); auto its_context = contexts_.find(_id); if (its_context != contexts_.end()) { DLT_UNREGISTER_CONTEXT(*(its_context->second.get())); } +#endif #endif } @@ -169,16 +197,27 @@ std::shared_ptr connector_impl::get_channel(const std::string &_id) con return (its_channel != channels_.end() ? its_channel->second : nullptr); } +std::shared_ptr connector_impl::get_channel_impl(const std::string &_id) const { + std::lock_guard its_channels_lock(channels_mutex_); + auto its_channel = channels_.find(_id); + return (its_channel != channels_.end() ? its_channel->second : nullptr); +} + void connector_impl::trace(const byte_t *_header, uint16_t _header_size, - const byte_t *_data, uint16_t _data_size) { -#ifdef USE_DLT + const byte_t *_data, uint32_t _data_size) { + +#if USE_DLT if (!is_enabled_) return; if (_data_size == 0) return; // no data - if (is_sd_message(_data, _data_size) && !is_sd_enabled_) + // Clip + const uint16_t its_data_size + = uint16_t(_data_size > USHRT_MAX ? USHRT_MAX : _data_size); + + if (is_sd_message(_data, its_data_size) && !is_sd_enabled_) return; // tracing of service discovery messages is disabled! service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -197,19 +236,54 @@ void connector_impl::trace(const byte_t *_header, uint16_t _header_size, // Forward to channel if the filter set of the channel allows std::lock_guard its_channels_lock(channels_mutex_); - std::lock_guard its_contexts_lock(contexts_mutex_); + #ifndef ANDROID + std::lock_guard its_contexts_lock(contexts_mutex_); + #endif for (auto its_channel : channels_) { - if (its_channel.second->matches(its_service, its_instance, its_method)) { - auto its_context = contexts_.find(its_channel.second->get_id()); - if (its_context != contexts_.end()) { - DLT_TRACE_NETWORK_SEGMENTED(*(its_context->second.get()), - DLT_NW_TRACE_IPC, - _header_size, static_cast(const_cast(_header)), - _data_size, static_cast(const_cast(_data))); - } else { - // This should never happen! - VSOMEIP_ERROR << "tracing: found channel without DLT context!"; - } + auto ftype = its_channel.second->matches(its_service, its_instance, its_method); + if (ftype.first) { + #ifndef ANDROID + auto its_context = contexts_.find(its_channel.second->get_id()); + if (its_context != contexts_.end()) { + try { + if (ftype.second) { + //Positive Filter + DLT_TRACE_NETWORK_SEGMENTED(*(its_context->second.get()), + DLT_NW_TRACE_IPC, + _header_size, static_cast(const_cast(_header)), + its_data_size, static_cast(const_cast(_data))); + } else { + //Header-Only Filter + DLT_TRACE_NETWORK_TRUNCATED(*(its_context->second.get()), + DLT_NW_TRACE_IPC, + _header_size, static_cast(const_cast(_header)), + VSOMEIP_FULL_HEADER_SIZE, + static_cast(const_cast(_data))); + } + } catch (const std::exception& e) { + VSOMEIP_INFO << "connector_impl::trace: " + << "Exception caught when trying to log a trace with DLT. " + << e.what(); + } + } else { + // This should never happen! + VSOMEIP_ERROR << "tracing: found channel without DLT context!"; + } + #else + std::stringstream ss; + ss << "TC:"; + for(int i = 0; i < _header_size; i++) { + ss << ' ' << std::setfill('0') << std::setw(2) << std::hex << int(_header[i]); + } + if (ftype.second) + _data_size = VSOMEIP_FULL_HEADER_SIZE; + for(int i = 0; i < its_data_size; i++) { + ss << ' ' << std::setfill('0') << std::setw(2) << std::hex << int(_data[i]); + } + std::string app = runtime::get_property("LogApplication"); + + ALOGI(app.c_str(), ss.str().c_str()); + #endif } } #else diff --git a/implementation/tracing/src/header.cpp b/implementation/tracing/src/header.cpp index 0940e5987..bea82c38e 100644 --- a/implementation/tracing/src/header.cpp +++ b/implementation/tracing/src/header.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp index ad7f7520f..deda45c9c 100644 --- a/implementation/utility/include/byteorder.hpp +++ b/implementation/utility/include/byteorder.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,9 +6,9 @@ #ifndef VSOMEIP_V3_BYTEORDER_HPP #define VSOMEIP_V3_BYTEORDER_HPP -#if defined(LINUX) +#if defined(__linux__) #include -#elif defined(FREEBSD) +#elif defined(__freebsd__) #include #else // TEST IF THERE COULD BE AN ERROR! @@ -38,8 +38,6 @@ #define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x1) << 8 | (x0))) #define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x3) << 24 | (x2) << 16 | (x1) << 8 | (x0))) -#define VSOMEIP_WORDS_TO_LONG(x0, x1) (uint32_t((x1) << 16 | (x0))) - #define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) >> 8)) #define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) & 0xFF)) @@ -48,8 +46,8 @@ #define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 8) & 0xFF)) #define VSOMEIP_LONG_BYTE3(x) (uint8_t((x) & 0xFF)) -#define VSOMEIP_LONG_WORD0(x) (uint16_t(((x) >> 16) & 0xFFFF)) -#define VSOMEIP_LONG_WORD1(x) (uint16_t((x) & 0xFFFF)) +#define VSOMEIP_LONG_WORD0(x) (uint16_t((((x) >> 16) & 0xFFFF)) +#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) & 0xFFFF)) #else diff --git a/implementation/utility/include/criticalsection.hpp b/implementation/utility/include/criticalsection.hpp index 2040b7411..762c821a8 100644 --- a/implementation/utility/include/criticalsection.hpp +++ b/implementation/utility/include/criticalsection.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index 359bc7c06..970fb0f0e 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,11 +6,12 @@ #ifndef VSOMEIP_V3_UTILITY_HPP #define VSOMEIP_V3_UTILITY_HPP +#include +#include #include -#include #include +#include #include -#include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -19,6 +20,8 @@ #include #include +#include + #include "criticalsection.hpp" namespace vsomeip_v3 { @@ -36,7 +39,9 @@ class utility { } static inline bool is_request(message_type_e _type) { - return (_type < message_type_e::MT_NOTIFICATION); + return ((_type < message_type_e::MT_NOTIFICATION) + || (_type >= message_type_e::MT_REQUEST_ACK + && _type <= message_type_e::MT_REQUEST_NO_RETURN_ACK)); } static inline bool is_request_no_return(std::shared_ptr _message) { @@ -68,10 +73,6 @@ class utility { return _type == message_type_e::MT_ERROR; } - static inline bool is_event(byte_t _data) { - return (0x80 & _data) > 0; - } - static inline bool is_notification(byte_t _type) { return (is_notification(static_cast(_type))); } @@ -90,19 +91,20 @@ class utility { static uint32_t get_payload_size(const byte_t *_data, uint32_t _size); - static bool is_routing_manager(const std::shared_ptr &_config); - static void remove_lockfile(const std::shared_ptr &_config); + static bool is_routing_manager(const std::string &_network); + static void remove_lockfile(const std::string &_network); static bool exists(const std::string &_path); static bool VSOMEIP_IMPORT_EXPORT is_file(const std::string &_path); static bool VSOMEIP_IMPORT_EXPORT is_folder(const std::string &_path); - static const std::string get_base_path(const std::shared_ptr &_config); + static std::string get_base_path(const std::string &_network); static client_t request_client_id(const std::shared_ptr &_config, const std::string &_name, client_t _client); - static void release_client_id(client_t _client); - static std::set get_used_client_ids(); - static void reset_client_ids(); + static void release_client_id(const std::string &_network, + client_t _client); + static std::set get_used_client_ids(const std::string &_network); + static void reset_client_ids(const std::string &_network); static inline bool is_valid_message_type(message_type_e _type) { return (_type == message_type_e::MT_REQUEST @@ -129,27 +131,52 @@ class utility { || _code == return_code_e::E_WRONG_PROTOCOL_VERSION || _code == return_code_e::E_WRONG_INTERFACE_VERSION || _code == return_code_e::E_MALFORMED_MESSAGE - || _code == return_code_e::E_WRONG_MESSAGE_TYPE - || (static_cast(_code) >= 0x20 - && static_cast(_code) <= 0x5E)); + || _code == return_code_e::E_WRONG_MESSAGE_TYPE); + } + + static inline bool compare(const vsomeip_sec_client_t &_lhs, + const vsomeip_sec_client_t &_rhs) { + + bool is_equal(false); + if (_lhs.client_type == _rhs.client_type) { + switch (_lhs.client_type) { + case VSOMEIP_CLIENT_INVALID: + is_equal = true; + break; + case VSOMEIP_CLIENT_UDS: + is_equal = (_lhs.client.uds_client.user == _rhs.client.uds_client.user + && _lhs.client.uds_client.group == _rhs.client.uds_client.group); + break; + case VSOMEIP_CLIENT_TCP: + is_equal = (_lhs.client.ip_client.ip == _rhs.client.ip_client.ip + && _lhs.client.ip_client.port == _rhs.client.ip_client.port); + break; + default: + break; + } + } + return (is_equal); } private: - static std::uint16_t get_max_client_number(const std::shared_ptr &_config); + struct data_t { + data_t(); - static std::mutex mutex__; - static client_t next_client__; - static std::map used_clients__; + client_t next_client_; + std::map used_clients_; #ifdef _WIN32 - static HANDLE lock_handle__; -#else - static int lock_fd__; -#endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - static bool is_checked__; + HANDLE lock_handle_; #else - static std::set is_checked__; + int lock_fd_; #endif + }; + +private: + static std::uint16_t get_max_client_number( + const std::shared_ptr &_config); + + static std::mutex mutex__; + static std::map data__; // network --> data }; } // namespace vsomeip_v3 diff --git a/implementation/utility/src/criticalsection.cpp b/implementation/utility/src/criticalsection.cpp index 78b0b5cbe..197ca4d34 100644 --- a/implementation/utility/src/criticalsection.cpp +++ b/implementation/utility/src/criticalsection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp index 139faefdd..a3ed5d105 100644 --- a/implementation/utility/src/utility.cpp +++ b/implementation/utility/src/utility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -32,18 +32,16 @@ namespace vsomeip_v3 { std::mutex utility::mutex__; -client_t utility::next_client__(VSOMEIP_CLIENT_UNSET); -std::map utility::used_clients__; +std::map utility::data__; + +utility::data_t::data_t() + : next_client_(VSOMEIP_CLIENT_UNSET), #ifdef _WIN32 -HANDLE utility::lock_handle__(INVALID_HANDLE_VALUE); -#else -int utility::lock_fd__(-1); -#endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS -bool utility::is_checked__(false); + lock_handle_(INVALID_HANDLE_VALUE) #else -std::set utility::is_checked__; + lock_fd_(-1) #endif +{} uint64_t utility::get_message_size(const byte_t *_data, size_t _size) { uint64_t its_size(0); @@ -63,55 +61,45 @@ uint32_t utility::get_payload_size(const byte_t *_data, uint32_t _size) { return (its_size); } -bool utility::is_routing_manager(const std::shared_ptr &_config) { +bool utility::is_routing_manager(const std::string &_network) { // Only the first caller can become routing manager. // Therefore, subsequent calls can be immediately answered... std::lock_guard its_lock(mutex__); -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - if (is_checked__) - return false; + if (data__.find(_network) != data__.end()) + return (false); - is_checked__ = true; -#else - if (is_checked__.find(_config->get_network()) != is_checked__.end()) - return false; + auto r = data__.insert(std::make_pair(_network, data_t())); + if (!r.second) + return (false); - is_checked__.insert(_config->get_network()); -#endif #ifdef _WIN32 wchar_t its_tmp_folder[MAX_PATH]; if (GetTempPathW(MAX_PATH, its_tmp_folder)) { std::wstring its_lockfile(its_tmp_folder); - std::string its_network(_config->get_network() + ".lck"); + std::string its_network(_network + ".lck"); its_lockfile.append(its_network.begin(), its_network.end()); - lock_handle__ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); - if (lock_handle__ == INVALID_HANDLE_VALUE) { + r.first->second.lock_handle_ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); + if (r.first->second.lock_handle_ == INVALID_HANDLE_VALUE) { VSOMEIP_ERROR << __func__ << ": CreateFileW failed: " << std::hex << GetLastError(); } } else { VSOMEIP_ERROR << __func__ << ": Could not get temp folder: " << std::hex << GetLastError(); - lock_handle__ = INVALID_HANDLE_VALUE; + r.first->second.lock_handle_ = INVALID_HANDLE_VALUE; } - return (lock_handle__ != INVALID_HANDLE_VALUE); + return (r.first->second.lock_handle_ != INVALID_HANDLE_VALUE); #else - std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - its_base_path = {env_base_path + _config->get_network()}; - } -#endif + std::string its_base_path(VSOMEIP_BASE_PATH + _network); std::string its_lockfile(its_base_path + ".lck"); int its_lock_ctrl(-1); struct flock its_lock_data = { F_WRLCK, SEEK_SET, 0, 0, 0 }; - lock_fd__ = open(its_lockfile.c_str(), O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP); - if (-1 != lock_fd__) { + r.first->second.lock_fd_ = open(its_lockfile.c_str(), O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP); + if (-1 != r.first->second.lock_fd_) { its_lock_data.l_pid = getpid(); - its_lock_ctrl = fcntl(lock_fd__, F_SETLK, &its_lock_data); + its_lock_ctrl = fcntl(r.first->second.lock_fd_, F_SETLK, &its_lock_data); } else { VSOMEIP_ERROR << __func__ << ": Could not open " << its_lockfile << ": " << std::strerror(errno); @@ -121,26 +109,23 @@ bool utility::is_routing_manager(const std::shared_ptr &_config) #endif } -void utility::remove_lockfile(const std::shared_ptr &_config) { +void utility::remove_lockfile(const std::string &_network) { std::lock_guard its_lock(mutex__); -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - if (!is_checked__) // No need to do anything as automatic - return; -#else - if (is_checked__.find(_config->get_network()) == is_checked__.end()) // No need to do anything as automatic + + auto r = data__.find(_network); + if (r == data__.end()) // No need to do anything as automatic return; -#endif #ifdef _WIN32 - if (lock_handle__ != INVALID_HANDLE_VALUE) { - if (CloseHandle(lock_handle__) == 0) { + if (r->second.lock_handle_ != INVALID_HANDLE_VALUE) { + if (CloseHandle(r->second.lock_handle_) == 0) { VSOMEIP_ERROR << __func__ << ": CloseHandle failed." << std::hex << GetLastError(); } wchar_t its_tmp_folder[MAX_PATH]; if (GetTempPathW(MAX_PATH, its_tmp_folder)) { std::wstring its_lockfile(its_tmp_folder); - std::string its_network(_config->get_network() + ".lck"); + std::string its_network(_network + ".lck"); its_lockfile.append(its_network.begin(), its_network.end()); if (DeleteFileW(its_lockfile.c_str()) == 0) { VSOMEIP_ERROR << __func__ << ": DeleteFileW failed: " @@ -153,17 +138,11 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { } } #else - std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - its_base_path = {env_base_path + _config->get_network()}; - } -#endif + std::string its_base_path(VSOMEIP_BASE_PATH + _network); std::string its_lockfile(its_base_path + ".lck"); - if (lock_fd__ != -1) { - if (close(lock_fd__) == -1) { + if (r->second.lock_fd_ != -1) { + if (close(r->second.lock_fd_) == -1) { VSOMEIP_ERROR << __func__ << ": Could not close lock_fd__" << std::strerror(errno); } @@ -173,11 +152,7 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { << ": " << std::strerror(errno); } #endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - is_checked__ = false; -#else - is_checked__.erase(_config->get_network()); -#endif + data__.erase(_network); } bool utility::exists(const std::string &_path) { @@ -203,19 +178,8 @@ bool utility::is_folder(const std::string &_path) { return false; } -const std::string utility::get_base_path( - const std::shared_ptr &_config) { -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - std::string its_base_path(env_base_path + _config->get_network()); - return std::string(env_base_path + _config->get_network() + "-"); - } else { - return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); - } -#else - return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); -#endif +std::string utility::get_base_path(const std::string &_network) { + return std::string(VSOMEIP_BASE_PATH + _network + "-"); } client_t @@ -232,21 +196,25 @@ utility::request_client_id( static const client_t its_biggest_client = its_masked_diagnosis_address | its_client_mask; static const client_t its_smallest_client = its_masked_diagnosis_address; - if (next_client__ == VSOMEIP_CLIENT_UNSET) { - next_client__ = its_smallest_client; + auto r = data__.find(_config->get_network()); + if (r == data__.end()) + return (VSOMEIP_CLIENT_UNSET); + + if (r->second.next_client_ == VSOMEIP_CLIENT_UNSET) { + r->second.next_client_ = its_smallest_client; } if (_client != VSOMEIP_CLIENT_UNSET) { // predefined client identifier - const auto its_iterator = used_clients__.find(_client); - if (its_iterator == used_clients__.end()) { // unused identifier - used_clients__[_client] = _name; - return _client; + const auto its_iterator = r->second.used_clients_.find(_client); + if (its_iterator == r->second.used_clients_.end()) { // unused identifier + r->second.used_clients_[_client] = _name; + return (_client); } else { // already in use // The name matches the assigned name --> return client // NOTE: THIS REQUIRES A CONSISTENT CONFIGURATION!!! if (its_iterator->second == _name) { - return _client; + return (_client); } VSOMEIP_WARNING << "Requested client identifier " @@ -259,49 +227,58 @@ utility::request_client_id( } } - if (next_client__ == its_biggest_client) { + if (r->second.next_client_ == its_biggest_client) { // start at beginning of client range again when the biggest client was reached - next_client__ = its_smallest_client; + r->second.next_client_ = its_smallest_client; } std::uint16_t increase_count = 0; do { - next_client__ = (next_client__ & static_cast(~its_client_mask)) // save diagnosis address bits - | (static_cast((next_client__ // set all diagnosis address bits to one + r->second.next_client_ = (r->second.next_client_ + & static_cast(~its_client_mask)) // save diagnosis address bits + | (static_cast((r->second.next_client_ // set all diagnosis address bits to one | static_cast(~its_client_mask)) + 1u) // and add one to the result & its_client_mask); // set the diagnosis address bits to zero again if (increase_count++ == its_max_num_clients) { VSOMEIP_ERROR << __func__ << " no free client IDs left! " "Max amount of possible concurrent active vsomeip " - "applications reached (" << std::dec << used_clients__.size() + "applications reached (" << std::dec << r->second.used_clients_.size() << ")."; - return VSOMEIP_CLIENT_UNSET; + return (VSOMEIP_CLIENT_UNSET); } - } while (used_clients__.find(next_client__) != used_clients__.end() - || _config->is_configured_client_id(next_client__)); + } while (r->second.used_clients_.find(r->second.next_client_) != r->second.used_clients_.end() + || _config->is_configured_client_id(r->second.next_client_)); - used_clients__[next_client__] = _name; - return next_client__; + r->second.used_clients_[r->second.next_client_] = _name; + return (r->second.next_client_); } void -utility::release_client_id(client_t _client) { +utility::release_client_id(const std::string &_network, client_t _client) { std::lock_guard its_lock(mutex__); - used_clients__.erase(_client); + auto r = data__.find(_network); + if (r != data__.end()) + r->second.used_clients_.erase(_client); } std::set -utility::get_used_client_ids() { +utility::get_used_client_ids(const std::string &_network) { std::lock_guard its_lock(mutex__); std::set its_used_clients; - for (const auto& c : used_clients__) - its_used_clients.insert(c.first); + auto r = data__.find(_network); + if (r != data__.end()) { + for (const auto& c : r->second.used_clients_) + its_used_clients.insert(c.first); + } return its_used_clients; } -void utility::reset_client_ids() { +void utility::reset_client_ids(const std::string &_network) { std::lock_guard its_lock(mutex__); - used_clients__.clear(); - next_client__ = VSOMEIP_CLIENT_UNSET; + auto r = data__.find(_network); + if (r != data__.end()) { + r->second.used_clients_.clear(); + r->second.next_client_ = VSOMEIP_CLIENT_UNSET; + } } @@ -315,7 +292,7 @@ std::uint16_t utility::get_max_client_number( #else __builtin_popcount( #endif - static_cast(~_config->get_diagnosis_mask())); + static_cast(~_config->get_diagnosis_mask())); for (int var = 0; var < bits_for_clients; ++var) { its_max_clients = static_cast(its_max_clients | (1 << var)); } diff --git a/implementation/utility/src/wrappers.cpp b/implementation/utility/src/wrappers.cpp new file mode 100644 index 000000000..1b09e8c12 --- /dev/null +++ b/implementation/utility/src/wrappers.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifdef __linux__ + +#include +#include + +/* + * These definitions MUST remain in the global namespace. + */ +extern "C" +{ + /* + * The real socket(2), renamed by GCC. + */ + int __real_socket(int domain, int type, int protocol) noexcept; + + /* + * Overrides socket(2) to set SOCK_CLOEXEC by default. + */ + int __wrap_socket(int domain, int type, int protocol) noexcept + { + return __real_socket(domain, type | SOCK_CLOEXEC, protocol); + } + + /* + * Overrides accept(2) to set SOCK_CLOEXEC by default. + */ + int __wrap_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) + { + return accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); + } +} + +#endif diff --git a/interface/compat/vsomeip/constants.hpp b/interface/compat/vsomeip/constants.hpp index c91d03742..2d149202d 100644 --- a/interface/compat/vsomeip/constants.hpp +++ b/interface/compat/vsomeip/constants.hpp @@ -19,7 +19,7 @@ const ttl_t DEFAULT_TTL = 0xFFFFFF; // "until next reboot" const std::string DEFAULT_MULTICAST = "224.0.0.0"; const uint16_t DEFAULT_PORT = 30500; -const uint16_t ILLEGAL_PORT = 0; +const uint16_t ILLEGAL_PORT = 0xFFFF; const uint16_t NO_TRACE_FILTER_EXPRESSION = 0x0000; diff --git a/interface/compat/vsomeip/primitive_types.hpp b/interface/compat/vsomeip/primitive_types.hpp index 93c9960de..93237d05a 100644 --- a/interface/compat/vsomeip/primitive_types.hpp +++ b/interface/compat/vsomeip/primitive_types.hpp @@ -9,7 +9,7 @@ #include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif diff --git a/interface/compat/vsomeip/trace.hpp b/interface/compat/vsomeip/trace.hpp index ebdd4185d..db2054a72 100644 --- a/interface/compat/vsomeip/trace.hpp +++ b/interface/compat/vsomeip/trace.hpp @@ -153,29 +153,29 @@ class channel { */ class connector { public: - /** - * \brief Get access to the connector. - * - * \return Shared pointer to the singleton object. - */ + /** + * \brief Get access to the connector. + * + * \return Shared pointer to the singleton object. + */ static std::shared_ptr get(); virtual ~connector() {}; - /** - * \brief Add a trace channel to the connector. - * - * Creates a trace channel with the given identifier and name - * and adds it to the connector. - * - * \param _id Id of the trace channel. - * \param _name Name of the trace channel - * - * \return Shared pointer to the created trace channel or - * nullptr if the trace channel could not be created because - * another trace channel with the given identifier does - * already exist. - */ + /** + * \brief Add a trace channel to the connector. + * + * Creates a trace channel with the given identifier and name + * and adds it to the connector. + * + * \param _id Id of the trace channel. + * \param _name Name of the trace channel + * + * \return Shared pointer to the created trace channel or + * nullptr if the trace channel could not be created because + * another trace channel with the given identifier does + * already exist. + */ virtual std::shared_ptr add_channel( const std::string &_id, const std::string &_name) = 0; @@ -203,7 +203,7 @@ class connector { * of the default trace channel. * * \return Shared pointer to the created trace channel or - * nullptr if the trace channel does not exist. + * nullptr if the trace channel does not exist. */ virtual std::shared_ptr get_channel( const std::string &_id = VSOMEIP_TC_DEFAULT_CHANNEL_ID) const = 0; diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index 366ecf1b0..10ead3efe 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,14 +12,17 @@ #include #include +#include #include #include +#include #include #include #include namespace vsomeip_v3 { +class configuration; class configuration_public; class event; class payload; @@ -475,7 +478,7 @@ class application { * \param _handler Handler function to be called on state change. * */ - virtual void register_state_handler(state_handler_t _handler) = 0; + virtual void register_state_handler(const state_handler_t &_handler) = 0; /** * @@ -517,7 +520,7 @@ class application { */ virtual void register_message_handler(service_t _service, instance_t _instance, method_t _method, - message_handler_t _handler) = 0; + const message_handler_t &_handler) = 0; /** * * \brief Unregisters the message handler for the specified service @@ -559,7 +562,7 @@ class application { * */ virtual void register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, major_version_t _major = ANY_MAJOR, minor_version_t _minor = ANY_MINOR) = 0; /** @@ -599,35 +602,37 @@ class application { * handler decides if the subscription is accepted or not. * */ + VSOMEIP_DEPRECATED_UID_GID virtual void register_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - subscription_handler_t _handler) = 0; - - /** - * - * \brief Registers an async subscription handler. - * - * A subscription handler is called whenever the subscription state of an - * eventgroup changes. The callback is called with the client identifier - * and a boolean that indicates whether the client subscribed or - * unsubscribed. - * This method offers the possibility to asynchronously accept/rejects - * subscriptions through a callback. - * - * \param _service Service identifier of service instance whose - * subscription state is to be monitored. - * \param _instance Instance identifier of service instance whose - * subscription state is to be monitored. - * \param _eventgroup Eventgroup identifier of eventgroup whose - * subscription state is to be monitored. - * \param _handler Callback that shall be called. The value passed to the - * callback passed as a parameter to this handler decides if the - * subscription is accepted or not. - * - */ - virtual void register_async_subscription_handler( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - async_subscription_handler_t _handler) = 0; + const subscription_handler_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_t &_handler) = 0; /** * @@ -742,7 +747,7 @@ class application { * \param _offer_type type of offered services to be returned (OT_LOCAL = 0x00, OT_REMOTE = 0x01, OT_ALL = 0x02) * \param offered_services_handler_t handler which gets called with a vector of service instance pairs that are currently offered */ - virtual void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) = 0; + virtual void get_offered_services_async(offer_type_e _offer_type, const offered_services_handler_t &_handler) = 0; /** * @@ -769,7 +774,7 @@ class application { * \param _handler A watchdog handler, pass nullptr to deactivate. * \param _interval Call interval in seconds, pass std::chrono::seconds::zero() to deactivate. */ - virtual void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval) = 0; + virtual void set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval) = 0; /** * \brief Enables or disables calling of registered acceptance @@ -784,8 +789,8 @@ class application { * \param _enable enable or disable calling of offer acceptance handler */ virtual void set_sd_acceptance_required(const remote_info_t& _remote, - const std::string& _path, - bool _enable) = 0; + const std::string& _path, + bool _enable) = 0; /** * \brief Enables or disables calling of registered acceptance @@ -823,7 +828,7 @@ class application { * * \param _handler The handler to be called */ - virtual void register_sd_acceptance_handler(sd_acceptance_handler_t _handler) = 0; + virtual void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called upon detection of a @@ -835,7 +840,7 @@ class application { * \param _handler The handler to be called */ virtual void register_reboot_notification_handler( - reboot_notification_handler_t _handler) = 0; + const reboot_notification_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called when the routing reached @@ -847,7 +852,7 @@ class application { * \param _handler The handler to be called */ virtual void register_routing_ready_handler( - routing_ready_handler_t _handler) = 0; + const routing_ready_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called when the routing state @@ -859,7 +864,7 @@ class application { * \param _handler The handler to be called */ virtual void register_routing_state_handler( - routing_state_handler_t _handler) = 0; + const routing_state_handler_t &_handler) = 0; /** * \brief Update service configuration to offer a local service on the @@ -903,7 +908,7 @@ class application { uint32_t _gid, std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler) = 0; + const security_update_handler_t &_handler) = 0; /** * \brief Remove a security configuration for routing manager and all local clients @@ -919,7 +924,186 @@ class application { */ virtual void remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler) = 0; + const security_update_handler_t &_handler) = 0; + + /** + * + * \brief Registers a subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value returned by this + * handler decides if the subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_ext_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_ext_t &_handler) = 0; + + + /** + * + * \brief Subscribes to an eventgroup. + * + * A user application must call this function to subscribe to an eventgroup. + * Before calling subscribe it must register all events it interested in by + * calls to @ref request_event. The method additionally allows to specify + * a specific event. If a specific event is specified, all other events of + * the eventgroup are not received by the application. + * + * Note: For external services, providing a specific event does not change + * anything regarding the message routing. The specific event is only used + * to filter incoming events and to determine which initial events must be + * sent. + * + * \param _service Service identifier of the service that contains the + * eventgroup. + * \param _instance Instance identifier of the service that contains the + * eventgroup. + * \param _eventgroup Eventgroup identifier of the eventgroup. + * \param _major Major version number of the service. + * \param _event All (Default) or a specific event. + * \param _filter Filter configuration to decide whether or not an + * incoming event will be forwarded to the application. + */ + virtual void subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter) = 0; + + /** + * \brief Registers a handler which will be called upon reception of + * a remote VSOMEIP/SD message with the sending ECU's IP address and port as + * parameter + * + * This method has only an effect when called on the application acting as + * routing manager + * + * \param _handler The handler to be called + */ + virtual void register_message_acceptance_handler(const message_acceptance_handler_t &_handler) = 0; + + /** + * \brief Get the configuration additional data of an application plugin + * + * \return The configuration additional data of an application plugin + */ + virtual std::map get_additional_data( + const std::string &_plugin_name) = 0; + + + /** + * + * \brief Register a callback that is called when service instances + * availability (state) changes. + * + * This method allows for the registration of callbacks that are called + * whenever a service appears or disappears. It is possible to specify + * wildcards for service, instance and/or version. Additionally, the + * version specification is optional and defaults to DEFAULT_MAJOR + * /DEFAULT_MINOR. + * + * \param _service Service identifier of the service instance whose + * availability shall be reported. Can be set to ANY_SERVICE. + * \param _instance Instance identifier of the service instance whose + * availability shall be reported. Can be set to ANY_INSTANCE. + * \param _handler Callback to be called if availability (state) changes. + * \param _major Major service version. The parameter defaults to + * DEFAULT_MAJOR and can be set to ANY_MAJOR. + * \param _minor Minor service version. The parameter defaults to + * DEFAULT_MINOR and can be set to ANY_MINOR. + * + */ + virtual void register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, + major_version_t _major = ANY_MAJOR, minor_version_t _minor = ANY_MINOR) = 0; + + /** + * + * \brief Registers a subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * (vsomeip_sec_client_t-aware) + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value returned by this + * handler decides if the subscription is accepted or not. + * + */ + virtual void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * (vsomeip_sec_client_t-aware) + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler) = 0; }; /** @} */ diff --git a/interface/vsomeip/constants.hpp b/interface/vsomeip/constants.hpp index 3a8201a18..2b040c5ea 100644 --- a/interface/vsomeip/constants.hpp +++ b/interface/vsomeip/constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,14 @@ const ttl_t DEFAULT_TTL = 0xFFFFFF; // "until next reboot" const std::string DEFAULT_MULTICAST = "224.0.0.0"; const uint16_t DEFAULT_PORT = 30500; -const uint16_t ILLEGAL_PORT = 0; +const uint16_t ILLEGAL_PORT = 0xFFFF; const uint16_t ANY_PORT = 0; const uint16_t NO_TRACE_FILTER_EXPRESSION = 0x0000; const service_t ANY_SERVICE = 0xFFFF; const instance_t ANY_INSTANCE = 0xFFFF; +const eventgroup_t ANY_EVENTGROUP = 0xFFFF; const method_t ANY_METHOD = 0xFFFF; const major_version_t ANY_MAJOR = 0xFF; const minor_version_t ANY_MINOR = 0xFFFFFFFF; diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp index e10c45353..6485380f0 100644 --- a/interface/vsomeip/defines.hpp +++ b/interface/vsomeip/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,36 +6,39 @@ #ifndef VSOMEIP_V3_DEFINES_HPP_ #define VSOMEIP_V3_DEFINES_HPP_ -#define VSOMEIP_PROTOCOL_VERSION 0x1 +#include +#include + +constexpr std::uint8_t VSOMEIP_PROTOCOL_VERSION = 0x1; // 0 = unlimited, if not specified otherwise via configuration file -#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 0 +constexpr std::size_t VSOMEIP_MAX_LOCAL_MESSAGE_SIZE = 0; // 0 = unlimited, if not specified otherwise via configuration file -#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 0 -#define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1416 - -#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE - -#define VSOMEIP_SOMEIP_HEADER_SIZE 8 -#define VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE 8 -#define VSOMEIP_FULL_HEADER_SIZE 16 - -#define VSOMEIP_SERVICE_POS_MIN 0 -#define VSOMEIP_SERVICE_POS_MAX 1 -#define VSOMEIP_METHOD_POS_MIN 2 -#define VSOMEIP_METHOD_POS_MAX 3 -#define VSOMEIP_EVENT_POS_MIN 2 -#define VSOMEIP_EVENT_POS_MAX 3 -#define VSOMEIP_LENGTH_POS_MIN 4 -#define VSOMEIP_LENGTH_POS_MAX 7 -#define VSOMEIP_CLIENT_POS_MIN 8 -#define VSOMEIP_CLIENT_POS_MAX 9 -#define VSOMEIP_SESSION_POS_MIN 10 -#define VSOMEIP_SESSION_POS_MAX 11 -#define VSOMEIP_PROTOCOL_VERSION_POS 12 -#define VSOMEIP_INTERFACE_VERSION_POS 13 -#define VSOMEIP_MESSAGE_TYPE_POS 14 -#define VSOMEIP_RETURN_CODE_POS 15 -#define VSOMEIP_PAYLOAD_POS 16 +constexpr std::size_t VSOMEIP_MAX_TCP_MESSAGE_SIZE = 0; +constexpr std::size_t VSOMEIP_MAX_UDP_MESSAGE_SIZE = 1416; + +constexpr std::size_t VSOMEIP_PACKET_SIZE = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + +constexpr std::size_t VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE = 8; +constexpr std::uint32_t VSOMEIP_SOMEIP_HEADER_SIZE = 8; +constexpr std::uint32_t VSOMEIP_FULL_HEADER_SIZE = 16; + +constexpr std::size_t VSOMEIP_SERVICE_POS_MIN = 0; +constexpr std::size_t VSOMEIP_SERVICE_POS_MAX = 1; +constexpr std::size_t VSOMEIP_METHOD_POS_MIN = 2; +constexpr std::size_t VSOMEIP_METHOD_POS_MAX = 3; +constexpr std::size_t VSOMEIP_EVENT_POS_MIN = 2; +constexpr std::size_t VSOMEIP_EVENT_POS_MAX = 3; +constexpr std::size_t VSOMEIP_LENGTH_POS_MIN = 4; +constexpr std::size_t VSOMEIP_LENGTH_POS_MAX = 7; +constexpr std::size_t VSOMEIP_CLIENT_POS_MIN = 8; +constexpr std::size_t VSOMEIP_CLIENT_POS_MAX = 9; +constexpr std::size_t VSOMEIP_SESSION_POS_MIN = 10; +constexpr std::size_t VSOMEIP_SESSION_POS_MAX = 11; +constexpr std::size_t VSOMEIP_PROTOCOL_VERSION_POS = 12; +constexpr std::size_t VSOMEIP_INTERFACE_VERSION_POS = 13; +constexpr std::size_t VSOMEIP_MESSAGE_TYPE_POS = 14; +constexpr std::size_t VSOMEIP_RETURN_CODE_POS = 15; +constexpr std::size_t VSOMEIP_PAYLOAD_POS = 16; #endif // VSOMEIP_V3_DEFINES_HPP_ diff --git a/interface/vsomeip/deprecated.hpp b/interface/vsomeip/deprecated.hpp new file mode 100644 index 000000000..9ba023573 --- /dev/null +++ b/interface/vsomeip/deprecated.hpp @@ -0,0 +1,10 @@ +#ifndef VSOMEIP_V3_DEPRECATED_HPP_ +#define VSOMEIP_V3_DEPRECATED_HPP_ + +#ifdef VSOMEIP_INTERNAL_SUPPRESS_DEPRECATED +#define VSOMEIP_DEPRECATED_UID_GID +#else +#define VSOMEIP_DEPRECATED_UID_GID [[deprecated("Use vsomeip_sec_client_t-aware functions and types instead.")]] +#endif + +#endif // VSOMEIP_V3_DEPRECATED_HPP_ diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index a6bc3154f..8229a8952 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -88,6 +88,13 @@ enum class reliability_type_e : uint8_t { RT_UNKNOWN = 0xFF }; +enum class availability_state_e : uint8_t { + AS_UNAVAILABLE = 0x00, // unseen + AS_OFFERED = 0x01, // seen, but not requested/not yet usable + AS_AVAILABLE = 0x02, // seen and usable + AS_UNKNOWN = 0xFF +}; + } // namespace vsomeip_v3 #endif // VSOMEIP_V3_ENUMERATION_TYPES_HPP_ diff --git a/interface/vsomeip/error.hpp b/interface/vsomeip/error.hpp index 8415d90fa..ecbf591a7 100644 --- a/interface/vsomeip/error.hpp +++ b/interface/vsomeip/error.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/function_types.hpp b/interface/vsomeip/function_types.hpp index 31ef9d509..61030256a 100644 --- a/interface/vsomeip/function_types.hpp +++ b/interface/vsomeip/function_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/handler.hpp b/interface/vsomeip/handler.hpp index 7e2bbe9f2..f95ed7b0d 100644 --- a/interface/vsomeip/handler.hpp +++ b/interface/vsomeip/handler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,7 +10,9 @@ #include #include +#include #include +#include namespace vsomeip_v3 { @@ -19,15 +21,26 @@ class message; typedef std::function< void (state_type_e) > state_handler_t; typedef std::function< void (const std::shared_ptr< message > &) > message_handler_t; typedef std::function< void (service_t, instance_t, bool) > availability_handler_t; -typedef std::function< bool (client_t, uid_t, gid_t, bool) > subscription_handler_t; +typedef std::function< void (service_t, instance_t, availability_state_e) > availability_state_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< bool (client_t, uid_t, gid_t, bool) > subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< bool (client_t, uid_t, gid_t, const std::string &, bool) > subscription_handler_ext_t; typedef std::function< void (const uint16_t) > error_handler_t; typedef std::function< void (const service_t, const instance_t, const eventgroup_t, const event_t, const uint16_t) > subscription_status_handler_t; -typedef std::function< void (client_t, uid_t, gid_t, bool, std::function< void (const bool) > )> async_subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< void (client_t, uid_t, gid_t, bool, + std::function< void (const bool) > )> async_subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< void (client_t, uid_t, gid_t, const std::string &, bool, + std::function< void (const bool) > )> async_subscription_handler_ext_t; typedef std::function< void (const std::vector> &_services) > offered_services_handler_t; typedef std::function< void () > watchdog_handler_t; +/* + * vsomeip_sec_client_t-aware subscription handlers + */ +using subscription_handler_sec_t = std::function; +using async_subscription_handler_sec_t = std::function)>; + struct ip_address_t { union { ipv4_address_t v4_; @@ -77,11 +90,20 @@ struct remote_info_t { } }; +struct message_acceptance_t { + std::uint32_t remote_address_; + std::uint16_t local_port_; + bool is_local_; + service_t service_; + instance_t instance_; +}; + typedef std::function sd_acceptance_handler_t; typedef std::function reboot_notification_handler_t; typedef std::function routing_ready_handler_t; typedef std::function routing_state_handler_t; typedef std::function security_update_handler_t; +typedef std::function message_acceptance_handler_t; } // namespace vsomeip_v3 diff --git a/interface/vsomeip/internal/deserializable.hpp b/interface/vsomeip/internal/deserializable.hpp index ae661e577..b2a549ec4 100644 --- a/interface/vsomeip/internal/deserializable.hpp +++ b/interface/vsomeip/internal/deserializable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/internal/logger.hpp b/interface/vsomeip/internal/logger.hpp index db92b861b..4d1f4b64f 100644 --- a/interface/vsomeip/internal/logger.hpp +++ b/interface/vsomeip/internal/logger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/internal/policy_manager.hpp b/interface/vsomeip/internal/policy_manager.hpp index 45756ec65..0d610d9ef 100644 --- a/interface/vsomeip/internal/policy_manager.hpp +++ b/interface/vsomeip/internal/policy_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,15 +6,18 @@ #ifndef VSOMEIP_V3_POLICY_MANAGER_HPP_ #define VSOMEIP_V3_POLICY_MANAGER_HPP_ + #include +#include +#include #include namespace vsomeip_v3 { struct policy; -class policy_manager { +class VSOMEIP_IMPORT_EXPORT policy_manager { public: static std::shared_ptr get(); @@ -35,4 +38,5 @@ class policy_manager { } // namespace vsomeip_v3 + #endif // VSOMEIP_V3_POLICY_MANAGER_HPP_ diff --git a/interface/vsomeip/internal/serializable.hpp b/interface/vsomeip/internal/serializable.hpp index 52540b83e..8101e522c 100644 --- a/interface/vsomeip/internal/serializable.hpp +++ b/interface/vsomeip/internal/serializable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/message.hpp b/interface/vsomeip/message.hpp index 0d1c5cca5..e7e0b0dea 100644 --- a/interface/vsomeip/message.hpp +++ b/interface/vsomeip/message.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,9 @@ #include +#include #include +#include namespace vsomeip_v3 { @@ -62,12 +64,22 @@ class message: virtual public message_base { /** * \brief Return uid of the message sender. */ - VSOMEIP_EXPORT virtual uid_t get_uid() const = 0; + VSOMEIP_DEPRECATED_UID_GID VSOMEIP_EXPORT virtual uid_t get_uid() const = 0; /** * \brief Return gid of the message sender. */ - VSOMEIP_EXPORT virtual gid_t get_gid() const = 0; + VSOMEIP_DEPRECATED_UID_GID VSOMEIP_EXPORT virtual gid_t get_gid() const = 0; + + /** + * \brief Return environment (hostname) of the message sender. + */ + VSOMEIP_EXPORT virtual std::string get_env() const = 0; + + /** + * \brief Return security client of the message sender. + */ + VSOMEIP_EXPORT virtual vsomeip_sec_client_t get_sec_client() const = 0; }; /** @} */ diff --git a/interface/vsomeip/message_base.hpp b/interface/vsomeip/message_base.hpp index b6efa8bc3..fbdceb7b9 100644 --- a/interface/vsomeip/message_base.hpp +++ b/interface/vsomeip/message_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/payload.hpp b/interface/vsomeip/payload.hpp index 3e7e45a43..9b8ea9576 100644 --- a/interface/vsomeip/payload.hpp +++ b/interface/vsomeip/payload.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/plugin.hpp b/interface/vsomeip/plugin.hpp index 33667a882..25ccbb2dc 100644 --- a/interface/vsomeip/plugin.hpp +++ b/interface/vsomeip/plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -39,12 +39,7 @@ typedef create_plugin_func (*plugin_init_func)(); */ class VSOMEIP_IMPORT_EXPORT_PLUGIN plugin { public: - virtual ~plugin() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~plugin() {} virtual uint32_t get_plugin_version() const = 0; virtual const std::string &get_plugin_name() const = 0; @@ -65,15 +60,15 @@ class plugin_impl : public plugin { type_ = _type; } - const std::string &get_plugin_name() const override { + const std::string &get_plugin_name() const { return name_; } - uint32_t get_plugin_version() const override { + uint32_t get_plugin_version() const { return version_; } - plugin_type_e get_plugin_type() const override { + plugin_type_e get_plugin_type() const { return type_; } diff --git a/interface/vsomeip/plugins/application_plugin.hpp b/interface/vsomeip/plugins/application_plugin.hpp index 90e3e64d2..a052aa2a3 100644 --- a/interface/vsomeip/plugins/application_plugin.hpp +++ b/interface/vsomeip/plugins/application_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/plugins/pre_configuration_plugin.hpp b/interface/vsomeip/plugins/pre_configuration_plugin.hpp index 6505249f5..538599326 100644 --- a/interface/vsomeip/plugins/pre_configuration_plugin.hpp +++ b/interface/vsomeip/plugins/pre_configuration_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/primitive_types.hpp b/interface/vsomeip/primitive_types.hpp index 26a9fd706..0a9eaa5e1 100644 --- a/interface/vsomeip/primitive_types.hpp +++ b/interface/vsomeip/primitive_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,7 +10,7 @@ #include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -41,9 +41,12 @@ typedef uint8_t interface_version_t; typedef uint8_t byte_t; typedef uint16_t diagnosis_t; +typedef uint16_t port_t; + // Addresses typedef std::array ipv4_address_t; typedef std::array ipv6_address_t; +typedef std::uint16_t port_t; typedef std::string trace_channel_t; diff --git a/interface/vsomeip/runtime.hpp b/interface/vsomeip/runtime.hpp index 513847ddf..e2d97c8ab 100644 --- a/interface/vsomeip/runtime.hpp +++ b/interface/vsomeip/runtime.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -207,6 +207,26 @@ class VSOMEIP_IMPORT_EXPORT runtime { * */ virtual void remove_application( const std::string &_name) = 0; + + /** + * + * \brief Creates a vsomeip application object. + * + * An application object manages service offers and requests as well as + * event subscriptions. It allows to register user application functions + * as callbacks that are called on specific events during runtime, e.g + * to react on incoming SOME/IP messages. + * An application object is identified by a unique name that is also used + * in (and therefore has to match) the configuration files of vsomeip. If + * the name is left empty, the application name is taken from the + * environment variable "VSOMEIP_APPLICATION_NAME" + * + * \param _name Name of the application on the system. + * \param _path Path to the configuration file or folder. + * + */ + virtual std::shared_ptr create_application( + const std::string &_name, const std::string &_path) = 0; }; /** @} */ diff --git a/interface/vsomeip/structured_types.hpp b/interface/vsomeip/structured_types.hpp new file mode 100644 index 000000000..059d33c7e --- /dev/null +++ b/interface/vsomeip/structured_types.hpp @@ -0,0 +1,66 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_STRUCTURED_TYPES_HPP_ +#define VSOMEIP_V3_STRUCTURED_TYPES_HPP_ + +#include +#include + +namespace vsomeip_v3 { + +// Messages are forwarded either because their value differs from the +// last received message (on_change) or because the specified time +// (interval) between two messages has elapsed. A message that is forwarded +// because of a changed value may reset the time until the next unchanged +// message is forwarded or not (on_change_resets_interval). By specifiying +// indexes and bit masks, the comparison that is carried out to decide whether +// or not two message values differ is configurable (ignore). +struct debounce_filter_t { + debounce_filter_t() + : on_change_(false), + on_change_resets_interval_(false), + interval_(-1) { + } + + debounce_filter_t(const debounce_filter_t &_source) + : on_change_(_source.on_change_), + on_change_resets_interval_(_source.on_change_resets_interval_), + interval_(_source.interval_), + ignore_(_source.ignore_) { + } + + inline void operator=(const debounce_filter_t &_other) { + on_change_ = _other.on_change_; + on_change_resets_interval_ = _other.on_change_resets_interval_; + interval_ = _other.interval_; + ignore_ = _other.ignore_; + } + + inline bool operator==(const debounce_filter_t &_other) const { + + return (on_change_ == _other.on_change_ + && on_change_resets_interval_ == _other.on_change_resets_interval_ + && interval_ == _other.interval_ + && ignore_ == _other.ignore_); + } + + inline bool operator!=(const debounce_filter_t &_other) const { + + return (on_change_ != _other.on_change_ + || on_change_resets_interval_ != _other.on_change_resets_interval_ + || interval_ != _other.interval_ + || ignore_ != _other.ignore_); + } + + bool on_change_; + bool on_change_resets_interval_; + int64_t interval_; + std::map ignore_; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_STRUCTURED_TYPES_HPP diff --git a/interface/vsomeip/trace.hpp b/interface/vsomeip/trace.hpp index cf5b7b9cd..016dc5a7e 100644 --- a/interface/vsomeip/trace.hpp +++ b/interface/vsomeip/trace.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/vsomeip.hpp b/interface/vsomeip/vsomeip.hpp index 231fa3a08..f0a66c5e5 100644 --- a/interface/vsomeip/vsomeip.hpp +++ b/interface/vsomeip/vsomeip.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/vsomeip_sec.h b/interface/vsomeip/vsomeip_sec.h new file mode 100644 index 000000000..88c36669f --- /dev/null +++ b/interface/vsomeip/vsomeip_sec.h @@ -0,0 +1,158 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ +#define VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef uint16_t vsomeip_sec_service_id_t; +typedef uint16_t vsomeip_sec_instance_id_t; +typedef uint16_t vsomeip_sec_member_id_t; // SOME/IP method or event + +typedef uint32_t vsomeip_sec_ip_addr_t; // ip address in network byte order +typedef uint16_t vsomeip_sec_network_port_t; // network port in network byte order + +#ifndef __unix__ +typedef uint32_t uid_t; +typedef uint32_t gid_t; +#endif + +typedef struct { + uid_t user; + gid_t group; +} vsomeip_sec_uds_client_credentials_t; + +typedef struct { + vsomeip_sec_ip_addr_t ip; + vsomeip_sec_network_port_t port; +} vsomeip_sec_ip_client_credentials_t; + +typedef enum { + VSOMEIP_CLIENT_UDS, + VSOMEIP_CLIENT_TCP, + VSOMEIP_CLIENT_INVALID +} vsomeip_sec_client_type_t; + +typedef struct { + vsomeip_sec_client_type_t client_type; + union { + vsomeip_sec_uds_client_credentials_t uds_client; + vsomeip_sec_ip_client_credentials_t ip_client; + } client; +} vsomeip_sec_client_t; + +typedef enum { + VSOMEIP_SEC_OK, + VSOMEIP_SEC_PERM_DENIED +} vsomeip_sec_acl_result_t; + +typedef enum { + VSOMEIP_SEC_POLICY_OK, + VSOMEIP_SEC_POLICY_NOT_FOUND, + VSOMEIP_SEC_POLICY_INVALID +} vsomeip_sec_policy_result_t; + +/** + * Load the policy and initialize policy plugin functionality. + * This function MUST be called before any other function in this library can be called. + * It will return whether loading the policy was successful or if there was some problem + * during initialization. + * + * Please note that the policy initializer does not take any additional arguments. It is assumed + * here tha the policy plugin libraries have some out-of-bounds methods to, e.g., find the policy + * file. + * + * The function may be called multiple times (even from multiple threads) without problems. + */ + vsomeip_sec_policy_result_t vsomeip_sec_policy_initialize(); + +/** + * Authenticate connection with vSomeIP router. + * + * vSomeIP router (vsomeipd) has by definition unlimited access to other vSomeIP applications. + * Therefore, EVERY connection with the router must be authenticated and then any command from/to + * vsomeipd is implicitly allowed. + * + * This method MUST be called to ensure that the remote end is supposed to act as + * vSomeIP routing manager. + * + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_authenticate_router(const vsomeip_sec_client_t *router); + + +/* + * ### RPC + */ + +/** + * Check if a server is authorised to offer a specific service / instance + * + * vsomeip_sec_policy_is_client_allowed_to_offer checks if \p server is allowed to offer a \p + * service by the security policy. + * + * This API MUST be called by vSomeIP clients before sending requests and before + * processing responses. It and SHOULD be called at the router for every service offer before + * distributing it among the clients. + * + * @note + * Both, method calls and subscribe-notify communications are end-to-end + * authenticated. Therefore, authentication of the server at the router side is optional but + * recommended. Doing so would help to detect system missconfiguration and simplify + * application debugging. + * + * @note + * Due to asynchronous nature of SOME/IP method calls, to deliver a method response, server + * establishes a separate socket which destination client must be authenticated. This method + * does exactly that. + * + * @note + * While client access may be restricted to certain methods or events, servers are always + * allowed to offer. + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_offer( + const vsomeip_sec_client_t *server, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance); + + + +/** + * Check if client is allowed to request a service. + * + * This method MUST be called at the server/stub side before serving a client request. It may + * additionally be used by vsomeipd when servicing service discovery so that clients that do not + * have the permission to request a certain service cannot (even) successfully discover it. + * + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_request( + const vsomeip_sec_client_t *client, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance); + + +/** + * Check if client is allowed to access a specific SOME/IP method. + * + * SOME/IP does not really distinguish between methods and events. It just handles everything + * via a uint16 member identifier. The identifiers below 0x7FFF are used for methods, identifier + * starting at 0x8000 are used for events. So we just have one method to check if the client is + * allowed to interact with a specific member. + * + * This method MUST be called at the server/stub side before processing a request that triggers + * a specific method or completes event registration. + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_access_member( + const vsomeip_sec_client_t *client, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance, vsomeip_sec_member_id_t member); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ diff --git a/libvsomeip.yaml b/libvsomeip.yaml new file mode 100644 index 000000000..85f4ea174 --- /dev/null +++ b/libvsomeip.yaml @@ -0,0 +1,6 @@ +- name: libvsomeip + version: 3.3.0 + vendor: Lynx Team + license: + concluded: CLOSED and MPLv2 + declared: MPLv2 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b4f63c7ca..2121715b3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3839 +1,25 @@ -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.1) - -# Add the gtest header files to the include files -include_directories( - . - ${gtest_SOURCE_DIR}/include -) - -set(TEST_LINK_LIBRARIES gtest) - -# Function to copy files into the build directory (or anywhere else) -# On unixoid systems this function will create symlinks instead -# SOURCE_PATH: Path to the file which should be copied -# DESTINATION_PATH: destination file -# TARGET_TO_DEPEND: The copying of the file will be added as -# a dependency to this target -function(copy_to_builddir SOURCE_PATH DESTINATION_PATH TARGET_TO_DEPEND) - if(${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR NOT ${TEST_SYMLINK_CONFIG_FILES}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Copying \"${SOURCE_PATH}\" into build directory" - ) - else() - if(${TEST_SYMLINK_CONFIG_FILES_RELATIVE}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create a relative link - COMMAND ln -s -r "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - else() - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create an absolute link - COMMAND ${CMAKE_COMMAND} -E create_symlink "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - endif() - endif() - # Add a random number to the end of the string to avoid problems with - # duplicate filenames - set(FILENAME "") - get_filename_component(FILENAME ${SOURCE_PATH} NAME ) - string(RANDOM LENGTH 4 ALPHABET 0123456789 RANDOMNUMBER) - if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" - ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER}) - else() - ADD_CUSTOM_TARGET(symlink_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" - ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} symlink_${FILENAME}_${RANDOMNUMBER}) - endif() -endfunction() - -############################################################################## -# configuration-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CONFIGURATION configuration-test) - - add_executable(${TEST_CONFIGURATION} - configuration_tests/configuration-test.cpp - ${PROJECT_SOURCE_DIR}/implementation/plugin/src/plugin_manager_impl.cpp - ) - target_link_libraries(${TEST_CONFIGURATION} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # The following will make sure that ${TEST_CONFIGURATION_CONFIG_FILE} is copied - # from the config folder into the test folder in the builddirectory - # This makes it possible to call the configuration test within the build directory - set(TEST_CONFIGURATION_CONFIG_FILE configuration-test.json) - set(TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE configuration-test-deprecated.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/configuration_tests/${TEST_CONFIGURATION_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CONFIGURATION_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/configuration_tests/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) -endif() -############################################################################## -# application test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_APPLICATION application_test) - - add_executable(${TEST_APPLICATION} application_tests/${TEST_APPLICATION}.cpp) - target_link_libraries(${TEST_APPLICATION} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_NAME ${TEST_APPLICATION}_single_process) - add_executable(${TEST_APPLICATION_SINGLE_PROCESS_NAME} application_tests/${TEST_APPLICATION_SINGLE_PROCESS_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_SINGLE_PROCESS_NAME} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_AVAILABILITY_NAME ${TEST_APPLICATION}_availability) - add_executable(${TEST_APPLICATION_AVAILABILITY_NAME} application_tests/${TEST_APPLICATION_AVAILABILITY_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_AVAILABILITY_NAME} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE ${TEST_APPLICATION}_single_process.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_CONFIGURATION_FILE ${TEST_APPLICATION}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_CONFIGURATION_FILE} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_daemon.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE ${TEST_APPLICATION}_no_dispatch_threads.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_no_dispatch_threads_daemon.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_STARTER ${TEST_APPLICATION}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_STARTER} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_STARTER ${TEST_APPLICATION}_single_process_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_AVAILABILITY_STARTER ${TEST_APPLICATION_AVAILABILITY_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - ) -endif() -############################################################################## -# magic-cookies-test-client -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MAGIC_COOKIES_NAME magic_cookies_test) - - set(TEST_MAGIC_COOKIES_CLIENT ${TEST_MAGIC_COOKIES_NAME}_client) - add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service) - add_executable(${TEST_MAGIC_COOKIES_SERVICE} magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE ${TEST_MAGIC_COOKIES_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - set(TEST_MAGIC_COOKIES_SERVICE magic_cookies_test_service) - # Copy config file for service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE ${TEST_MAGIC_COOKIES_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_MAGIC_COOKIES_STARTER ${TEST_MAGIC_COOKIES_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER} - ${TEST_MAGIC_COOKIES_CLIENT} - ) -endif() -############################################################################## -# someip-header-factory-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_HEADER_FACTORY_NAME header_factory_test) - - set(TEST_HEADER_FACTORY header_factory_test) - add_executable(${TEST_HEADER_FACTORY} header_factory_tests/header_factory_test.cpp) - target_link_libraries(${TEST_HEADER_FACTORY} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - ############################################################################## - # Now comes the second part of the header factory test which consists of ouf - # a client and a service both with settings file and bash scripts to start them - set(TEST_HEADER_FACTORY_CLIENT header_factory_test_client) - add_executable(${TEST_HEADER_FACTORY_CLIENT} header_factory_tests/${TEST_HEADER_FACTORY_CLIENT}.cpp) - target_link_libraries(${TEST_HEADER_FACTORY_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${TEST_HEADER_FACTORY_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_HEADER_FACTORY_CLIENT_START_SCRIPT ${TEST_HEADER_FACTORY_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${TEST_HEADER_FACTORY_CLIENT} - ) - - set(TEST_HEADER_FACTORY_SERVICE header_factory_test_service) - add_executable(${TEST_HEADER_FACTORY_SERVICE} header_factory_tests/${TEST_HEADER_FACTORY_SERVICE}.cpp) - target_link_libraries(${TEST_HEADER_FACTORY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${TEST_HEADER_FACTORY_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_HEADER_FACTORY_SERVICE_START_SCRIPT ${TEST_HEADER_FACTORY_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${TEST_HEADER_FACTORY_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_HEADER_FACTORY_STARTER header_factory_test_send_receive_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER} - ${TEST_HEADER_FACTORY_CLIENT} - ) -endif() -############################################################################## -# routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - ############################################################################## - set(TEST_EXTERNAL_LOCAL_ROUTING_NAME external_local_routing_test) - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE external_local_routing_test_service) - add_executable(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start external client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT external_local_routing_test_client_external) - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_STARTER external_local_routing_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) -else() - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.bat.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) -endif() -############################################################################## -# restart_routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_RESTART_ROUTING_NAME restart_routing_test) - - set(TEST_RESTART_ROUTING_SERVICE restart_routing_test_service) - add_executable(${TEST_RESTART_ROUTING_SERVICE} restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_RESTART_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE ${TEST_RESTART_ROUTING_SERVICE}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_START_SCRIPT ${TEST_RESTART_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - set(TEST_RESTART_ROUTING_CLIENT restart_routing_test_client) - add_executable(${TEST_RESTART_ROUTING_CLIENT} - restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT}.cpp - ) - target_link_libraries(${TEST_RESTART_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE ${TEST_RESTART_ROUTING_CLIENT}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_START_SCRIPT ${TEST_RESTART_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_RESTART_ROUTING_STARTER restart_routing_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_STARTER} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy config file for autoconfig into $BUILDDIR/test - set(TEST_RESTART_ROUTING_AUTO_CONFIG_FILE ${TEST_RESTART_ROUTING_NAME}_autoconfig.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) -endif() - -############################################################################## -# security test -############################################################################## - -if (${TEST_SECURITY}) - if(NOT ${TESTS_BAT}) - set(TEST_SECURITY_NAME security_test) - set(TEST_SECURITY_SERVICE security_test_service) - set(TEST_SECURITY_CLIENT security_test_client) - - add_executable(${TEST_SECURITY_SERVICE} security_tests/${TEST_SECURITY_SERVICE}.cpp) - target_link_libraries(${TEST_SECURITY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_SECURITY_LOCAL_CONFIG_FILE ${TEST_SECURITY_NAME}_local_config.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_LOCAL_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${TEST_SECURITY_SERVICE} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_service_external_allow.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_client_external_allow.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) - - # Copy service config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_service_external_deny.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) - - # Copy client config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_client_external_deny.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start local test into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT ${TEST_SECURITY_NAME}_local_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT ${TEST_SECURITY_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT ${TEST_SECURITY_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - add_executable(${TEST_SECURITY_CLIENT} - security_tests/${TEST_SECURITY_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECURITY_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - endif() -endif() - -############################################################################## -# payload-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_LOCAL_PAYLOAD_NAME local_payload_test) - - set(TEST_PAYLOAD_SERVICE payload_test_service) - add_executable(${TEST_PAYLOAD_SERVICE} payload_tests/${TEST_PAYLOAD_SERVICE}.cpp) - target_link_libraries(${TEST_PAYLOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT local_${TEST_PAYLOAD_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - set(TEST_PAYLOAD_CLIENT payload_test_client) - add_executable(${TEST_PAYLOAD_CLIENT} - payload_tests/${TEST_PAYLOAD_CLIENT}.cpp - payload_tests/stopwatch.cpp - ) - target_link_libraries(${TEST_PAYLOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT local_${TEST_PAYLOAD_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_STARTER local_payload_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - set(TEST_EXTERNAL_LOCAL_PAYLOAD_NAME external_local_payload_test) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE external_local_payload_test_service) - - # Copy config file for service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL external_local_payload_test_client_local) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME external_local_payload_test_client_local) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - ############################################################################## - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME external_local_payload_test_client_external) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL external_local_payload_test_client_external) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL external_local_payload_test_service_client_external) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME external_local_payload_test_client_local_and_external) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload) - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) -endif() - -############################################################################## -# big_payload_test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_BIG_PAYLOAD_NAME big_payload_test) - - set(TEST_BIG_PAYLOAD_SERVICE big_payload_test_service) - add_executable(${TEST_BIG_PAYLOAD_SERVICE} big_payload_tests/${TEST_BIG_PAYLOAD_SERVICE}.cpp) - target_link_libraries(${TEST_BIG_PAYLOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_BIG_PAYLOAD_CLIENT big_payload_test_client) - add_executable(${TEST_BIG_PAYLOAD_CLIENT} big_payload_tests/${TEST_BIG_PAYLOAD_CLIENT}.cpp) - target_link_libraries(${TEST_BIG_PAYLOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_queue_limited.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_service.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_client_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_service_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_specific.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_specific.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - # Copy config file for UDP client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_service.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client local to $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start service local to $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_local_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_queue_limited) - set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client for external test into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL big_payload_test_external_limited_general) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL big_payload_test_external_queue_limited_general) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC big_payload_test_external_queue_limited_specific) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP big_payload_test_external_udp) - set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start server for external into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_external_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client for external test into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} - ) -endif() - -############################################################################## -# client id tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CLIENT_ID_NAME client_id_test) - set(TEST_CLIENT_ID_SERVICE ${TEST_CLIENT_ID_NAME}_service) - add_executable(${TEST_CLIENT_ID_SERVICE} client_id_tests/${TEST_CLIENT_ID_NAME}_service.cpp) - target_link_libraries(${TEST_CLIENT_ID_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility) - add_executable(${TEST_CLIENT_ID_UTILITY} - client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp - ${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp) - target_link_libraries(${TEST_CLIENT_ID_UTILITY} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - set(TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_511.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_4095.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_127.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_discontinuous_masked_511.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - # copy starter scripts into builddir - set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) - set(TEST_CLIENT_ID_SLAVE_STARTER ${TEST_CLIENT_ID_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SLAVE_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) -endif() - -############################################################################## -# subscribe notify tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_NAME subscribe_notify_test) - set(TEST_SUBSCRIBE_NOTIFY_SERVICE ${TEST_SUBSCRIBE_NOTIFY_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_SERVICE} subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # subscribe_notify_test_one_event_two_eventgroups - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME subscribe_notify_test_one_event_two_eventgroups) - - # service - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - # client - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_client) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) -endif() - -############################################################################## -# subscribe notify one tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_ONE_NAME subscribe_notify_one_test) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) -endif() - -############################################################################## -# cpu-load-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_CPU_LOAD_NAME cpu_load_test) - - set(TEST_CPU_LOAD_SERVICE cpu_load_test_service) - add_executable(${TEST_CPU_LOAD_SERVICE} - cpu_load_tests/${TEST_CPU_LOAD_SERVICE}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - - ############################################################################## - set(TEST_CPU_LOAD_CLIENT cpu_load_test_client) - add_executable(${TEST_CPU_LOAD_CLIENT} - cpu_load_tests/${TEST_CPU_LOAD_CLIENT}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - set(TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - - ############################################################################## - # copy starter scripts into builddir - set(TEST_CPU_LOAD_MASTER_STARTER ${TEST_CPU_LOAD_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_MASTER_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SLAVE_STARTER ${TEST_CPU_LOAD_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SLAVE_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) -endif() - -############################################################################## -# initial event tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_INITIAL_EVENT_NAME initial_event_test) - set(TEST_INITIAL_EVENT_SERVICE ${TEST_INITIAL_EVENT_NAME}_service) - add_executable(${TEST_INITIAL_EVENT_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_CLIENT ${TEST_INITIAL_EVENT_NAME}_client) - add_executable(${TEST_INITIAL_EVENT_CLIENT} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_client.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_AVAILABILITY_CHECKER ${TEST_INITIAL_EVENT_NAME}_availability_checker) - add_executable(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_availability_checker.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_STOP_SERVICE ${TEST_INITIAL_EVENT_NAME}_stop_service) - add_executable(${TEST_INITIAL_EVENT_STOP_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_stop_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_STOP_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) - set(TEST_INITIAL_EVENT_SLAVE_STARTER ${TEST_INITIAL_EVENT_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) -endif() - -############################################################################## -# offer tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFER_NAME offer_test) - set(TEST_OFFER_SERVICE ${TEST_OFFER_NAME}_service) - add_executable(${TEST_OFFER_SERVICE} offer_tests/${TEST_OFFER_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_CLIENT ${TEST_OFFER_NAME}_client) - add_executable(${TEST_OFFER_CLIENT} offer_tests/${TEST_OFFER_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_SERVICE_EXTERNAL ${TEST_OFFER_NAME}_service_external) - add_executable(${TEST_OFFER_SERVICE_EXTERNAL} offer_tests/${TEST_OFFER_NAME}_service_external.cpp) - target_link_libraries(${TEST_OFFER_SERVICE_EXTERNAL} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_SERVICE_AVAILABILITY_CHECKER ${TEST_OFFER_NAME}_service_availability_checker) - add_executable(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} offer_tests/${TEST_OFFER_NAME}_service_availability_checker.cpp) - target_link_libraries(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER ${TEST_OFFER_NAME}_external_sd_msg_sender) - add_executable(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} offer_tests/${TEST_OFFER_NAME}_external_sd_msg_sender.cpp) - target_link_libraries(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # client and service for offer test big sd msg - set(TEST_OFFER_BIG_NAME offer_test_big_sd_msg) - set(TEST_OFFER_BIG_SERVICE ${TEST_OFFER_BIG_NAME}_service) - add_executable(${TEST_OFFER_BIG_SERVICE} offer_tests/${TEST_OFFER_BIG_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_BIG_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_BIG_CLIENT ${TEST_OFFER_BIG_NAME}_client) - add_executable(${TEST_OFFER_BIG_CLIENT} offer_tests/${TEST_OFFER_BIG_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_BIG_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_STARTER} - ${TEST_OFFER_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFER_LOCAL_CONFIG_FILE ${TEST_OFFER_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for external test - set(TEST_OFFER_SLAVE_CONFIG_FILE ${TEST_OFFER_NAME}_external_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - set(TEST_OFFER_MASTER_CONFIG_FILE ${TEST_OFFER_NAME}_external_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_MASTER_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for big SD message test - set(TEST_OFFER_BIG_SLAVE_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - set(TEST_OFFER_BIG_MASTER_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_EXTERNAL_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${TEST_OFFER_SERVICE} - ) - set(TEST_OFFER_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_NAME}_external_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_SERVICE} - ) - set(TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER ${TEST_OFFER_NAME}_external_slave_sd_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER} - ${TEST_OFFER_SERVICE} - ) - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_MASTER_STARTER ${TEST_OFFER_BIG_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_BIG_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) -endif() - -############################################################################## -# offered services info tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) - set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) - add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) - add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) -endif() - -############################################################################## -# pending subscription tests tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_PENDING_SUBSCRIPTION_NAME pending_subscription_test) - set(TEST_PENDING_SUBSCRIPTION_SERVICE ${TEST_PENDING_SUBSCRIPTION_NAME}_service) - add_executable(${TEST_PENDING_SUBSCRIPTION_SERVICE} pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_service.cpp) - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_PENDING_SUBSCRIPTION_CLIENT ${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender) - add_executable(${TEST_PENDING_SUBSCRIPTION_CLIENT} - pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # copy starter scripts into builddir - set(TEST_PENDING_SUBSCRIPTION_MASTER_STARTER ${TEST_PENDING_SUBSCRIPTION_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_PENDING_SUBSCRIPTION_CONFIG_FILE ${TEST_PENDING_SUBSCRIPTION_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) -endif() - -############################################################################## -# malicious data tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MALICIOUS_DATA_NAME malicious_data_test) - set(TEST_MALICIOUS_DATA_SERVICE ${TEST_MALICIOUS_DATA_NAME}_service) - add_executable(${TEST_MALICIOUS_DATA_SERVICE} malicious_data_tests/${TEST_MALICIOUS_DATA_NAME}_service.cpp) - target_link_libraries(${TEST_MALICIOUS_DATA_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_MALICIOUS_DATA_CLIENT ${TEST_MALICIOUS_DATA_NAME}_msg_sender) - add_executable(${TEST_MALICIOUS_DATA_CLIENT} - malicious_data_tests/${TEST_MALICIOUS_DATA_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_MALICIOUS_DATA_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # copy starter scripts into builddir - set(TEST_MALICIOUS_DATA_MASTER_STARTER ${TEST_MALICIOUS_DATA_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${TEST_MALICIOUS_DATA_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_MALICIOUS_DATA_CONFIG_FILE ${TEST_MALICIOUS_DATA_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${TEST_MALICIOUS_DATA_SERVICE} - ) -endif() - -############################################################################## -# e2e test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_E2E_NAME e2e_test) - set(TEST_E2E_SERVICE e2e_test_service) - set(TEST_E2E_CLIENT e2e_test_client) - - add_executable(${TEST_E2E_SERVICE} e2e_tests/${TEST_E2E_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_E2E_CLIENT} - e2e_tests/${TEST_E2E_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_service_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_client_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) -endif() - -############################################################################## -# e2e profile 04 test -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_04}) - set(TEST_E2E_PROFILE_04_NAME e2e_profile_04_test) - set(TEST_E2E_PROFILE_04_SERVICE e2e_profile_04_test_service) - set(TEST_E2E_PROFILE_04_CLIENT e2e_profile_04_test_client) - - add_executable(${TEST_E2E_PROFILE_04_SERVICE} e2e_tests/${TEST_E2E_PROFILE_04_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_PROFILE_04_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_E2E_PROFILE_04_CLIENT} - e2e_tests/${TEST_E2E_PROFILE_04_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_PROFILE_04_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_service_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_client_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) -endif() - -############################################################################## -# event tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_EVENT_NAME event_test) - set(TEST_EVENT_SERVICE ${TEST_EVENT_NAME}_service) - set(TEST_EVENT_CLIENT ${TEST_EVENT_NAME}_client) - - add_executable(${TEST_EVENT_SERVICE} event_tests/${TEST_EVENT_SERVICE}.cpp) - target_link_libraries(${TEST_EVENT_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_EVENT_CLIENT} - event_tests/${TEST_EVENT_CLIENT}.cpp - ) - target_link_libraries(${TEST_EVENT_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_EVENT_SLAVE_TCP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_SLAVE_UDP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_MASTER_CONFIG_FILE ${TEST_EVENT_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_CONFIG_FILE} - ${TEST_EVENT_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_EVENT_MASTER_START_SCRIPT ${TEST_EVENT_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} - ${TEST_EVENT_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_EVENT_SLAVE_START_SCRIPT ${TEST_EVENT_NAME}_slave_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_START_SCRIPT} - ${TEST_EVENT_CLIENT} - ) - -endif() - -############################################################################## -# npdu-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_NPDU_NAME npdu_test) - - set(TEST_NPDU_DAEMON npdu_test_rmd) - set(TEST_NPDU_DAEMON_CLIENT ${TEST_NPDU_DAEMON}_client_side) - add_executable(${TEST_NPDU_DAEMON_CLIENT} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_CLIENT} PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_DAEMON_SERVICE ${TEST_NPDU_DAEMON}_service_side) - add_executable(${TEST_NPDU_DAEMON_SERVICE} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_SERVICE} PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - ############################################################################## - - set(TEST_NPDU_SERVICE npdu_test_service) - - set(TEST_NPDU_SERVICE_ONE npdu_test_service_1) - add_executable(${TEST_NPDU_SERVICE_ONE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_ONE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0) - target_link_libraries(${TEST_NPDU_SERVICE_ONE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_TWO npdu_test_service_2) - add_executable(${TEST_NPDU_SERVICE_TWO} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_TWO} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1) - target_link_libraries(${TEST_NPDU_SERVICE_TWO} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_THREE npdu_test_service_3) - add_executable(${TEST_NPDU_SERVICE_THREE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_THREE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2) - target_link_libraries(${TEST_NPDU_SERVICE_THREE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_FOUR npdu_test_service_4) - add_executable(${TEST_NPDU_SERVICE_FOUR} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_FOUR} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3) - target_link_libraries(${TEST_NPDU_SERVICE_FOUR} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_no_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_no_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy config file for service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_CLIENT npdu_test_client) - - set(TEST_NPDU_CLIENT_ONE npdu_test_client_1) - add_executable(${TEST_NPDU_CLIENT_ONE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_ONE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_TWO npdu_test_client_2) - add_executable(${TEST_NPDU_CLIENT_TWO} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_TWO} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_THREE npdu_test_client_3) - add_executable(${TEST_NPDU_CLIENT_THREE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_THREE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_FOUR npdu_test_client_4) - add_executable(${TEST_NPDU_CLIENT_FOUR} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_FOUR} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_no_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_no_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy config file for client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_STARTER ${TEST_NPDU_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} - ${TEST_NPDU_DAEMON_CLIENT} - ) -endif() - -############################################################################## -# someip tp tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_SOMEIPTP_NAME someip_tp_test) - set(TEST_SOMEIPTP_SERVICE ${TEST_SOMEIPTP_NAME}_service) - - add_executable(${TEST_SOMEIPTP_SERVICE} someip_tp_tests/${TEST_SOMEIPTP_SERVICE}.cpp) - target_link_libraries(${TEST_SOMEIPTP_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_SOMEIPTP_CLIENT ${TEST_SOMEIPTP_NAME}_msg_sender) - add_executable(${TEST_SOMEIPTP_CLIENT} - someip_tp_tests/${TEST_SOMEIPTP_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_SOMEIPTP_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_CONFIG_FILE ${TEST_SOMEIPTP_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${TEST_SOMEIPTP_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_START_SCRIPT ${TEST_SOMEIPTP_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_START_SCRIPT}.in - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${TEST_SOMEIPTP_SERVICE} - ) -endif() - -############################################################################## -# second IP address tests -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_SECOND_ADDRESS}) - set(TEST_SECOND_ADDRESS_NAME second_address_test) - set(TEST_SECOND_ADDRESS_SERVICE ${TEST_SECOND_ADDRESS_NAME}_service) - set(TEST_SECOND_ADDRESS_CLIENT ${TEST_SECOND_ADDRESS_NAME}_client) - - add_executable(${TEST_SECOND_ADDRESS_SERVICE} - second_address_tests/${TEST_SECOND_ADDRESS_SERVICE}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_SECOND_ADDRESS_CLIENT} - second_address_tests/${TEST_SECOND_ADDRESS_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_service_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_service_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_MASTER_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_slave_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${TEST_SECOND_ADDRESS_CLIENT} - ) -endif() - -############################################################################## -# suspend resume tests -############################################################################## -if(NOT ${TESTS_BAT}) - - set(TEST_SUSPEND_RESUME_NAME suspend_resume_test) - set(TEST_SUSPEND_RESUME_SERVICE ${TEST_SUSPEND_RESUME_NAME}_service) - set(TEST_SUSPEND_RESUME_CLIENT ${TEST_SUSPEND_RESUME_NAME}_client) - - add_executable(${TEST_SUSPEND_RESUME_SERVICE} - suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_SUSPEND_RESUME_CLIENT} - suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE ${TEST_SUSPEND_RESUME_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE ${TEST_SUSPEND_RESUME_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_MASTER_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_slave_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - -endif() - ############################################################################## -# Add for every test a dependency to gtest +# add network, unit and benchmark tests directories ############################################################################## +add_subdirectory( network_tests EXCLUDE_FROM_ALL ) -if(NOT ${TESTS_BAT}) - add_dependencies(${TEST_CONFIGURATION} gtest) - add_dependencies(${TEST_APPLICATION} gtest) - add_dependencies(${TEST_APPLICATION_SINGLE_PROCESS_NAME} gtest) - add_dependencies(${TEST_APPLICATION_AVAILABILITY_NAME} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_SERVICE} gtest) - add_dependencies(${TEST_HEADER_FACTORY} gtest) - add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) - add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) - add_dependencies(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest) - add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_SERVICE} gtest) - add_dependencies(${TEST_INITIAL_EVENT_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} gtest) - add_dependencies(${TEST_INITIAL_EVENT_STOP_SERVICE} gtest) - add_dependencies(${TEST_OFFER_SERVICE} gtest) - add_dependencies(${TEST_OFFER_CLIENT} gtest) - add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) - add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) - add_dependencies(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_CLIENT} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_SERVICE} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_CLIENT} gtest) - if (${TEST_SECURITY}) - add_dependencies(${TEST_SECURITY_SERVICE} gtest) - add_dependencies(${TEST_SECURITY_CLIENT} gtest) - endif() - add_dependencies(${TEST_E2E_SERVICE} gtest) - add_dependencies(${TEST_E2E_CLIENT} gtest) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(${TEST_E2E_PROFILE_04_SERVICE} gtest) - add_dependencies(${TEST_E2E_PROFILE_04_CLIENT} gtest) - endif() - add_dependencies(${TEST_EVENT_SERVICE} gtest) - add_dependencies(${TEST_EVENT_CLIENT} gtest) - add_dependencies(${TEST_NPDU_SERVICE_ONE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_TWO} gtest) - add_dependencies(${TEST_NPDU_SERVICE_THREE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_FOUR} gtest) - add_dependencies(${TEST_NPDU_CLIENT_ONE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_TWO} gtest) - add_dependencies(${TEST_NPDU_CLIENT_THREE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_FOUR} gtest) - add_dependencies(${TEST_NPDU_DAEMON_CLIENT} gtest) - add_dependencies(${TEST_NPDU_DAEMON_SERVICE} gtest) - add_dependencies(${TEST_SOMEIPTP_CLIENT} gtest) - add_dependencies(${TEST_SOMEIPTP_SERVICE} gtest) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(${TEST_SECOND_ADDRESS_CLIENT} gtest) - add_dependencies(${TEST_SECOND_ADDRESS_SERVICE} gtest) - endif() - add_dependencies(${TEST_SUSPEND_RESUME_CLIENT} gtest) - add_dependencies(${TEST_SUSPEND_RESUME_SERVICE} gtest) -else() - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) -endif() - -############################################################################## -# Add tests to the target build_tests -############################################################################## +if (NOT DISABLE_SECURITY) + add_subdirectory( unit_tests EXCLUDE_FROM_ALL ) -if(NOT ${TESTS_BAT}) - add_dependencies(build_tests ${TEST_CONFIGURATION}) - add_dependencies(build_tests ${TEST_APPLICATION}) - add_dependencies(build_tests ${TEST_APPLICATION_SINGLE_PROCESS_NAME}) - add_dependencies(build_tests ${TEST_APPLICATION_AVAILABILITY_NAME}) - add_dependencies(build_tests ${TEST_MAGIC_COOKIES_CLIENT}) - add_dependencies(build_tests ${TEST_MAGIC_COOKIES_SERVICE}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY_CLIENT}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT}) - add_dependencies(build_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_PAYLOAD_SERVICE}) - add_dependencies(build_tests ${TEST_PAYLOAD_CLIENT}) - add_dependencies(build_tests ${TEST_BIG_PAYLOAD_SERVICE}) - add_dependencies(build_tests ${TEST_BIG_PAYLOAD_CLIENT}) - add_dependencies(build_tests ${TEST_CLIENT_ID_SERVICE}) - add_dependencies(build_tests ${TEST_CLIENT_ID_UTILITY}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE}) - add_dependencies(build_tests ${TEST_CPU_LOAD_SERVICE}) - add_dependencies(build_tests ${TEST_CPU_LOAD_CLIENT}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_SERVICE}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_CLIENT}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_STOP_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_CLIENT}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE_EXTERNAL}) - add_dependencies(build_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER}) - add_dependencies(build_tests ${TEST_OFFER_BIG_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_BIG_CLIENT}) - add_dependencies(build_tests ${TEST_RESTART_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_RESTART_ROUTING_CLIENT}) - if (${TEST_SECURITY}) - add_dependencies(build_tests ${TEST_SECURITY_SERVICE}) - add_dependencies(build_tests ${TEST_SECURITY_CLIENT}) + if(benchmark_FOUND) + add_subdirectory( benchmark_tests EXCLUDE_FROM_ALL ) endif() - add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) - add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) - add_dependencies(build_tests ${TEST_PENDING_SUBSCRIPTION_SERVICE}) - add_dependencies(build_tests ${TEST_PENDING_SUBSCRIPTION_CLIENT}) - add_dependencies(build_tests ${TEST_MALICIOUS_DATA_SERVICE}) - add_dependencies(build_tests ${TEST_MALICIOUS_DATA_CLIENT}) - add_dependencies(build_tests ${TEST_E2E_SERVICE}) - add_dependencies(build_tests ${TEST_E2E_CLIENT}) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(build_tests ${TEST_E2E_PROFILE_04_SERVICE}) - add_dependencies(build_tests ${TEST_E2E_PROFILE_04_CLIENT}) - endif() - add_dependencies(build_tests ${TEST_EVENT_SERVICE}) - add_dependencies(build_tests ${TEST_EVENT_CLIENT}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_ONE}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_TWO}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_THREE}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_FOUR}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_ONE}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_TWO}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_THREE}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_FOUR}) - add_dependencies(build_tests ${TEST_NPDU_DAEMON_CLIENT}) - add_dependencies(build_tests ${TEST_NPDU_DAEMON_SERVICE}) - add_dependencies(build_tests ${TEST_SOMEIPTP_CLIENT}) - add_dependencies(build_tests ${TEST_SOMEIPTP_SERVICE}) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(build_tests ${TEST_SECOND_ADDRESS_CLIENT}) - add_dependencies(build_tests ${TEST_SECOND_ADDRESS_SERVICE}) - endif() - add_dependencies(build_tests ${TEST_SUSPEND_RESUME_CLIENT}) - add_dependencies(build_tests ${TEST_SUSPEND_RESUME_SERVICE}) -else() - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT}) endif() -# some tests require the routingmanagerd -add_dependencies(build_tests routingmanagerd) - ############################################################################## -# Add tests +# Add internal_routing_disabled_acceptance_test ############################################################################## if(NOT ${TESTS_BAT}) - add_test(NAME ${TEST_CONFIGURATION} - COMMAND ${TEST_CONFIGURATION} - ) - - # application test - add_test(NAME ${TEST_APPLICATION} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_STARTER} - ) - set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) - add_test(NAME ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_APPLICATION_AVAILABILITY_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_AVAILABILITY_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_AVAILABILITY_NAME} PROPERTIES TIMEOUT 120) - - # magic cookies test - add_test(NAME ${TEST_MAGIC_COOKIES_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER} - ) - set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 250) - - # Header/Factory tets - add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) - add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER} - ) - - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ) - - add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 120) - - # Payload tests - add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER} - ) - add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ) - set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 960) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - - # big payload tests - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) - - # client id tests - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY} - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_511 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_511 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_4095 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_4095 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_4095 PROPERTIES TIMEOUT 600) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_127 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_127 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_127 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 PROPERTIES TIMEOUT 120) - - # subscribe notify tests - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp PROPERTIES TIMEOUT 120) - - # subscribe notify one id tests - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - # cpu load tests - add_test(NAME ${TEST_CPU_LOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_MASTER_STARTER} - ) - set_tests_properties(${TEST_CPU_LOAD_NAME} PROPERTIES TIMEOUT 3000) - - # initial event tests - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP CLIENT_SUBSCRIBES_TWICE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice PROPERTIES TIMEOUT 120) - - # offer tests - add_test(NAME ${TEST_OFFER_NAME}_local - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 180) - add_test(NAME ${TEST_OFFER_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) - add_test(NAME ${TEST_OFFER_BIG_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_BIG_NAME} PROPERTIES TIMEOUT 360) - - # offered services info tets - add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) - - # Restart-Routing tests - add_test(NAME ${TEST_RESTART_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_STARTER} - ) - if (${TEST_SECURITY}) - # Security tests - add_test(NAME ${TEST_SECURITY_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_allow - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_allow.json --allow - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_deny - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_deny.json --deny - ) - endif() - - # pending subscriptions test - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_NACK) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_RESUBSCRIBE_MIXED) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} REQUEST_TO_SD) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port PROPERTIES TIMEOUT 180) - - # malicious data test - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_events - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} MALICIOUS_EVENTS) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_events PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_protocol_version - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} PROTOCOL_VERSION) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_protocol_version PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_message_type - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} MESSAGE_TYPE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_message_type PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_return_code - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} RETURN_CODE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_return_code PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} WRONG_HEADER_FIELDS_UDP) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp PROPERTIES TIMEOUT 180) - - # npdu tests - add_test(NAME ${TEST_NPDU_NAME}_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} UDP sync) - set_tests_properties(${TEST_NPDU_NAME}_udp PROPERTIES TIMEOUT 840) - - add_test(NAME ${TEST_NPDU_NAME}_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} TCP sync) - set_tests_properties(${TEST_NPDU_NAME}_tcp PROPERTIES TIMEOUT 840) - - # e2e tests - add_test(NAME ${TEST_E2E_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} e2e_test_client_external.json) - set_tests_properties(${TEST_E2E_NAME}_external PROPERTIES TIMEOUT 180) - - if (${TEST_E2E_PROFILE_04}) - add_test(NAME ${TEST_E2E_PROFILE_04_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_04_test_client_external.json) - set_tests_properties(${TEST_E2E_PROFILE_04_NAME}_external PROPERTIES TIMEOUT 180) - endif () - - # event tests - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_tcp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_tcp PROPERTIES TIMEOUT 180) - - # SOME/IP-TP tests - add_test(NAME ${TEST_SOMEIPTP_NAME}_in_sequence - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} IN_SEQUENCE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_in_sequence PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_mixed - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} MIXED) - set_tests_properties(${TEST_SOMEIPTP_NAME}_mixed PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_incomplete - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} INCOMPLETE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_incomplete PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_duplicate - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} DUPLICATE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_duplicate PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap_front_back - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP_FRONT_BACK) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap_front_back PROPERTIES TIMEOUT 180) - - if(${TEST_SECOND_ADDRESS}) - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} SERVICE UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} CLIENT UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp PROPERTIES TIMEOUT 180) - endif() - - # suspend resume test - add_test(NAME ${TEST_SUSPEND_RESUME_NAME}_initial - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} SERVICE - ) - set_tests_properties(${TEST_SUSPEND_RESUME_NAME}_initial PROPERTIES TIMEOUT 80) - -else() - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ) + add_subdirectory(internal_routing_disabled_acceptance_test) endif() diff --git a/test/benchmark_tests/CMakeLists.txt b/test/benchmark_tests/CMakeLists.txt new file mode 100644 index 000000000..24905ecdd --- /dev/null +++ b/test/benchmark_tests/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +project ("benchmark_tests_bin" LANGUAGES CXX) + +file (GLOB SRCS main.cpp **/*.cpp ../common/utility.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Threads REQUIRED) +find_package(Boost 1.55 COMPONENTS filesystem system REQUIRED) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable (${PROJECT_NAME} ${SRCS} ) +target_link_libraries ( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + benchmark::benchmark + gtest +) + +add_dependencies(build_benchmark_tests ${PROJECT_NAME}) diff --git a/test/benchmark_tests/main.cpp b/test/benchmark_tests/main.cpp new file mode 100644 index 000000000..d859055f6 --- /dev/null +++ b/test/benchmark_tests/main.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_check_credentials.cpp b/test/benchmark_tests/security_tests/bm_check_credentials.cpp new file mode 100644 index 000000000..756cd5f44 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_check_credentials.cpp @@ -0,0 +1,106 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4004201; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4004200; +} + +static void BM_check_credentials_policies_not_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_valid); +} + +static void BM_check_credentials_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_valid); +} + +BENCHMARK(BM_check_credentials_policies_not_loaded); +BENCHMARK(BM_check_credentials_policies_loaded_invalid_values); +BENCHMARK(BM_check_credentials_policies_loaded_valid_values); +BENCHMARK(BM_check_credentials_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_check_credentials_policies_loaded_audit_mode_valid_values); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp b/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp new file mode 100644 index 000000000..ed6ed5797 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4003017; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 5002; +} + +static void BM_check_routing_credentials_policies_not_loaded(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_valid); +} + +static void BM_check_routing_credentials_policies_loaded_lazy_load_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, true); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_lazy_load_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, true); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_valid); +} + +BENCHMARK(BM_check_routing_credentials_policies_not_loaded); +BENCHMARK(BM_check_routing_credentials_policies_loaded_invalid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_valid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_lazy_load_invalid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_lazy_load_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp b/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp new file mode 100644 index 000000000..aa8040686 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::client_t alternate_client = 11; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +vsomeip_v3::uid_t uid_3 = 2; +vsomeip_v3::gid_t gid_3 = 2; +} + +static void BM_get_client_to_sec_client_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_2 = utility::create_uds_client(uid_2, gid_2); + + // add client and security client mappings + security->store_client_to_sec_client_mapping(client, &its_sec_client_uid_gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_2); + } + + vsomeip_sec_client_t its_sec_client_uid_gid_3 = utility::create_uds_client(uid_3, gid_3); + + // add alternate client and security client + security->store_client_to_sec_client_mapping(alternate_client, &its_sec_client_uid_gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_3); + } +} + +static void BM_get_client_to_sec_client_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_1); + } + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_1); + } +} + +BENCHMARK(BM_get_client_to_sec_client_mapping_valid_values); +BENCHMARK(BM_get_client_to_sec_client_mapping_invalid_values); diff --git a/test/benchmark_tests/security_tests/bm_get_clients.cpp b/test/benchmark_tests/security_tests/bm_get_clients.cpp new file mode 100644 index 000000000..091c9e1ef --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_clients.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +std::unordered_set clients; +std::unordered_set local_clients; +vsomeip_v3::client_t client_1 = 10; +vsomeip_v3::client_t client_2 = 11; +vsomeip_v3::client_t client_3 = 12; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +static void BM_get_clients(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid, gid); + + // Loop to do the benchmark test the get with an empty clients list. + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } + + local_clients.insert(client_1); + security->store_client_to_sec_client_mapping(client_1, &its_sec_client_uid_gid); + + // Loop to do the benchmark test the get with 1 client on the list + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } + + // Repeat with two more clients. + security->store_client_to_sec_client_mapping(client_2, &its_sec_client_uid_gid); + security->store_client_to_sec_client_mapping(client_3, &its_sec_client_uid_gid); + + local_clients.insert(client_2); + local_clients.insert(client_3); + + //Loop to do the benchmark test the get with 3 clients on the list + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } +} + +BENCHMARK(BM_get_clients); diff --git a/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp b/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp new file mode 100644 index 000000000..71a517a15 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +} + +static void BM_get_sec_client_to_clients_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + // Add client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid, client); + + std::set clients_1; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_1); + } + + // Add alternate client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid_alternate, client); + + std::set clients_2; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_2); + } +} + +static void BM_get_sec_client_to_clients_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + std::set clients; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients); + } + + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients); + } +} + +BENCHMARK(BM_get_sec_client_to_clients_mapping_valid_values); +BENCHMARK(BM_get_sec_client_to_clients_mapping_invalid_values); diff --git a/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp new file mode 100644 index 000000000..fbbbde348 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp @@ -0,0 +1,195 @@ +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + + vsomeip_v3::uid_t uid_1 = 4003031; + vsomeip_v3::gid_t gid_1 = 4003031; + vsomeip_v3::service_t service_1 = 0xf913; + + vsomeip_v3::instance_t instance = 0x03; + vsomeip_v3::method_t method = 0x04; + + vsomeip_v3::gid_t invalid_uid = 1; + vsomeip_v3::gid_t invalid_gid = 1; + + vsomeip_v3::gid_t deny_uid = 9999; + vsomeip_v3::gid_t deny_gid = 9999; + vsomeip_v3::service_t deny_service = 0x40; +} + +static void BM_is_client_allowed_policies_not_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_cache_policies_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_deny_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_cache_policies_loaded_audit_mode(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_deny_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method); + } +} + +BENCHMARK(BM_is_client_allowed_policies_not_loaded); +BENCHMARK(BM_is_client_allowed_policies_loaded_valid_values); +BENCHMARK(BM_is_client_allowed_cache_policies_loaded); +BENCHMARK(BM_is_client_allowed_policies_loaded_invalid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_deny_valid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_valid_values); +BENCHMARK(BM_is_client_allowed_cache_policies_loaded_audit_mode); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_deny_valid_values); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp new file mode 100644 index 000000000..4b8299f60 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp @@ -0,0 +1,167 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + +vsomeip_v3::uid_t uid_1 = 4003016; +vsomeip_v3::gid_t gid_1 = 4003016; +vsomeip_v3::service_t service_1 = 0xf8c2; + +vsomeip_v3::service_t deny_service = 0x40; + +vsomeip_v3::instance_t instance = 0x03; + +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::gid_t invalid_gid = 1; + +vsomeip_v3::gid_t deny_uid = 9000; +vsomeip_v3::gid_t deny_gid = 9000; +} + +static void BM_is_offer_allowed_policies_not_loaded(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_valid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_deny_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_deny, deny_service, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_valid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_deny_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_deny, deny_service, instance); + } +} + +BENCHMARK(BM_is_offer_allowed_policies_not_loaded); +BENCHMARK(BM_is_offer_allowed_policies_loaded_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_invalid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_deny_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_deny_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp new file mode 100644 index 000000000..8e3ab4d3e --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp @@ -0,0 +1,358 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; + +vsomeip_v3::uid_t valid_uid { 0 }; +vsomeip_v3::uid_t invalid_uid { 1234567 }; + +vsomeip_v3::gid_t valid_gid { 0 }; + +vsomeip_v3::service_t valid_service { 0xf913 }; +vsomeip_v3::service_t invalid_service { 0x41 }; +} + +static void BM_is_policy_update_allowed_valid_uid_no_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_no_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_valid_uid_valid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_valid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_valid_uid_invalid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_invalid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_ignore_whitelist(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void +BM_is_policy_update_allowed_valid_uid_invalid_request_ignore_whitelist(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +BENCHMARK(BM_is_policy_update_allowed_valid_uid_no_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_no_requests); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_valid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_valid_requests); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_invalid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_invalid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_ignore_whitelist); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_invalid_request_ignore_whitelist); diff --git a/test/benchmark_tests/security_tests/bm_load_policies.cpp b/test/benchmark_tests/security_tests/bm_load_policies.cpp new file mode 100644 index 000000000..bfafd7e74 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_load_policies.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../common/utility.hpp" +#include + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_policies, and check its changes using other methods. +// The remove_security_policy method checks if there is any loaded policy. +// The is_audit method checks the check_credentials value. +// No test was created for allow_remote_clients because it was inacessible. + +static void BM_load_policies_loaded_policies(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_no_policies(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Remove all the policies from the file. + policy_elements.at(0).tree_.get_child("security").erase("policies"); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_check_credentials_true(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the check credentials value as false. + bool check_credentials_value {true}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_check_credentials_false(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the check credentials value as false. + bool check_credentials_value {false}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +BENCHMARK(BM_load_policies_loaded_policies); +BENCHMARK(BM_load_policies_no_policies); +BENCHMARK(BM_load_policies_check_credentials_true); +BENCHMARK(BM_load_policies_check_credentials_false); diff --git a/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp b/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp new file mode 100644 index 000000000..9c9a43d93 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../common/utility.hpp" +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_security_update_whitelist, and check its changes using other methods. +// The is_policy_removal_allowed method checks if a selected uid is present in the whitelist. +// The is_policy_update_allowed method checks if a selected service_id is present in the whitelist. + +static void BM_load_security_update_whitelist_check_no_uids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with an empty list of user uids. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_uids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with a list of uids loaded + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_no_service_ids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies with an empty service id vector. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + + // Add a security whitelist with an empty list of user uids. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_service_ids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with list of service ids loaded. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_whitelist_disabled(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with check_whitelist disabled + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, false); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +BENCHMARK(BM_load_security_update_whitelist_check_no_uids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_no_service_ids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_uids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_service_ids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_whitelist_disabled); diff --git a/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp b/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp new file mode 100644 index 000000000..9a529eb88 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; + +std::pair client_uid_gid{uid, gid}; +} + +static void BM_remove_client_to_sec_client_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client); + } + + for (auto _ : state) { + security->remove_client_to_sec_client_mapping(client); + } +} + +static void BM_remove_client_to_sec_client_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + security->store_client_to_sec_client_mapping(client, &its_sec_client); + security->store_sec_client_to_client_mapping(&its_sec_client, client); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client); + } + + for (auto _ : state) { + security->remove_client_to_sec_client_mapping(client); + } +} + +BENCHMARK(BM_remove_client_to_sec_client_mapping_invalid_values); +BENCHMARK(BM_remove_client_to_sec_client_mapping_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp b/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp new file mode 100644 index 000000000..c56cfd676 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace +{ + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4002200; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4003014; +} + +static void BM_remove_security_policy_policies_not_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + for (auto _ : state) + security->remove_security_policy(invalid_uid, invalid_gid); +} + +static void BM_remove_security_policy_policies_loaded_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + for (const auto &e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->remove_security_policy(invalid_uid, invalid_gid); +} + +static void BM_remove_security_policy_policies_loaded_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + for (const auto &e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->remove_security_policy(valid_uid, valid_gid); +} + +BENCHMARK(BM_remove_security_policy_policies_not_loaded); +BENCHMARK(BM_remove_security_policy_policies_loaded_invalid_values); +BENCHMARK(BM_remove_security_policy_policies_loaded_valid_values); diff --git a/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json b/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json new file mode 100644 index 000000000..ab1b06b8b --- /dev/null +++ b/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json @@ -0,0 +1,255 @@ +{ + "security": { + "policies": [ + { + "credentials": { + "gid": "0", + "uid": "0" + }, + "deny": {} + }, + { + "deny": { + "requests": [ + { + "instance": "any", + "service": "0x40" + } + ] + }, + "credentials": { + "gid": "9999", + "uid": "9999" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91b" + }, + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "5004", + "uid": "4003021" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + }, + { + "instance": "any", + "service": "0xf8c7" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4003029", + "uid": "4003029" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xb025" + }, + { + "instance": "any", + "service": "0xb024" + }, + { + "instance": "any", + "service": "0xb021" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4013210", + "uid": "4013210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91b" + } + ] + }, + "credentials": { + "gid": "4017205", + "uid": "4017205" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4002200", + "4003014" + ], + "uid": [ + "4002200", + "4003014" + ] + } + ] + } + } + ] + } +} diff --git a/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json new file mode 100644 index 000000000..221d0352a --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json @@ -0,0 +1,1556 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8ac" + }, + { + "instance": "any", + "service": "0x102d" + }, + { + "instance": "any", + "service": "0x102e" + }, + { + "instance": "any", + "service": "0xf8a5" + }, + { + "instance": "any", + "service": "0xf8a7" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0x1023" + }, + { + "instance": "any", + "service": "0xf8aa" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0x1002" + }, + { + "instance": "any", + "service": "0xf8ab" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xfea8" + }, + { + "instance": "any", + "service": "0xfe8c" + }, + { + "instance": "any", + "service": "0xf91b" + }, + { + "instance": "any", + "service": "0x101c" + }, + { + "instance": "any", + "service": "0xfe9c" + }, + { + "instance": "any", + "service": "0xb51a" + }, + { + "instance": "any", + "service": "0xfeaa" + }, + { + "instance": "any", + "service": "0xb510" + }, + { + "instance": "any", + "service": "0xfa60" + }, + { + "instance": "any", + "service": "0xf917" + }, + { + "instance": "any", + "service": "0xfeac" + }, + { + "instance": "any", + "service": "0xfe87" + }, + { + "instance": "any", + "service": "0xfe8a" + }, + { + "instance": "any", + "service": "0xfe86" + }, + { + "instance": "any", + "service": "0xfe88" + }, + { + "instance": "any", + "service": "0xfeab" + }, + { + "instance": "any", + "service": "0xfe9d" + }, + { + "instance": "any", + "service": "0xfea3" + }, + { + "instance": "any", + "service": "0xfea6" + }, + { + "instance": "any", + "service": "0xfe8e" + }, + { + "instance": "any", + "service": "0xfe9f" + }, + { + "instance": "any", + "service": "0xfe92" + }, + { + "instance": "any", + "service": "0xb519" + }, + { + "instance": "any", + "service": "0xfe8d" + }, + { + "instance": "any", + "service": "0xfe83" + }, + { + "instance": "any", + "service": "0xfeae" + }, + { + "instance": "any", + "service": "0xfe81" + }, + { + "instance": "any", + "service": "0xfe98" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xfea7" + }, + { + "instance": "any", + "service": "0xfea1" + }, + { + "instance": "any", + "service": "0xfead" + }, + { + "instance": "any", + "service": "0xfe93" + }, + { + "instance": "any", + "service": "0xfe8b" + }, + { + "instance": "any", + "service": "0xfea5" + }, + { + "instance": "any", + "service": "0x1534" + }, + { + "instance": "any", + "service": "0xfeaf" + }, + { + "instance": "any", + "service": "0xf912" + }, + { + "instance": "any", + "service": "0x1506" + }, + { + "instance": "any", + "service": "0xfe90" + }, + { + "instance": "any", + "service": "0x101d" + }, + { + "instance": "any", + "service": "0xfea9" + }, + { + "instance": "any", + "service": "0xf911" + }, + { + "instance": "any", + "service": "0x1001" + }, + { + "instance": "any", + "service": "0xfe9a" + }, + { + "instance": "any", + "service": "0xfe97" + }, + { + "instance": "any", + "service": "0x9001" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xfe9e" + }, + { + "instance": "any", + "service": "0xb513" + }, + { + "instance": "any", + "service": "0xfeb0" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0xfe89" + }, + { + "instance": "any", + "service": "0xfe82" + }, + { + "instance": "any", + "service": "0x1536" + }, + { + "instance": "any", + "service": "0x1531" + }, + { + "instance": "any", + "service": "0xfea4" + }, + { + "instance": "any", + "service": "0xfe9b" + }, + { + "instance": "any", + "service": "0xfe99" + }, + { + "instance": "any", + "service": "0xfe95" + }, + { + "instance": "any", + "service": "0xfe84" + }, + { + "instance": "any", + "service": "0xfea2" + }, + { + "instance": "any", + "service": "0xfe91" + }, + { + "instance": "any", + "service": "0xfe94" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "0", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003029", + "uid": "4003029" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003205", + "uid": "4003205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4005300", + "uid": "4005204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4006200", + "uid": "4006200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006201", + "uid": "4006201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4006220", + "uid": "4006220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006221", + "uid": "4006221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006241", + "uid": "4006241" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007200", + "uid": "4007200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007210", + "uid": "4007210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007211", + "uid": "4007211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007212", + "uid": "4007212" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008303", + "uid": "4008205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008305", + "uid": "4008207" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8aa" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4010200", + "uid": "4010200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8ab" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012230" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012240" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013202", + "uid": "4013202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "5501", + "uid": "4013203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013206" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013209", + "uid": "4013209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013213", + "uid": "4013213" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013214", + "uid": "4013214" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013215", + "uid": "4013215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013217", + "uid": "4013217" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013218", + "uid": "4013218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013219", + "uid": "4013219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013223", + "uid": "4013223" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013225", + "uid": "4013225" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + } + ] + }, + "credentials": { + "gid": "4013229", + "uid": "4013229" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4013233", + "uid": "4013233" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013234", + "uid": "4013234" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4013242", + "uid": "4013242" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4014201", + "uid": "4014201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a5" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0x102d" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4014390", + "uid": "4014390" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4015210", + "uid": "4015210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017201", + "uid": "4017201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4017202", + "uid": "4017202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017208", + "uid": "4017208" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017209", + "uid": "4017209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017210", + "uid": "4017210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8ac" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017211", + "uid": "4017211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017215", + "uid": "4017215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4017216", + "uid": "4017216" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017219", + "uid": "4017219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017220", + "uid": "4017220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017221", + "uid": "4017221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4018204", + "uid": "4018204" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4012300", + "4013225", + "4003031", + "4013201", + "4017219", + "4013202", + "4003014", + "4017221", + "4017201", + "4017211", + "4006200", + "4013213", + "4003026", + "4011201", + "4006220", + "4013218", + "4013217", + "0", + "4014300", + "4013215", + "4003019", + "4013207", + "4013211", + "4013223", + "4008303", + "4013220", + "4005300", + "4003205", + "4013219", + "4007210", + "4003024", + "4004200", + "4007234", + "4006202", + "5510", + "4013200" + ], + "uid": [ + "4013232", + "4013225", + "4003031", + "4012201", + "4013201", + "4005202", + "4017219", + "4008205", + "4013202", + "4003014", + "4017221", + "4017201", + "4004201", + "4017211", + "4006200", + "4013213", + "4003026", + "4011201", + "4006220", + "4013218", + "4013217", + "4013206", + "0", + "4014300", + "4013215", + "4003019", + "4013207", + "4013211", + "4013223", + "4013220", + "4003205", + "4013219", + "4007210", + "4012240", + "4003024", + "4007234", + "4006202", + "4013200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json new file mode 100644 index 000000000..e03049d83 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json @@ -0,0 +1,122 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0x1501" + }, + { + "instance": "any", + "service": "0xf8a8" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0x1532" + } + ] + }, + "credentials": { + "gid": "4002201", + "uid": "4002201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0x1501" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003014" + ], + "uid": [ + "4003014" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json new file mode 100644 index 000000000..9512f8d62 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json @@ -0,0 +1,54 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8a6" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf8c1" + } + ] + }, + "credentials": { + "gid": "4002205", + "uid": "4002205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a6" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003024" + ], + "uid": [ + "4003024" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json new file mode 100644 index 000000000..da35eb4fc --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json @@ -0,0 +1,64 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8d0" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8d0" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4002200", + "4003014" + ], + "uid": [ + "4002200", + "4003014" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json new file mode 100644 index 000000000..0de3d03c9 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json @@ -0,0 +1,1306 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb067" + }, + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xb0a8" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ], + "requests": [ + { + "instance": "any", + "service": "0x1531" + }, + { + "instance": "any", + "service": "0xb519" + }, + { + "instance": "any", + "service": "0xf8c2" + }, + { + "instance": "any", + "service": "0x1024" + }, + { + "instance": "any", + "service": "0x1397" + }, + { + "instance": "any", + "service": "0xb504" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xb020" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xb0a8" + }, + { + "instance": "any", + "service": "0xf918" + }, + { + "instance": "any", + "service": "0x1032" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0x1533" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "0", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "1041" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4002201", + "uid": "4002201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003019", + "uid": "4003019" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003022", + "uid": "4003022" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003027", + "uid": "4003027" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003028", + "uid": "4003028" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003036", + "uid": "4003036" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003203", + "uid": "4003203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003205", + "uid": "4003205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003207", + "uid": "4003207" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4006200", + "uid": "4006200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006220", + "uid": "4006220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006221", + "uid": "4006221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006222", + "uid": "4006222" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + } + ] + }, + "credentials": { + "gid": "4006241", + "uid": "4006241" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007200", + "uid": "4007200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007210", + "uid": "4007210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007211", + "uid": "4007211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007234", + "uid": "4007234" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb067" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4010200", + "uid": "4010200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012230" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012240" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013200", + "uid": "4013200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013206" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013211", + "uid": "4013211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013212", + "uid": "4013212" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013213", + "uid": "4013213" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013214", + "uid": "4013214" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4013218", + "uid": "4013218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4013219", + "uid": "4013219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xb067" + } + ] + }, + "credentials": { + "gid": "4013220", + "uid": "4013220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4014201", + "uid": "4014201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4014390", + "uid": "4014390" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4015200", + "uid": "4015200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4015201", + "uid": "4015201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017200", + "uid": "4017200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017201", + "uid": "4017201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017208", + "uid": "4017208" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017209", + "uid": "4017209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017210", + "uid": "4017210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017211", + "uid": "4017211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017215", + "uid": "4017215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017216", + "uid": "4017216" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017218", + "uid": "4017218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017219", + "uid": "4017219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017220", + "uid": "4017220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017221", + "uid": "4017221" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "0", + "4003016", + "4004200", + "4013207", + "4003015", + "4002200", + "4013200" + ], + "uid": [ + "0", + "4003016", + "4004201", + "4013207", + "4003015", + "4002200", + "4013200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json new file mode 100644 index 000000000..20f0b4761 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json @@ -0,0 +1,82 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf918" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf90c" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf918" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003014", + "0", + "4013207", + "4003203", + "4002200" + ], + "uid": [ + "4003014", + "0", + "4013207", + "4003203", + "4002200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json new file mode 100644 index 000000000..eedb12482 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json @@ -0,0 +1,63 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8c2" + } + ], + "requests": [] + }, + "credentials": { + "gid": "4003016", + "uid": "4003016" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c2" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c2" + } + ] + }, + "credentials": { + "gid": "4013202", + "uid": "4013202" + } + }, + { + "deny": { + "offers": [ + { + "instance": "any", + "service": "0x40" + } + ] + }, + "credentials": { + "gid": "9000", + "uid": "9000" + } + } + ] + } +} diff --git a/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json b/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json new file mode 100644 index 000000000..51993268d --- /dev/null +++ b/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json @@ -0,0 +1 @@ +{"container_policy_extensions": [{"container": "android-rse", "path": "../vsomeip_ext/android"}, {"container": "android-idc", "path": "../vsomeip_ext/android"}, {"container": "android-idc-base", "path": "../vsomeip_ext/android"}]} diff --git a/test/common/examples_policies/vsomeip/vsomeip_security.json b/test/common/examples_policies/vsomeip/vsomeip_security.json new file mode 100644 index 000000000..d278ea869 --- /dev/null +++ b/test/common/examples_policies/vsomeip/vsomeip_security.json @@ -0,0 +1,25 @@ +{ + "routing-credentials": { + "gid": "5002", + "uid": "4003017" + }, + "security": { + "check_credentials": "true", + "policies": [ + { + "allow": {}, + "credentials": { + "gid": "5002", + "uid": "4003017" + } + }, + { + "credentials": { + "gid": "0", + "uid": "0" + }, + "deny": {} + } + ] + } +} diff --git a/test/common/utility.cpp b/test/common/utility.cpp new file mode 100644 index 000000000..478deeb56 --- /dev/null +++ b/test/common/utility.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "utility.hpp" + +void +utility::load_policy_data(std::string _input, + std::vector &_elements, + std::set &_failed) { + + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(_input, its_tree); + _elements.push_back({ _input, its_tree }); + } + catch (boost::property_tree::json_parser_error &e) { + _failed.insert(_input); + } +} + +void +utility::read_data(const std::set &_input, + std::vector &_elements, + std::set &_failed) { + + for (auto i : _input) { + if (vsomeip_v3::utility::is_file(i)) { + load_policy_data(i, _elements, _failed); + } else if (vsomeip_v3::utility::is_folder(i)) { + std::map its_names; + boost::filesystem::path its_path(i); + for (auto j = boost::filesystem::directory_iterator(its_path); + j != boost::filesystem::directory_iterator(); + j++) { + std::string name = j->path().string() + "/vsomeip_security.json"; + if (vsomeip_v3::utility::is_file(name)) + its_names[name] = true; + } + + for (const auto& n : its_names) + load_policy_data(n.first, _elements, _failed); + } + } +} + +std::set +utility::get_all_files_in_dir(const std::string &_dir_path, + const std::vector &_dir_skip_list) { + + // Create a vector of string + std::set list_of_files; + try { + // Check if given path exists and points to a directory + if (boost::filesystem::exists(_dir_path) + && boost::filesystem::is_directory(_dir_path)) { + // Create a Recursive Directory Iterator object and points to the + // starting of directory + boost::filesystem::recursive_directory_iterator iter(_dir_path); + // Create a Recursive Directory Iterator object pointing to end. + boost::filesystem::recursive_directory_iterator end; + // Iterate till end + while (iter != end) { + // Check if current entry is a directory and if exists in + // skip list + if (boost::filesystem::is_directory(iter->path()) + && (std::find(_dir_skip_list.begin(), + _dir_skip_list.end(), iter->path().filename()) + != _dir_skip_list.end())) { + // Boost Filesystem API to skip current directory iteration +#if VSOMEIP_BOOST_VERSION < 108100 + iter.no_push(); +#else + iter.disable_recursion_pending(); +#endif + } else { + // Add the name in vector + list_of_files.insert(iter->path().string()); + } + boost::system::error_code ec; + // Increment the iterator to point to next entry in recursive iteration + iter.increment(ec); + if (ec) { + std::cerr << "Error While Accessing : " << iter->path().string() << " :: " << ec.message() << '\n'; + } + } + } + } + catch (std::system_error & e) { + std::cerr << "Exception :: " << e.what(); + } + return list_of_files; +} + +std::string +utility::get_policies_path() { + + return boost::filesystem::canonical( + boost::filesystem::current_path()).string() + + "/../test/common/examples_policies"; +} + +vsomeip_sec_client_t +utility::create_uds_client(uid_t user, gid_t group) { + vsomeip_sec_client_t result; + result.client_type = VSOMEIP_CLIENT_UDS; + result.client.uds_client = { user, group }; + return result; +} + +void +utility::force_check_credentials( + std::vector &_policy_elements, + std::string _value) { + + for(auto &i : _policy_elements) { + try { + boost::property_tree::ptree &security + = i.tree_.get_child("security"); + boost::property_tree::ptree &credentials + = security.get_child("check_credentials"); + if (credentials.get_value().compare(_value)) { + security.erase("check_credentials"); + credentials.put("check_credentials", _value); + } + } + catch(...) {} + } + } + +void utility::get_policy_uids(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_uids) +{ + try { + std::vector user_ids; + auto policy_tree = _policy_element.tree_.get_child("security.policies"); + for (auto policy_node : policy_tree) { + auto optional_credential_node = + policy_node.second.get_child_optional("credentials.uid"); + if (optional_credential_node) { + auto optional_user_id = + optional_credential_node.get().get_value_optional(); + if (optional_user_id) { + user_ids.push_back(optional_user_id.get()); + } + } + } + for (const std::string &uid_string : user_ids) { + _out_uids.push_back((vsomeip_v3::uid_t)std::strtoul(uid_string.c_str(), NULL, 0)); + } + } catch (...) { + std::cerr << "Caught exception while reading user ids in policy element \"" + << _policy_element.name_ << "\"!" << std::endl; + } +} + +void utility::get_policy_services(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_services) +{ + try { + std::vector services; + auto policy_tree = _policy_element.tree_.get_child("security.policies"); + for (auto policy_node : policy_tree) { + // Get allowed request services. + auto allow_requests = policy_node.second.get_child_optional("allow.requests"); + if (allow_requests) { + for (auto &request_node : allow_requests.get()) { + auto optional_service = request_node.second.get_child("service") + .get_value_optional(); + if (optional_service) { + services.push_back(optional_service.get()); + } + } + } + // Get denied request services. + auto deny_requests = policy_node.second.get_child_optional("deny.requests"); + if (deny_requests) { + for (auto &request_node : deny_requests.get()) { + auto optional_service = request_node.second.get_child("service") + .get_value_optional(); + if (optional_service) { + services.push_back(optional_service.get()); + } + } + } + } + for (const std::string &service_str : services) { + _out_services.push_back( + (vsomeip_v3::service_t)std::strtoul(service_str.c_str(), NULL, 0)); + } + } catch (...) { + std::cerr << "Caught exception while reading services in policy element \"" + << _policy_element.name_ << "\"!" << std::endl; + } +} + +void utility::add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const bool _check_whitelist) +{ + std::vector user_ids; + get_policy_uids(_policy_element, user_ids); + + std::vector services; + get_policy_services(_policy_element, services); + + add_security_whitelist(_policy_element, user_ids, services, _check_whitelist); +} + +void utility::add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const std::vector &_user_ids, + const std::vector &_services, + const bool _check_whitelist) +{ + // Add the user ids to the whitelist. + boost::property_tree::ptree id_array_node; + for (auto user_id : _user_ids) { + boost::property_tree::ptree id_node; + id_node.put("", user_id); + id_array_node.push_back(std::make_pair("", id_node)); + } + _policy_element.tree_.add_child("security-update-whitelist.uids", id_array_node); + + // Add the services to the whitelist. + boost::property_tree::ptree service_array_node; + for (auto service : _services) { + boost::property_tree::ptree service_node; + service_node.put("", service); + service_array_node.push_back(std::make_pair("", service_node)); + } + _policy_element.tree_.add_child("security-update-whitelist.services", service_array_node); + + // Update the 'check_whitelist' flag. + _policy_element.tree_.add("security-update-whitelist.check-whitelist", _check_whitelist); +} diff --git a/test/common/utility.hpp b/test/common/utility.hpp new file mode 100644 index 000000000..b4f110068 --- /dev/null +++ b/test/common/utility.hpp @@ -0,0 +1,77 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../implementation/security/include/policy_manager_impl.hpp" +#include "../../implementation/configuration/include/configuration_impl.hpp" +#include "../../implementation/utility/include/utility.hpp" + +// This is needed to silence internal warnings in boost, when e.g. including +#define BOOST_BIND_GLOBAL_PLACEHOLDERS + +#include +#include +#include + +#include + +class utility { +public: + static void load_policy_data(std::string _input, + std::vector &_elements, + std::set &_failed); + + static void read_data(const std::set &_input, + std::vector &_elements, std::set &_failed); + + static std::set get_all_files_in_dir(const std::string &_dir_path, + const std::vector &_dir_skip_list); + + static std::string get_policies_path(); + + static vsomeip_sec_client_t create_uds_client(uid_t user, gid_t group); + + static void force_check_credentials(std::vector &_policy_elements, std::string _value); + /** + * @brief Get all of the user ids in the given policy element. + * + * @param _policy_element + * @param _out_uids + */ + static void get_policy_uids(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_uids); + + /** + * @brief Get all of the services in the given policy element. + * + * @param _policy_element + * @param _out_services + */ + static void get_policy_services(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_services); + + /** + * @brief Add a security whitelist to the given policy element. Uses all user ids and + * services mentioned in the policy. + * + * @param _policy_element + * @param _check_whitelist + */ + static void add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const bool _check_whitelist); + + /** + * @brief Add a security whitelist with the given ids and services to the policy element. + * + * @param _policy_element + * @param _user_ids + * @param _services + * @param _check_whitelist + */ + static void add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const std::vector &_user_ids, + const std::vector &_services, + const bool _check_whitelist); +}; diff --git a/test/internal_routing_disabled_acceptance_test/CMakeLists.txt b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt new file mode 100644 index 000000000..c82335010 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.4...3.22) + +# Workaround for version range in cmake_minimum_required() before 3.12 +if(${CMAKE_VERSION} VERSION_LESS 3.12) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +endif() + +project(internal_routing_disabled_acceptance_test LANGUAGES CXX) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -pedantic -Wall -Wconversion -Wextra") +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Threads REQUIRED) +find_package(Boost 1.55 COMPONENTS system REQUIRED) + +add_executable(${PROJECT_NAME} applet.cpp client.cpp server.cpp main.cpp) +target_include_directories(${PROJECT_NAME} PRIVATE ${gtest_SOURCE_DIR}/include) +target_link_libraries(${PROJECT_NAME} PRIVATE gtest Threads::Threads vsomeip3 ${Boost_LIBRARIES}) + +enable_testing() +add_test(NAME ${PROJECT_NAME} COMMAND $) +add_dependencies(build_network_tests ${PROJECT_NAME}) +configure_file(vsomeip.json vsomeip.json COPYONLY) +set_property( + TEST ${PROJECT_NAME} + APPEND PROPERTY ENVIRONMENT + "LD_LIBRARY_PATH=$" + "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/vsomeip.json" +) +set_property( + TEST ${PROJECT_NAME} + APPEND PROPERTY TIMEOUT + 60 +) diff --git a/test/internal_routing_disabled_acceptance_test/applet.cpp b/test/internal_routing_disabled_acceptance_test/applet.cpp new file mode 100644 index 000000000..50bf41c6c --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/applet.cpp @@ -0,0 +1,44 @@ +#include "applet.hpp" + +#include +#include + +#include +#include + +applet::applet(std::string_view name) : application{vsomeip_v3::runtime::get()->create_application(std::string{name})} +{ + if(!this->application->init()) + { + using namespace std::string_literals; + throw std::runtime_error{__func__ + "(): vSomeIP application init failure"s}; + } + + this->async_start = std::async( + std::launch::async, + &vsomeip_v3::application::start, + this->application + ); + + this->application->register_state_handler( + [this](vsomeip_v3::state_type_e state){ + switch(state) + { + case vsomeip_v3::state_type_e::ST_REGISTERED: + return this->on_state_registered(); + case vsomeip_v3::state_type_e::ST_DEREGISTERED: + return this->on_state_deregistered(); + } + } + ); +} + +applet::~applet() +{ + this->application->clear_all_handler(); + this->application->stop(); + this->async_start.wait(); +} + +void applet::on_state_registered() {} +void applet::on_state_deregistered() {} diff --git a/test/internal_routing_disabled_acceptance_test/applet.hpp b/test/internal_routing_disabled_acceptance_test/applet.hpp new file mode 100644 index 000000000..d536dc0ed --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/applet.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +#include + +struct applet +{ +protected: + std::shared_ptr application; + + applet(std::string_view name); + virtual ~applet(); + +private: + std::future async_start; + + virtual void on_state_registered(); + virtual void on_state_deregistered(); +}; diff --git a/test/internal_routing_disabled_acceptance_test/client.cpp b/test/internal_routing_disabled_acceptance_test/client.cpp new file mode 100644 index 000000000..ff7be781c --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/client.cpp @@ -0,0 +1,152 @@ +#include "client.hpp" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "config.hpp" + +client::client() : applet{"client"}, counter_event_received{}, counter_method_request{}, counter_method_response{} +{ + this->application->register_message_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + vsomeip_v3::ANY_METHOD, + [this](const std::shared_ptr& message){ + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = message->get_payload(); + + switch(message->get_message_type()) + { + case vsomeip_v3::message_type_e::MT_RESPONSE: + std::cout + << "received:\n" + << "\tservice: " << std::hex << message->get_service() << '\n' + << "\tinstance: " << std::hex << message->get_instance() << '\n' + << "\tmethod: " << std::hex << message->get_method() << '\n' + << "\tpayload: " << payload->get_data() << '\n'; + this->counter_method_response++; + break; + + case vsomeip_v3::message_type_e::MT_NOTIFICATION: + std::cout << "GOT NOTIFICATION\n"; + this->counter_event_received++; + [[fallthrough]]; + + default: + std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + } + } + ); + + this->application->register_availability_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + [this](vsomeip_v3::service_t service, vsomeip_v3::instance_t instance, bool available){ + std::cout + << __func__ << '(' + << std::hex << service << ", " + << std::hex << instance << ", " + << std::boolalpha << available << ")\n"; + + if(service != config::SERVICE_ID) + return; + if(instance != config::INSTANCE_ID) + return; + if(!available) + return; + + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + + std::shared_ptr payload = runtime->create_payload(); + constexpr vsomeip_v3::byte_t str[]{"hello world"}; + payload->set_data(str, sizeof(str)); + + std::shared_ptr request = runtime->create_request(); + request->set_service(config::SERVICE_ID); + request->set_instance(config::INSTANCE_ID); + request->set_method(config::METHOD_ID); + request->set_payload(payload); + + for(int i = 0; i < 10; i++) + { + std::cout << "sending: " << str << '\n'; + this->application->send(request); + this->counter_method_request++; + + using namespace std::chrono_literals; + std::this_thread::sleep_for(1s); + } + } + ); + + this->application->request_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + {config::EVENTGROUP_ID}, + vsomeip_v3::event_type_e::ET_FIELD, + vsomeip_v3::reliability_type_e::RT_UNRELIABLE + ); + + this->application->subscribe( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENTGROUP_ID + ); +} + +client::~client() +{ + this->application->unsubscribe( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENTGROUP_ID + ); + + this->application->release_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID + ); + + this->application->release_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +std::size_t client::get_event_count() noexcept +{ + return this->counter_event_received; +} + +std::size_t client::get_method_request_count() noexcept +{ + return this->counter_method_request; +} + +std::size_t client::get_method_response_count() noexcept +{ + return this->counter_method_response; +} + +void client::on_state_registered() +{ + this->application->request_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +void client::on_state_deregistered() +{ + std::cout << "Client is deregistered!!! Probably could not be registered!!!\n"; +} diff --git a/test/internal_routing_disabled_acceptance_test/client.hpp b/test/internal_routing_disabled_acceptance_test/client.hpp new file mode 100644 index 000000000..f6eba6508 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/client.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "applet.hpp" + +struct client final : applet +{ + client(); + ~client(); + + std::size_t get_event_count() noexcept; + std::size_t get_method_request_count() noexcept; + std::size_t get_method_response_count() noexcept; + +private: + void on_state_registered() override; + void on_state_deregistered() override; + + std::atomic_size_t counter_event_received; + std::atomic_size_t counter_method_request; + std::atomic_size_t counter_method_response; +}; diff --git a/test/internal_routing_disabled_acceptance_test/config.hpp b/test/internal_routing_disabled_acceptance_test/config.hpp new file mode 100644 index 000000000..50dab14bf --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/config.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace config +{ + constexpr vsomeip_v3::service_t SERVICE_ID = 0x2222; + constexpr vsomeip_v3::instance_t INSTANCE_ID = 0x3333; + constexpr vsomeip_v3::method_t METHOD_ID = 0x4444; + constexpr vsomeip_v3::event_t EVENT_ID = 0x5555; + constexpr vsomeip_v3::eventgroup_t EVENTGROUP_ID = 0x6666; +} diff --git a/test/internal_routing_disabled_acceptance_test/main.cpp b/test/internal_routing_disabled_acceptance_test/main.cpp new file mode 100644 index 000000000..7a2e7fccf --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include + +#include "client.hpp" +#include "server.hpp" + +TEST(internal_routing_disabled_acceptance_test, check_connectivity) +{ + server s; + client c; + + using namespace std::chrono_literals; + std::this_thread::sleep_for(15s); + + std::cout + << "[server]\n" + << "\tevents: " << s.get_event_count() << '\n' + << "\tmethod requests: " << s.get_method_request_count() << '\n' + << "\tmethod responses: " << s.get_method_response_count() << '\n'; + + std::cout + << "[client]\n" + << "\tevents: " << c.get_event_count() << '\n' + << "\tmethod requests: " << c.get_method_request_count() << '\n' + << "\tmethod responses: " << c.get_method_response_count() << '\n'; + + EXPECT_EQ(s.get_event_count(), 10); + EXPECT_EQ(s.get_method_request_count(), 0); + EXPECT_EQ(s.get_method_response_count(), 0); + + EXPECT_EQ(c.get_event_count(), 0); + EXPECT_EQ(c.get_method_request_count(), 0); + EXPECT_EQ(c.get_method_response_count(), 0); +} + +int main(int count, char** values) +{ + testing::InitGoogleTest(&count, values); + return RUN_ALL_TESTS(); +} diff --git a/test/internal_routing_disabled_acceptance_test/server.cpp b/test/internal_routing_disabled_acceptance_test/server.cpp new file mode 100644 index 000000000..6e00b1e81 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/server.cpp @@ -0,0 +1,132 @@ +#include "server.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +#include "config.hpp" + +server::server() : applet{"server"}, counter_event_sent{}, counter_method_request{}, counter_method_response{} +{ + this->application->register_message_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + config::METHOD_ID, + [this](const std::shared_ptr& message){ + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = message->get_payload(); + + switch(message->get_message_type()) + { + case vsomeip_v3::message_type_e::MT_REQUEST: + std::cout << "GOT REQUEST\n"; + this->counter_method_request++; + { + std::shared_ptr response = runtime->create_response(message); + response->set_payload(payload); + + this->application->send(response); + this->counter_method_response++; + + this->application->notify( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + payload, + true + ); + this->counter_event_sent++; + } + break; + + default: + std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + } + } + ); + + this->application->offer_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + {config::EVENTGROUP_ID}, + vsomeip_v3::event_type_e::ET_FIELD, + {}, + false, + true, + nullptr, + vsomeip_v3::reliability_type_e::RT_UNRELIABLE + ); + + std::thread{ + [this]{ + using namespace std::chrono_literals; + std::this_thread::sleep_for(1s); + + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = runtime->create_payload(); + for(int i = 0; i < 10; i++) + { + int j = i | 0x30; + payload->set_data(reinterpret_cast(&j), sizeof(j)); + this->application->notify( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + payload, + true + ); + this->counter_event_sent++; + + std::this_thread::sleep_for(1s); + } + } + }.detach(); +} + +server::~server() +{ + this->application->stop_offer_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID + ); + + this->application->stop_offer_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +std::size_t server::get_event_count() noexcept +{ + return this->counter_event_sent; +} + +std::size_t server::get_method_request_count() noexcept +{ + return this->counter_method_request; +} + +std::size_t server::get_method_response_count() noexcept +{ + return this->counter_method_response; +} + +void server::on_state_registered() +{ + this->application->offer_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +void server::on_state_deregistered() +{ + std::cout << "Server is deregistered!!! Probably could not be registered!!!\n"; +} diff --git a/test/internal_routing_disabled_acceptance_test/server.hpp b/test/internal_routing_disabled_acceptance_test/server.hpp new file mode 100644 index 000000000..53685f3da --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/server.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "applet.hpp" + +struct server final : applet +{ + server(); + ~server(); + + std::size_t get_event_count() noexcept; + std::size_t get_method_request_count() noexcept; + std::size_t get_method_response_count() noexcept; + +private: + void on_state_registered() override; + void on_state_deregistered() override; + + std::atomic_size_t counter_event_sent; + std::atomic_size_t counter_method_request; + std::atomic_size_t counter_method_response; +}; diff --git a/test/internal_routing_disabled_acceptance_test/vsomeip.json b/test/internal_routing_disabled_acceptance_test/vsomeip.json new file mode 100644 index 000000000..f8ec145ec --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/vsomeip.json @@ -0,0 +1,35 @@ +{ + "logging": { + "level": "trace", + "console": "true" + }, + "applications": [ + { + "name": "server", + "id": "0x1001" + }, + { + "name": "client", + "id": "0x1002" + } + ], + "services": [ + { + "service": "0x2222", + "instance": "0x3333", + "unreliable": 12345 + } + ], + "routing": { + "enabled": "false", + "host": "server", + "address": "127.0.0.1", + "port": 1270 + }, + "service-discovery": { + "enable": "true", + "multicast": "224.244.224.244", + "port": 2240, + "protocol": "udp" + } +} diff --git a/test/network_tests/CMakeLists.txt b/test/network_tests/CMakeLists.txt new file mode 100644 index 000000000..6a1486042 --- /dev/null +++ b/test/network_tests/CMakeLists.txt @@ -0,0 +1,4391 @@ +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +set (VSOMEIP_NAME vsomeip3) + +# Add the gtest header files to the include files +include_directories( + . + ${gtest_SOURCE_DIR}/include +) + +set(TEST_LINK_LIBRARIES gtest) + +set(NETWORK_TEST_BIN_DIR ${PROJECT_BINARY_DIR}/test/network_tests) +set(NETWORK_TEST_SRC_DIR ${PROJECT_SOURCE_DIR}/test/network_tests) + +# Function to copy files into the build directory (or anywhere else) +# On unixoid systems this function will create symlinks instead +# SOURCE_PATH: Path to the file which should be copied +# DESTINATION_PATH: destination file +# TARGET_TO_DEPEND: The copying of the file will be added as +# a dependency to this target +function(copy_to_builddir SOURCE_PATH DESTINATION_PATH TARGET_TO_DEPEND) + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR NOT ${TEST_SYMLINK_CONFIG_FILES}) + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Copying \"${SOURCE_PATH}\" into build directory" + ) + else() + if(${TEST_SYMLINK_CONFIG_FILES_RELATIVE}) + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + # Create a relative link + COMMAND ln -s -r "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" + ) + else() + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + # Create an absolute link + COMMAND ${CMAKE_COMMAND} -E create_symlink "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" + ) + endif() + endif() + # Add a random number to the end of the string to avoid problems with + # duplicate filenames + set(FILENAME "") + get_filename_component(FILENAME ${SOURCE_PATH} NAME ) + string(RANDOM LENGTH 4 ALPHABET 0123456789 RANDOMNUMBER) + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER} + DEPENDS "${DESTINATION_PATH}" + ) + ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER}) + else() + ADD_CUSTOM_TARGET(symlink_${FILENAME}_${RANDOMNUMBER} + DEPENDS "${DESTINATION_PATH}" + ) + ADD_DEPENDENCIES(${TARGET_TO_DEPEND} symlink_${FILENAME}_${RANDOMNUMBER}) + endif() +endfunction() + +############################################################################## +# configuration-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_CONFIGURATION configuration-test) + + add_executable(${TEST_CONFIGURATION} + configuration_tests/configuration-test.cpp + ${PROJECT_SOURCE_DIR}/implementation/plugin/src/plugin_manager_impl.cpp + ${PROJECT_SOURCE_DIR}/test/common/utility.cpp + ) + target_link_libraries(${TEST_CONFIGURATION} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # The following will make sure that ${TEST_CONFIGURATION_CONFIG_FILE} is copied + # from the config folder into the test folder in the builddirectory + # This makes it possible to call the configuration test within the build directory + set(TEST_CONFIGURATION_CONFIG_FILE configuration-test.json) + set(TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE configuration-test-deprecated.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_CONFIG_FILE} + ${TEST_CONFIGURATION} + ) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} + ${TEST_CONFIGURATION} + ) +endif() +############################################################################## +# application test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_APPLICATION application_test) + + add_executable(${TEST_APPLICATION} application_tests/${TEST_APPLICATION}.cpp) + target_link_libraries(${TEST_APPLICATION} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_NAME ${TEST_APPLICATION}_single_process) + add_executable(${TEST_APPLICATION_SINGLE_PROCESS_NAME} application_tests/${TEST_APPLICATION_SINGLE_PROCESS_NAME}.cpp) + target_link_libraries(${TEST_APPLICATION_SINGLE_PROCESS_NAME} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_AVAILABILITY_NAME ${TEST_APPLICATION}_availability) + add_executable(${TEST_APPLICATION_AVAILABILITY_NAME} application_tests/${TEST_APPLICATION_AVAILABILITY_NAME}.cpp) + target_link_libraries(${TEST_APPLICATION_AVAILABILITY_NAME} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE ${TEST_APPLICATION}_single_process.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} + ${TEST_APPLICATION}_single_process + ) + + set(TEST_APPLICATION_CONFIGURATION_FILE ${TEST_APPLICATION}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_daemon.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE ${TEST_APPLICATION}_no_dispatch_threads.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_no_dispatch_threads_daemon.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_STARTER ${TEST_APPLICATION}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_STARTER ${TEST_APPLICATION}_single_process_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ${TEST_APPLICATION}_single_process + ) + + set(TEST_APPLICATION_AVAILABILITY_STARTER ${TEST_APPLICATION_AVAILABILITY_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_AVAILABILITY_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} + ${TEST_APPLICATION_SINGLE_PROCESS_NAME} + ) +endif() +############################################################################## +# magic-cookies-test-client +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_MAGIC_COOKIES_NAME magic_cookies_test) + + set(TEST_MAGIC_COOKIES_CLIENT ${TEST_MAGIC_COOKIES_NAME}_client) + add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT}.cpp) + target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service) + add_executable(${TEST_MAGIC_COOKIES_SERVICE} magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE}.cpp) + target_link_libraries(${TEST_MAGIC_COOKIES_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE ${TEST_MAGIC_COOKIES_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + set(TEST_MAGIC_COOKIES_SERVICE magic_cookies_test_service) + # Copy config file for service into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE ${TEST_MAGIC_COOKIES_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + ${TEST_MAGIC_COOKIES_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_MAGIC_COOKIES_STARTER ${TEST_MAGIC_COOKIES_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} + ${TEST_MAGIC_COOKIES_CLIENT} + ) +endif() +############################################################################## +# someip-header-factory-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_HEADER_FACTORY_NAME header_factory_test) + + set(TEST_HEADER_FACTORY header_factory_test) + add_executable(${TEST_HEADER_FACTORY} header_factory_tests/header_factory_test.cpp) + target_link_libraries(${TEST_HEADER_FACTORY} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + ############################################################################## + # Now comes the second part of the header factory test which consists of ouf + # a client and a service both with settings file and bash scripts to start them + set(TEST_HEADER_FACTORY_CLIENT header_factory_test_client) + add_executable(${TEST_HEADER_FACTORY_CLIENT} header_factory_tests/${TEST_HEADER_FACTORY_CLIENT}.cpp) + target_link_libraries(${TEST_HEADER_FACTORY_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} + ${TEST_HEADER_FACTORY_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_HEADER_FACTORY_CLIENT_START_SCRIPT ${TEST_HEADER_FACTORY_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} + ${TEST_HEADER_FACTORY_CLIENT} + ) + + set(TEST_HEADER_FACTORY_SERVICE header_factory_test_service) + add_executable(${TEST_HEADER_FACTORY_SERVICE} header_factory_tests/${TEST_HEADER_FACTORY_SERVICE}.cpp) + target_link_libraries(${TEST_HEADER_FACTORY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} + ${TEST_HEADER_FACTORY_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_HEADER_FACTORY_SERVICE_START_SCRIPT ${TEST_HEADER_FACTORY_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} + ${TEST_HEADER_FACTORY_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_HEADER_FACTORY_STARTER header_factory_test_send_receive_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} + ${TEST_HEADER_FACTORY_CLIENT} + ) +endif() +############################################################################## +# routing-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_LOCAL_ROUTING_NAME local_routing_test) + + set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) + add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) + add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + ############################################################################## + set(TEST_EXTERNAL_LOCAL_ROUTING_NAME external_local_routing_test) + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE external_local_routing_test_service) + add_executable(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start external client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT external_local_routing_test_client_external) + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_STARTER external_local_routing_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) +else() + set(TEST_LOCAL_ROUTING_NAME local_routing_test) + + set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) + add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) + add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.bat.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ${TEST_LOCAL_ROUTING_CLIENT} + ) +endif() +############################################################################## +# restart_routing-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_RESTART_ROUTING_NAME restart_routing_test) + + set(TEST_RESTART_ROUTING_SERVICE restart_routing_test_service) + add_executable(${TEST_RESTART_ROUTING_SERVICE} restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_RESTART_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE ${TEST_RESTART_ROUTING_SERVICE}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_RESTART_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_RESTART_ROUTING_SERVICE_START_SCRIPT ${TEST_RESTART_ROUTING_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} + ${TEST_RESTART_ROUTING_SERVICE} + ) + + set(TEST_RESTART_ROUTING_CLIENT restart_routing_test_client) + add_executable(${TEST_RESTART_ROUTING_CLIENT} + restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT}.cpp + ) + target_link_libraries(${TEST_RESTART_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE ${TEST_RESTART_ROUTING_CLIENT}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_RESTART_ROUTING_CLIENT_START_SCRIPT ${TEST_RESTART_ROUTING_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_RESTART_ROUTING_STARTER restart_routing_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy config file for autoconfig into $BUILDDIR/test + set(TEST_RESTART_ROUTING_AUTO_CONFIG_FILE ${TEST_RESTART_ROUTING_NAME}_autoconfig.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} + ${TEST_RESTART_ROUTING_CLIENT} + ) +endif() + +############################################################################## +# security test +############################################################################## + +if (${TEST_SECURITY}) + if(NOT ${TESTS_BAT}) + set(TEST_SECURITY_NAME security_test) + set(TEST_SECURITY_SERVICE security_test_service) + set(TEST_SECURITY_CLIENT security_test_client) + + add_executable(${TEST_SECURITY_SERVICE} security_tests/${TEST_SECURITY_SERVICE}.cpp) + target_link_libraries(${TEST_SECURITY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_SECURITY_LOCAL_CONFIG_FILE ${TEST_SECURITY_NAME}_local_config.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_LOCAL_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_LOCAL_CONFIG_FILE} + ${TEST_SECURITY_SERVICE} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_service_external_allow.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_SECURITY_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_client_external_allow.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_SECURITY_SERVICE} + ) + + # Copy service config file for external deny tests into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_service_external_deny.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + ${TEST_SECURITY_SERVICE} + ) + + # Copy client config file for external deny tests into $BUILDDIR/test + set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_client_external_deny.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start local test into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT ${TEST_SECURITY_NAME}_local_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT ${TEST_SECURITY_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT ${TEST_SECURITY_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + add_executable(${TEST_SECURITY_CLIENT} + security_tests/${TEST_SECURITY_CLIENT}.cpp + ) + target_link_libraries(${TEST_SECURITY_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + endif() +endif() + +############################################################################## +# payload-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_LOCAL_PAYLOAD_NAME local_payload_test) + + set(TEST_PAYLOAD_SERVICE payload_test_service) + add_executable(${TEST_PAYLOAD_SERVICE} payload_tests/${TEST_PAYLOAD_SERVICE}.cpp) + target_link_libraries(${TEST_PAYLOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT local_${TEST_PAYLOAD_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + set(TEST_PAYLOAD_CLIENT payload_test_client) + add_executable(${TEST_PAYLOAD_CLIENT} + payload_tests/${TEST_PAYLOAD_CLIENT}.cpp + payload_tests/stopwatch.cpp + ) + target_link_libraries(${TEST_PAYLOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT local_${TEST_PAYLOAD_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_STARTER local_payload_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + set(TEST_EXTERNAL_LOCAL_PAYLOAD_NAME external_local_payload_test) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE external_local_payload_test_service) + + # Copy config file for service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL external_local_payload_test_client_local) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME external_local_payload_test_client_local) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + ############################################################################## + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME external_local_payload_test_client_external) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL external_local_payload_test_client_external) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL external_local_payload_test_service_client_external) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME external_local_payload_test_client_local_and_external) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload) + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) +endif() + +############################################################################## +# big_payload_test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_BIG_PAYLOAD_NAME big_payload_test) + + set(TEST_BIG_PAYLOAD_SERVICE big_payload_test_service) + add_executable(${TEST_BIG_PAYLOAD_SERVICE} big_payload_tests/${TEST_BIG_PAYLOAD_SERVICE}.cpp) + target_link_libraries(${TEST_BIG_PAYLOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_BIG_PAYLOAD_CLIENT big_payload_test_client) + add_executable(${TEST_BIG_PAYLOAD_CLIENT} big_payload_tests/${TEST_BIG_PAYLOAD_CLIENT}.cpp) + target_link_libraries(${TEST_BIG_PAYLOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_queue_limited.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_queue_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_queue_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_client_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_service_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_specific.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_specific.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + # Copy config file for UDP client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client local to $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start service local to $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_local_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_queue_limited) + set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME big_payload_test_local_tcp) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_tcp_random) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_tcp_limited) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_tcp_queue_limited) + # Copy starter as well as client/service start scripts for external tests + set(TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_service_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client for external test into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL big_payload_test_external_limited_general) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL big_payload_test_external_queue_limited_general) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC big_payload_test_external_queue_limited_specific) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP big_payload_test_external_udp) + + # Copy starter as well as client/service start scripts for external tests + set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_service_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_client_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_BIG_PAYLOAD_CLIENT} + ) +endif() + +############################################################################## +# client id tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_CLIENT_ID_NAME client_id_test) + set(TEST_CLIENT_ID_SERVICE ${TEST_CLIENT_ID_NAME}_service) + add_executable(${TEST_CLIENT_ID_SERVICE} client_id_tests/${TEST_CLIENT_ID_NAME}_service.cpp) + target_link_libraries(${TEST_CLIENT_ID_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility) + add_executable(${TEST_CLIENT_ID_UTILITY} + client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp + ${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp) + target_link_libraries(${TEST_CLIENT_ID_UTILITY} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + set(TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_511.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_4095.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_127.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_discontinuous_masked_511.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + # copy starter scripts into builddir + set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} + ${TEST_CLIENT_ID_SERVICE} + ) + set(TEST_CLIENT_ID_SLAVE_STARTER ${TEST_CLIENT_ID_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SLAVE_STARTER} + ${TEST_CLIENT_ID_SERVICE} + ) +endif() + +############################################################################## +# debounce tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_DEBOUNCE_NAME debounce_test) + set(TEST_DEBOUNCE_CLIENT ${TEST_DEBOUNCE_NAME}_client) + add_executable(${TEST_DEBOUNCE_CLIENT} debounce_tests/${TEST_DEBOUNCE_CLIENT}.cpp) + target_link_libraries(${TEST_DEBOUNCE_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + set(TEST_DEBOUNCE_SERVICE ${TEST_DEBOUNCE_NAME}_service) + add_executable(${TEST_DEBOUNCE_SERVICE} debounce_tests/${TEST_DEBOUNCE_SERVICE}.cpp) + target_link_libraries(${TEST_DEBOUNCE_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_DEBOUNCE_MASTER_STARTER ${TEST_DEBOUNCE_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER} + ${TEST_DEBOUNCE_SERVICE} + ) + set(TEST_DEBOUNCE_SLAVE_STARTER ${TEST_DEBOUNCE_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_STARTER} + ${TEST_DEBOUNCE_SERVICE} + ) + + # configure configurations and copy them into builddir + set(TEST_DEBOUNCE_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + ${TEST_DEBOUNCE_SERVICE} + ) + set(TEST_DEBOUNCE_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + ${TEST_DEBOUNCE_SERVICE} + ) +endif() + +############################################################################## +# subscribe notify tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_SUBSCRIBE_NOTIFY_NAME subscribe_notify_test) + set(TEST_SUBSCRIBE_NOTIFY_SERVICE ${TEST_SUBSCRIBE_NOTIFY_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_SERVICE} subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_NAME}_service.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test (local communication via UDS) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # subscribe_notify_test_one_event_two_eventgroups + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME subscribe_notify_test_one_event_two_eventgroups) + + # service + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + # client + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_client) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test (local communication via TCP) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + +endif() + +############################################################################## +# subscribe notify one tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_SUBSCRIBE_NOTIFY_ONE_NAME subscribe_notify_one_test) + set(TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) +endif() + +############################################################################## +# cpu-load-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_CPU_LOAD_NAME cpu_load_test) + + set(TEST_CPU_LOAD_SERVICE cpu_load_test_service) + add_executable(${TEST_CPU_LOAD_SERVICE} + cpu_load_tests/${TEST_CPU_LOAD_SERVICE}.cpp + cpu_load_tests/cpu_load_measurer.cpp + ) + target_link_libraries(${TEST_CPU_LOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + ${TEST_CPU_LOAD_SERVICE} + ) + set(TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + ${TEST_CPU_LOAD_SERVICE} + ) + + ############################################################################## + set(TEST_CPU_LOAD_CLIENT cpu_load_test_client) + add_executable(${TEST_CPU_LOAD_CLIENT} + cpu_load_tests/${TEST_CPU_LOAD_CLIENT}.cpp + cpu_load_tests/cpu_load_measurer.cpp + ) + target_link_libraries(${TEST_CPU_LOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + ${TEST_CPU_LOAD_CLIENT} + ) + set(TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + ${TEST_CPU_LOAD_CLIENT} + ) + + ############################################################################## + # copy starter scripts into builddir + set(TEST_CPU_LOAD_MASTER_STARTER ${TEST_CPU_LOAD_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} + ${TEST_CPU_LOAD_SERVICE} + ) + set(TEST_CPU_LOAD_SLAVE_STARTER ${TEST_CPU_LOAD_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SLAVE_STARTER} + ${TEST_CPU_LOAD_SERVICE} + ) +endif() + +############################################################################## +# initial event tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_INITIAL_EVENT_NAME initial_event_test) + set(TEST_INITIAL_EVENT_SERVICE ${TEST_INITIAL_EVENT_NAME}_service) + add_executable(${TEST_INITIAL_EVENT_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_service.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_CLIENT ${TEST_INITIAL_EVENT_NAME}_client) + add_executable(${TEST_INITIAL_EVENT_CLIENT} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_client.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_AVAILABILITY_CHECKER ${TEST_INITIAL_EVENT_NAME}_availability_checker) + add_executable(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_availability_checker.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_STOP_SERVICE ${TEST_INITIAL_EVENT_NAME}_stop_service) + add_executable(${TEST_INITIAL_EVENT_STOP_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_stop_service.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_STOP_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} + ${TEST_INITIAL_EVENT_SERVICE} + ) + set(TEST_INITIAL_EVENT_SLAVE_STARTER ${TEST_INITIAL_EVENT_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SLAVE_STARTER} + ${TEST_INITIAL_EVENT_SERVICE} + ) +endif() + +############################################################################## +# offer tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_OFFER_NAME offer_test) + set(TEST_OFFER_SERVICE ${TEST_OFFER_NAME}_service) + add_executable(${TEST_OFFER_SERVICE} offer_tests/${TEST_OFFER_NAME}_service.cpp) + target_link_libraries(${TEST_OFFER_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_CLIENT ${TEST_OFFER_NAME}_client) + add_executable(${TEST_OFFER_CLIENT} offer_tests/${TEST_OFFER_NAME}_client.cpp) + target_link_libraries(${TEST_OFFER_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_SERVICE_EXTERNAL ${TEST_OFFER_NAME}_service_external) + add_executable(${TEST_OFFER_SERVICE_EXTERNAL} offer_tests/${TEST_OFFER_NAME}_service_external.cpp) + target_link_libraries(${TEST_OFFER_SERVICE_EXTERNAL} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER ${TEST_OFFER_NAME}_external_sd_msg_sender) + add_executable(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} offer_tests/${TEST_OFFER_NAME}_external_sd_msg_sender.cpp) + target_link_libraries(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # client and service for offer test big sd msg + set(TEST_OFFER_BIG_NAME offer_test_big_sd_msg) + set(TEST_OFFER_BIG_SERVICE ${TEST_OFFER_BIG_NAME}_service) + add_executable(${TEST_OFFER_BIG_SERVICE} offer_tests/${TEST_OFFER_BIG_NAME}_service.cpp) + target_link_libraries(${TEST_OFFER_BIG_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_BIG_CLIENT ${TEST_OFFER_BIG_NAME}_client) + add_executable(${TEST_OFFER_BIG_CLIENT} offer_tests/${TEST_OFFER_BIG_NAME}_client.cpp) + target_link_libraries(${TEST_OFFER_BIG_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER} + ${TEST_OFFER_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_OFFER_LOCAL_CONFIG_FILE ${TEST_OFFER_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + # generate and copy json files into builddir for external test + set(TEST_OFFER_SLAVE_CONFIG_FILE ${TEST_OFFER_NAME}_external_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_SLAVE_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + set(TEST_OFFER_MASTER_CONFIG_FILE ${TEST_OFFER_NAME}_external_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MASTER_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + # generate and copy json files into builddir for big SD message test + set(TEST_OFFER_BIG_SLAVE_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + ${TEST_OFFER_BIG_SERVICE} + ) + + set(TEST_OFFER_BIG_MASTER_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + ${TEST_OFFER_BIG_SERVICE} + ) + + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_EXTERNAL_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + ${TEST_OFFER_SERVICE} + ) + set(TEST_OFFER_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_NAME}_external_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} + ${TEST_OFFER_SERVICE} + ) + + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_BIG_MASTER_STARTER ${TEST_OFFER_BIG_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER} + ${TEST_OFFER_BIG_SERVICE} + ) + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_BIG_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} + ${TEST_OFFER_BIG_SERVICE} + ) +endif() + +############################################################################## +# offered services info tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) + set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) + add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) + add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) +endif() + +############################################################################## +# pending subscription tests tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_PENDING_SUBSCRIPTION_NAME pending_subscription_test) + set(TEST_PENDING_SUBSCRIPTION_SERVICE ${TEST_PENDING_SUBSCRIPTION_NAME}_service) + add_executable(${TEST_PENDING_SUBSCRIPTION_SERVICE} pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_service.cpp) + target_link_libraries(${TEST_PENDING_SUBSCRIPTION_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_PENDING_SUBSCRIPTION_CLIENT ${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender) + add_executable(${TEST_PENDING_SUBSCRIPTION_CLIENT} + pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_PENDING_SUBSCRIPTION_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # copy starter scripts into builddir + set(TEST_PENDING_SUBSCRIPTION_MASTER_STARTER ${TEST_PENDING_SUBSCRIPTION_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + ${TEST_PENDING_SUBSCRIPTION_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_PENDING_SUBSCRIPTION_CONFIG_FILE ${TEST_PENDING_SUBSCRIPTION_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + ${TEST_PENDING_SUBSCRIPTION_SERVICE} + ) +endif() + +############################################################################## +# malicious data tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_MALICIOUS_DATA_NAME malicious_data_test) + set(TEST_MALICIOUS_DATA_SERVICE ${TEST_MALICIOUS_DATA_NAME}_service) + add_executable(${TEST_MALICIOUS_DATA_SERVICE} malicious_data_tests/${TEST_MALICIOUS_DATA_NAME}_service.cpp) + target_link_libraries(${TEST_MALICIOUS_DATA_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_MALICIOUS_DATA_CLIENT ${TEST_MALICIOUS_DATA_NAME}_msg_sender) + add_executable(${TEST_MALICIOUS_DATA_CLIENT} + malicious_data_tests/${TEST_MALICIOUS_DATA_CLIENT}.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_MALICIOUS_DATA_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # copy starter scripts into builddir + set(TEST_MALICIOUS_DATA_MASTER_STARTER ${TEST_MALICIOUS_DATA_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} + ${TEST_MALICIOUS_DATA_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_MALICIOUS_DATA_CONFIG_FILE ${TEST_MALICIOUS_DATA_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_CONFIG_FILE} + ${TEST_MALICIOUS_DATA_SERVICE} + ) +endif() + +############################################################################## +# e2e test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_E2E_NAME e2e_test) + set(TEST_E2E_SERVICE e2e_test_service) + set(TEST_E2E_CLIENT e2e_test_client) + + add_executable(${TEST_E2E_SERVICE} e2e_tests/${TEST_E2E_SERVICE}.cpp) + target_link_libraries(${TEST_E2E_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_E2E_CLIENT} + e2e_tests/${TEST_E2E_CLIENT}.cpp + ) + target_link_libraries(${TEST_E2E_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_service_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_client_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_E2E_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_E2E_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_E2E_SERVICE} + ) +endif() + +############################################################################## +# e2e profile 04 test +############################################################################## + +if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_04}) + set(TEST_E2E_PROFILE_04_NAME e2e_profile_04_test) + set(TEST_E2E_PROFILE_04_SERVICE e2e_profile_04_test_service) + set(TEST_E2E_PROFILE_04_CLIENT e2e_profile_04_test_client) + + add_executable(${TEST_E2E_PROFILE_04_SERVICE} e2e_tests/${TEST_E2E_PROFILE_04_SERVICE}.cpp) + target_link_libraries(${TEST_E2E_PROFILE_04_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_E2E_PROFILE_04_CLIENT} + e2e_tests/${TEST_E2E_PROFILE_04_CLIENT}.cpp + ) + target_link_libraries(${TEST_E2E_PROFILE_04_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_service_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_client_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_E2E_PROFILE_04_SERVICE} + ) +endif() + +############################################################################## +# event tests +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_EVENT_NAME event_test) + set(TEST_EVENT_SERVICE ${TEST_EVENT_NAME}_service) + set(TEST_EVENT_CLIENT ${TEST_EVENT_NAME}_client) + + add_executable(${TEST_EVENT_SERVICE} event_tests/${TEST_EVENT_SERVICE}.cpp) + target_link_libraries(${TEST_EVENT_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_EVENT_CLIENT} + event_tests/${TEST_EVENT_CLIENT}.cpp + ) + target_link_libraries(${TEST_EVENT_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_EVENT_SLAVE_TCP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + ${TEST_EVENT_SERVICE} + ) + + set(TEST_EVENT_SLAVE_UDP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + ${TEST_EVENT_SERVICE} + ) + + set(TEST_EVENT_MASTER_CONFIG_FILE ${TEST_EVENT_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_CONFIG_FILE} + ${TEST_EVENT_CLIENT} + ) + + # Copy bashscript to start test (master) into $BUILDDIR/test + set(TEST_EVENT_MASTER_START_SCRIPT ${TEST_EVENT_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} + ${TEST_EVENT_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_EVENT_SLAVE_START_SCRIPT ${TEST_EVENT_NAME}_slave_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_START_SCRIPT} + ${TEST_EVENT_CLIENT} + ) + +endif() + +############################################################################## +# npdu-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_NPDU_NAME npdu_test) + + set(TEST_NPDU_DAEMON npdu_test_rmd) + set(TEST_NPDU_DAEMON_CLIENT ${TEST_NPDU_DAEMON}_client_side) + add_executable(${TEST_NPDU_DAEMON_CLIENT} npdu_tests/${TEST_NPDU_DAEMON}.cpp) + set_target_properties(${TEST_NPDU_DAEMON_CLIENT} PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE) + target_link_libraries(${TEST_NPDU_DAEMON_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_DAEMON_SERVICE ${TEST_NPDU_DAEMON}_service_side) + add_executable(${TEST_NPDU_DAEMON_SERVICE} npdu_tests/${TEST_NPDU_DAEMON}.cpp) + set_target_properties(${TEST_NPDU_DAEMON_SERVICE} PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE) + target_link_libraries(${TEST_NPDU_DAEMON_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + ############################################################################## + + set(TEST_NPDU_SERVICE npdu_test_service) + + set(TEST_NPDU_SERVICE_ONE npdu_test_service_1) + add_executable(${TEST_NPDU_SERVICE_ONE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_ONE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0) + target_link_libraries(${TEST_NPDU_SERVICE_ONE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_TWO npdu_test_service_2) + add_executable(${TEST_NPDU_SERVICE_TWO} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_TWO} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1) + target_link_libraries(${TEST_NPDU_SERVICE_TWO} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_THREE npdu_test_service_3) + add_executable(${TEST_NPDU_SERVICE_THREE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_THREE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2) + target_link_libraries(${TEST_NPDU_SERVICE_THREE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_FOUR npdu_test_service_4) + add_executable(${TEST_NPDU_SERVICE_FOUR} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_FOUR} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3) + target_link_libraries(${TEST_NPDU_SERVICE_FOUR} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service w/o npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_no_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy bashscript to start service w/o npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_no_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy config file for service with npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy bashscript to start service with npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} + ${TEST_NPDU_SERVICE_ONE} + ) + + ############################################################################## + + set(TEST_NPDU_CLIENT npdu_test_client) + + set(TEST_NPDU_CLIENT_ONE npdu_test_client_1) + add_executable(${TEST_NPDU_CLIENT_ONE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_ONE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_TWO npdu_test_client_2) + add_executable(${TEST_NPDU_CLIENT_TWO} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_TWO} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_THREE npdu_test_client_3) + add_executable(${TEST_NPDU_CLIENT_THREE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_THREE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_FOUR npdu_test_client_4) + add_executable(${TEST_NPDU_CLIENT_FOUR} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_FOUR} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for client w/o npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_no_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy bashscript to start client w/o npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_no_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy config file for client with npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy bashscript to start client with npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} + ${TEST_NPDU_CLIENT_ONE} + ) + + ############################################################################## + + set(TEST_NPDU_STARTER ${TEST_NPDU_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} + ${TEST_NPDU_DAEMON_CLIENT} + ) +endif() + +############################################################################## +# someip tp tests +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_SOMEIPTP_NAME someip_tp_test) + set(TEST_SOMEIPTP_SERVICE ${TEST_SOMEIPTP_NAME}_service) + + add_executable(${TEST_SOMEIPTP_SERVICE} someip_tp_tests/${TEST_SOMEIPTP_SERVICE}.cpp) + target_link_libraries(${TEST_SOMEIPTP_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_SOMEIPTP_CLIENT ${TEST_SOMEIPTP_NAME}_msg_sender) + add_executable(${TEST_SOMEIPTP_CLIENT} + someip_tp_tests/${TEST_SOMEIPTP_CLIENT}.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_SOMEIPTP_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_SOMEIPTP_MASTER_CONFIG_FILE ${TEST_SOMEIPTP_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + ${TEST_SOMEIPTP_CLIENT} + ) + + # Copy bashscript to start test (master) into $BUILDDIR/test + set(TEST_SOMEIPTP_MASTER_START_SCRIPT ${TEST_SOMEIPTP_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_START_SCRIPT}.in + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + ${TEST_SOMEIPTP_SERVICE} + ) +endif() + +############################################################################## +# second IP address tests +############################################################################## + +if(NOT ${TESTS_BAT} AND ${TEST_SECOND_ADDRESS}) + set(TEST_SECOND_ADDRESS_NAME second_address_test) + set(TEST_SECOND_ADDRESS_SERVICE ${TEST_SECOND_ADDRESS_NAME}_service) + set(TEST_SECOND_ADDRESS_CLIENT ${TEST_SECOND_ADDRESS_NAME}_client) + + add_executable(${TEST_SECOND_ADDRESS_SERVICE} + second_address_tests/${TEST_SECOND_ADDRESS_SERVICE}.cpp + ) + target_link_libraries(${TEST_SECOND_ADDRESS_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_SECOND_ADDRESS_CLIENT} + second_address_tests/${TEST_SECOND_ADDRESS_CLIENT}.cpp + ) + target_link_libraries(${TEST_SECOND_ADDRESS_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_service_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_CLIENT} + ) + + set(TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_CLIENT} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_service_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_MASTER_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_slave_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + ${TEST_SECOND_ADDRESS_CLIENT} + ) +endif() + +############################################################################## +# suspend resume tests +############################################################################## +if(NOT ${TESTS_BAT}) + + set(TEST_SUSPEND_RESUME_NAME suspend_resume_test) + set(TEST_SUSPEND_RESUME_SERVICE ${TEST_SUSPEND_RESUME_NAME}_service) + set(TEST_SUSPEND_RESUME_CLIENT ${TEST_SUSPEND_RESUME_NAME}_client) + + add_executable(${TEST_SUSPEND_RESUME_SERVICE} + suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE}.cpp + ) + target_link_libraries(${TEST_SUSPEND_RESUME_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_SUSPEND_RESUME_CLIENT} + suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT}.cpp + ) + target_link_libraries(${TEST_SUSPEND_RESUME_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE ${TEST_SUSPEND_RESUME_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE ${TEST_SUSPEND_RESUME_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_MASTER_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_slave_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + +endif() + +############################################################################## +# Add for every test a dependency to gtest +############################################################################## + +if(NOT ${TESTS_BAT}) + add_dependencies(${TEST_CONFIGURATION} gtest) + add_dependencies(${TEST_APPLICATION} gtest) + add_dependencies(${TEST_APPLICATION_SINGLE_PROCESS_NAME} gtest) + add_dependencies(${TEST_APPLICATION_AVAILABILITY_NAME} gtest) + add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} gtest) + add_dependencies(${TEST_MAGIC_COOKIES_SERVICE} gtest) + add_dependencies(${TEST_HEADER_FACTORY} gtest) + add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) + add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) + add_dependencies(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) + add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) + add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) + add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) + add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest) + add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest) + add_dependencies(${TEST_DEBOUNCE_CLIENT} gtest) + add_dependencies(${TEST_DEBOUNCE_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest) + add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest) + add_dependencies(${TEST_CPU_LOAD_CLIENT} gtest) + add_dependencies(${TEST_INITIAL_EVENT_SERVICE} gtest) + add_dependencies(${TEST_INITIAL_EVENT_CLIENT} gtest) + add_dependencies(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} gtest) + add_dependencies(${TEST_INITIAL_EVENT_STOP_SERVICE} gtest) + add_dependencies(${TEST_OFFER_SERVICE} gtest) + add_dependencies(${TEST_OFFER_CLIENT} gtest) + add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) + add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) + add_dependencies(${TEST_PENDING_SUBSCRIPTION_SERVICE} gtest) + add_dependencies(${TEST_PENDING_SUBSCRIPTION_CLIENT} gtest) + add_dependencies(${TEST_MALICIOUS_DATA_SERVICE} gtest) + add_dependencies(${TEST_MALICIOUS_DATA_CLIENT} gtest) + if (${TEST_SECURITY}) + add_dependencies(${TEST_SECURITY_SERVICE} gtest) + add_dependencies(${TEST_SECURITY_CLIENT} gtest) + endif() + add_dependencies(${TEST_E2E_SERVICE} gtest) + add_dependencies(${TEST_E2E_CLIENT} gtest) + if (${TEST_E2E_PROFILE_04}) + add_dependencies(${TEST_E2E_PROFILE_04_SERVICE} gtest) + add_dependencies(${TEST_E2E_PROFILE_04_CLIENT} gtest) + endif() + add_dependencies(${TEST_EVENT_SERVICE} gtest) + add_dependencies(${TEST_EVENT_CLIENT} gtest) + add_dependencies(${TEST_NPDU_SERVICE_ONE} gtest) + add_dependencies(${TEST_NPDU_SERVICE_TWO} gtest) + add_dependencies(${TEST_NPDU_SERVICE_THREE} gtest) + add_dependencies(${TEST_NPDU_SERVICE_FOUR} gtest) + add_dependencies(${TEST_NPDU_CLIENT_ONE} gtest) + add_dependencies(${TEST_NPDU_CLIENT_TWO} gtest) + add_dependencies(${TEST_NPDU_CLIENT_THREE} gtest) + add_dependencies(${TEST_NPDU_CLIENT_FOUR} gtest) + add_dependencies(${TEST_NPDU_DAEMON_CLIENT} gtest) + add_dependencies(${TEST_NPDU_DAEMON_SERVICE} gtest) + add_dependencies(${TEST_SOMEIPTP_CLIENT} gtest) + add_dependencies(${TEST_SOMEIPTP_SERVICE} gtest) + if(${TEST_SECOND_ADDRESS}) + add_dependencies(${TEST_SECOND_ADDRESS_CLIENT} gtest) + add_dependencies(${TEST_SECOND_ADDRESS_SERVICE} gtest) + endif() + add_dependencies(${TEST_SUSPEND_RESUME_CLIENT} gtest) + add_dependencies(${TEST_SUSPEND_RESUME_SERVICE} gtest) +else() + add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) +endif() + +############################################################################## +# Add tests to the target build_network_tests +############################################################################## + +if(NOT ${TESTS_BAT}) + add_dependencies(build_network_tests ${TEST_CONFIGURATION}) + add_dependencies(build_network_tests ${TEST_APPLICATION}) + add_dependencies(build_network_tests ${TEST_APPLICATION_SINGLE_PROCESS_NAME}) + add_dependencies(build_network_tests ${TEST_APPLICATION_AVAILABILITY_NAME}) + add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_CLIENT}) + add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_SERVICE}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_CLIENT}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) + add_dependencies(build_network_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_PAYLOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_PAYLOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_CLIENT_ID_SERVICE}) + add_dependencies(build_network_tests ${TEST_CLIENT_ID_UTILITY}) + add_dependencies(build_network_tests ${TEST_DEBOUNCE_CLIENT}) + add_dependencies(build_network_tests ${TEST_DEBOUNCE_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE}) + add_dependencies(build_network_tests ${TEST_CPU_LOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_CPU_LOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_SERVICE}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_CLIENT}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_STOP_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_CLIENT}) + add_dependencies(build_network_tests ${TEST_OFFER_SERVICE_EXTERNAL}) + add_dependencies(build_network_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) + add_dependencies(build_network_tests ${TEST_OFFER_BIG_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_BIG_CLIENT}) + add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_CLIENT}) + if (${TEST_SECURITY}) + add_dependencies(build_network_tests ${TEST_SECURITY_SERVICE}) + add_dependencies(build_network_tests ${TEST_SECURITY_CLIENT}) + endif() + add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) + add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) + add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_SERVICE}) + add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_CLIENT}) + add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_SERVICE}) + add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_CLIENT}) + add_dependencies(build_network_tests ${TEST_E2E_SERVICE}) + add_dependencies(build_network_tests ${TEST_E2E_CLIENT}) + if (${TEST_E2E_PROFILE_04}) + add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_SERVICE}) + add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_CLIENT}) + endif() + add_dependencies(build_network_tests ${TEST_EVENT_SERVICE}) + add_dependencies(build_network_tests ${TEST_EVENT_CLIENT}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_ONE}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_TWO}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_THREE}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_FOUR}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_ONE}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_TWO}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_THREE}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_FOUR}) + add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_CLIENT}) + add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_SERVICE}) + add_dependencies(build_network_tests ${TEST_SOMEIPTP_CLIENT}) + add_dependencies(build_network_tests ${TEST_SOMEIPTP_SERVICE}) + if(${TEST_SECOND_ADDRESS}) + add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_CLIENT}) + add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_SERVICE}) + endif() + add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_CLIENT}) + add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_SERVICE}) +else() + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) +endif() + +# some tests require the routingmanagerd +add_dependencies(build_network_tests routingmanagerd) + +############################################################################## +# Add tests +############################################################################## + +if(NOT ${TESTS_BAT}) + add_test(NAME ${TEST_CONFIGURATION} + COMMAND ${TEST_CONFIGURATION} + ) + + # application test + add_test(NAME ${TEST_APPLICATION} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} + ) + set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) + add_test(NAME ${TEST_APPLICATION_SINGLE_PROCESS_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ) + set_tests_properties(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_APPLICATION_AVAILABILITY_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} + ) + set_tests_properties(${TEST_APPLICATION_AVAILABILITY_NAME} PROPERTIES TIMEOUT 120) + + # magic cookies test + add_test(NAME ${TEST_MAGIC_COOKIES_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} + ) + set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 250) + + # Header/Factory tets + add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) + add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} + ) + + # Routing tests + add_test(NAME ${TEST_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ) + + add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 120) + + # Payload tests + add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} + ) + add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ) + set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 960) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) + + # big payload tests + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_LOCAL_TCP_TCP_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) + + # client id tests + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY} + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_511 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_511 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_511 PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_4095 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_4095 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_4095 PROPERTIES TIMEOUT 600) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_127 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_127 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_127 PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 PROPERTIES TIMEOUT 120) + + # debounce tests + add_test(NAME ${TEST_DEBOUNCE_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER}) + set_tests_properties(${TEST_DEBOUNCE_UTILITY} PROPERTIES TIMEOUT 30) + + # subscribe notify tests (local communication via UDS) + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} SAME_SERVICE_ID) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp PROPERTIES TIMEOUT 120) + + # subscribe_notify_tests (local communication via TCP) + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp PROPERTIES TIMEOUT 120) + + # subscribe notify one id tests + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + # cpu load tests + add_test(NAME ${TEST_CPU_LOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} + ) + set_tests_properties(${TEST_CPU_LOAD_NAME} PROPERTIES TIMEOUT 3000) + + # initial event tests + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP CLIENT_SUBSCRIBES_TWICE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice PROPERTIES TIMEOUT 120) + + # offer tests + add_test(NAME ${TEST_OFFER_NAME}_local + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER}) + set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 180) + add_test(NAME ${TEST_OFFER_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) + set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) + add_test(NAME ${TEST_OFFER_BIG_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER}) + set_tests_properties(${TEST_OFFER_BIG_NAME} PROPERTIES TIMEOUT 360) + + # offered services info tets + add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) + set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) + + # Restart-Routing tests + add_test(NAME ${TEST_RESTART_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} + ) + if (${TEST_SECURITY}) + # Security tests + add_test(NAME ${TEST_SECURITY_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ) + add_test(NAME ${TEST_SECURITY_NAME}_external_allow + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_allow.json --allow + ) + add_test(NAME ${TEST_SECURITY_NAME}_external_deny + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_deny.json --deny + ) + endif() + + # pending subscriptions test + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} UNSUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_NACK) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_RESUBSCRIBE_MIXED) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} REQUEST_TO_SD) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port PROPERTIES TIMEOUT 180) + + # malicious data test + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_events + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MALICIOUS_EVENTS) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_events PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_protocol_version + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} PROTOCOL_VERSION) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_protocol_version PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_message_type + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MESSAGE_TYPE) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_message_type PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_return_code + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} RETURN_CODE) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_return_code PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} WRONG_HEADER_FIELDS_UDP) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp PROPERTIES TIMEOUT 180) + + # npdu tests + add_test(NAME ${TEST_NPDU_NAME}_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} UDP sync) + set_tests_properties(${TEST_NPDU_NAME}_udp PROPERTIES TIMEOUT 840) + + add_test(NAME ${TEST_NPDU_NAME}_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} TCP sync) + set_tests_properties(${TEST_NPDU_NAME}_tcp PROPERTIES TIMEOUT 840) + + # e2e tests + add_test(NAME ${TEST_E2E_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} e2e_test_client_external.json) + set_tests_properties(${TEST_E2E_NAME}_external PROPERTIES TIMEOUT 180) + + if (${TEST_E2E_PROFILE_04}) + add_test(NAME ${TEST_E2E_PROFILE_04_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_04_test_client_external.json) + set_tests_properties(${TEST_E2E_PROFILE_04_NAME}_external PROPERTIES TIMEOUT 180) + endif () + + # event tests + add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED UDP) + set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED TCP) + set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_tcp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC UDP) + set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC TCP) + set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_tcp PROPERTIES TIMEOUT 180) + + # SOME/IP-TP tests + add_test(NAME ${TEST_SOMEIPTP_NAME}_in_sequence + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} IN_SEQUENCE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_in_sequence PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_mixed + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} MIXED) + set_tests_properties(${TEST_SOMEIPTP_NAME}_mixed PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_incomplete + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} INCOMPLETE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_incomplete PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_duplicate + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} DUPLICATE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_duplicate PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP) + set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap_front_back + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP_FRONT_BACK) + set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap_front_back PROPERTIES TIMEOUT 180) + + if(${TEST_SECOND_ADDRESS}) + add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} SERVICE UDP + ) + set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} CLIENT UDP + ) + set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp PROPERTIES TIMEOUT 180) + endif() + + # suspend resume test + add_test(NAME ${TEST_SUSPEND_RESUME_NAME}_initial + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} SERVICE + ) + +else() + # Routing tests + add_test(NAME ${TEST_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ) +endif() diff --git a/test/application_tests/application_test.cpp b/test/network_tests/application_tests/application_test.cpp similarity index 99% rename from test/application_tests/application_test.cpp rename to test/network_tests/application_tests/application_test.cpp index e39cf1f29..c7ad4f8c1 100644 --- a/test/application_tests/application_test.cpp +++ b/test/network_tests/application_tests/application_test.cpp @@ -466,7 +466,7 @@ TEST_F(someip_application_exception_test, catch_exception_in_invoked_handler) { } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/application_tests/application_test_availability.cpp b/test/network_tests/application_tests/application_test_availability.cpp similarity index 96% rename from test/application_tests/application_test_availability.cpp rename to test/network_tests/application_tests/application_test_availability.cpp index 06fd33e73..89d94c1c1 100644 --- a/test/application_tests/application_test_availability.cpp +++ b/test/network_tests/application_tests/application_test_availability.cpp @@ -30,7 +30,7 @@ TEST(someip_application_test_availability, register_availability_handlers) its_daemon.stop(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/application_tests/application_test_availability_starter.sh b/test/network_tests/application_tests/application_test_availability_starter.sh similarity index 100% rename from test/application_tests/application_test_availability_starter.sh rename to test/network_tests/application_tests/application_test_availability_starter.sh diff --git a/test/application_tests/application_test_client.cpp b/test/network_tests/application_tests/application_test_client.cpp similarity index 100% rename from test/application_tests/application_test_client.cpp rename to test/network_tests/application_tests/application_test_client.cpp diff --git a/test/application_tests/application_test_client_availability.cpp b/test/network_tests/application_tests/application_test_client_availability.cpp similarity index 100% rename from test/application_tests/application_test_client_availability.cpp rename to test/network_tests/application_tests/application_test_client_availability.cpp diff --git a/test/application_tests/application_test_daemon.cpp b/test/network_tests/application_tests/application_test_daemon.cpp similarity index 100% rename from test/application_tests/application_test_daemon.cpp rename to test/network_tests/application_tests/application_test_daemon.cpp diff --git a/test/application_tests/application_test_globals.hpp b/test/network_tests/application_tests/application_test_globals.hpp similarity index 100% rename from test/application_tests/application_test_globals.hpp rename to test/network_tests/application_tests/application_test_globals.hpp diff --git a/test/application_tests/application_test_service.cpp b/test/network_tests/application_tests/application_test_service.cpp similarity index 100% rename from test/application_tests/application_test_service.cpp rename to test/network_tests/application_tests/application_test_service.cpp diff --git a/test/application_tests/application_test_single_process.cpp b/test/network_tests/application_tests/application_test_single_process.cpp similarity index 97% rename from test/application_tests/application_test_single_process.cpp rename to test/network_tests/application_tests/application_test_single_process.cpp index b4497a7f3..c73889925 100644 --- a/test/application_tests/application_test_single_process.cpp +++ b/test/network_tests/application_tests/application_test_single_process.cpp @@ -38,7 +38,7 @@ TEST(someip_application_test_single_process, notify_increasing_counter) } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/application_tests/application_test_single_process.json b/test/network_tests/application_tests/application_test_single_process.json similarity index 100% rename from test/application_tests/application_test_single_process.json rename to test/network_tests/application_tests/application_test_single_process.json diff --git a/test/application_tests/application_test_single_process_starter.sh b/test/network_tests/application_tests/application_test_single_process_starter.sh similarity index 100% rename from test/application_tests/application_test_single_process_starter.sh rename to test/network_tests/application_tests/application_test_single_process_starter.sh diff --git a/test/application_tests/application_test_starter.sh b/test/network_tests/application_tests/application_test_starter.sh similarity index 93% rename from test/application_tests/application_test_starter.sh rename to test/network_tests/application_tests/application_test_starter.sh index bb1751567..7e8c022da 100755 --- a/test/application_tests/application_test_starter.sh +++ b/test/network_tests/application_tests/application_test_starter.sh @@ -30,7 +30,7 @@ cat <> $WS_ROOT/slave_test_output 2>&1" & - else - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./big_payload_test_service_external_start.sh \" >> $WS_ROOT/slave_test_output 2>&1" & + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_external_service_start.sh" & fi else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <(service_number)]); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/client_id_tests/client_id_test_slave_starter.sh b/test/network_tests/client_id_tests/client_id_test_slave_starter.sh similarity index 100% rename from test/client_id_tests/client_id_test_slave_starter.sh rename to test/network_tests/client_id_tests/client_id_test_slave_starter.sh diff --git a/test/client_id_tests/client_id_test_utility.cpp b/test/network_tests/client_id_tests/client_id_test_utility.cpp similarity index 95% rename from test/client_id_tests/client_id_test_utility.cpp rename to test/network_tests/client_id_tests/client_id_test_utility.cpp index 9cfe5aba6..a74f92295 100644 --- a/test/client_id_tests/client_id_test_utility.cpp +++ b/test/network_tests/client_id_tests/client_id_test_utility.cpp @@ -49,7 +49,7 @@ class client_id_utility_test: public ::testing::Test { if (its_plugin) { auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); if (its_config_plugin) { - configuration_ = its_config_plugin->get_configuration(APPLICATION_NAME_ROUTING_MANAGER); + configuration_ = its_config_plugin->get_configuration(APPLICATION_NAME_ROUTING_MANAGER, ""); } } } @@ -76,7 +76,7 @@ class client_id_utility_test: public ::testing::Test { app_->start(); }); // ensure clean preconditions - utility::reset_client_ids(); + utility::reset_client_ids(configuration_->get_network()); // required as there are two static versions of the utility class in this // test, one in the test itself and one in libvsomeip... @@ -93,7 +93,7 @@ class client_id_utility_test: public ::testing::Test { rm_impl_thread_.join(); } app_.reset(); - utility::release_client_id(client_id_routing_manager_); + utility::release_client_id(configuration_->get_network(), client_id_routing_manager_); } protected: @@ -312,8 +312,8 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_sequential) { EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max", VSOMEIP_CLIENT_UNSET)); - for (const auto& c : its_clients) { - utility::release_client_id(c); + for (const auto c : its_clients) { + utility::release_client_id(configuration_->get_network(), c); } } } @@ -360,7 +360,7 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented) { for (size_t i = 0; i < its_clients.size(); i++ ) { if (i % 2) { its_released_client_ids.push_back(its_clients[i]); - utility::release_client_id(its_clients[i]); + utility::release_client_id(configuration_->get_network(), its_clients[i]); } } for (const client_t c : its_released_client_ids) { @@ -396,8 +396,8 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented) { VSOMEIP_CLIENT_UNSET)); // release all - for (const auto& c : its_clients) { - utility::release_client_id(c); + for (const auto c : its_clients) { + utility::release_client_id(configuration_->get_network(), c); } its_clients.clear(); } @@ -447,7 +447,7 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented_extended) { std::vector its_intermediate_released_client_ids; for (size_t i = 0; i < intermediate_release; i++ ) { its_intermediate_released_client_ids.push_back(its_client_ids[i]); - utility::release_client_id(its_client_ids[i]); + utility::release_client_id(configuration_->get_network(), its_client_ids[i]); its_client_ids.erase(its_client_ids.begin() + i); } @@ -496,7 +496,7 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented_extended) { for (size_t i = 0; i < its_client_ids.size(); i++ ) { if (i % 2) { its_released_client_ids.push_back(its_client_ids[i]); - utility::release_client_id(its_client_ids[i]); + utility::release_client_id(configuration_->get_network(), its_client_ids[i]); } } for (const client_t c : its_released_client_ids) { @@ -534,7 +534,7 @@ TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented_extended) { // release all for (const client_t c : its_client_ids) { - utility::release_client_id(c); + utility::release_client_id(configuration_->get_network(), c); } } @@ -566,7 +566,7 @@ TEST_F(client_id_utility_test, request_released_client_id_after_maximum_client_i } // release a client ID - utility::release_client_id(its_client_ids[10]); + utility::release_client_id(configuration_->get_network(), its_client_ids[10]); // requesting an ID should return the maximum possible ID client_t its_max_client_id = utility::request_client_id(configuration_, @@ -586,7 +586,7 @@ TEST_F(client_id_utility_test, request_released_client_id_after_maximum_client_i EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); // release another ID - utility::release_client_id(its_client_ids[5]); + utility::release_client_id(configuration_->get_network(), its_client_ids[5]); its_client_id = utility::request_client_id(configuration_, APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); @@ -595,12 +595,12 @@ TEST_F(client_id_utility_test, request_released_client_id_after_maximum_client_i // release all for (const client_t c : its_client_ids) { - utility::release_client_id(c); + utility::release_client_id(configuration_->get_network(), c); } its_client_ids.clear(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/client_id_tests/client_id_test_utility.json b/test/network_tests/client_id_tests/client_id_test_utility.json similarity index 100% rename from test/client_id_tests/client_id_test_utility.json rename to test/network_tests/client_id_tests/client_id_test_utility.json diff --git a/test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json b/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json similarity index 100% rename from test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json rename to test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json diff --git a/test/client_id_tests/client_id_test_utility_masked_127.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json similarity index 100% rename from test/client_id_tests/client_id_test_utility_masked_127.json rename to test/network_tests/client_id_tests/client_id_test_utility_masked_127.json diff --git a/test/client_id_tests/client_id_test_utility_masked_4095.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json similarity index 100% rename from test/client_id_tests/client_id_test_utility_masked_4095.json rename to test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json diff --git a/test/client_id_tests/client_id_test_utility_masked_511.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json similarity index 100% rename from test/client_id_tests/client_id_test_utility_masked_511.json rename to test/network_tests/client_id_tests/client_id_test_utility_masked_511.json diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in similarity index 100% rename from test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in rename to test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in diff --git a/test/configuration_tests/configuration-test-deprecated.json b/test/network_tests/configuration_tests/configuration-test-deprecated.json similarity index 100% rename from test/configuration_tests/configuration-test-deprecated.json rename to test/network_tests/configuration_tests/configuration-test-deprecated.json diff --git a/test/configuration_tests/configuration-test.cpp b/test/network_tests/configuration_tests/configuration-test.cpp similarity index 82% rename from test/configuration_tests/configuration-test.cpp rename to test/network_tests/configuration_tests/configuration-test.cpp index ad4faa72c..800852e83 100644 --- a/test/configuration_tests/configuration-test.cpp +++ b/test/network_tests/configuration_tests/configuration-test.cpp @@ -8,6 +8,8 @@ #include +#include "../../common/utility.hpp" + #include #include #include @@ -16,7 +18,8 @@ #include "../../implementation/plugin/include/plugin_manager_impl.hpp" #include "../../implementation/configuration/include/configuration_impl.hpp" #include "../../implementation/configuration/include/configuration_plugin.hpp" -#include "../../implementation/security/include/security_impl.hpp" +#include "../../implementation/protocol/include/protocol.hpp" +#include "../../implementation/security/include/policy_manager_impl.hpp" namespace vsomeip = vsomeip_v3; @@ -156,7 +159,7 @@ void check_file(const std::string &_config_file, // 0. Set environment variable to config file and load it -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) setenv("VSOMEIP_CONFIGURATION", _config_file.c_str(), 1); #else _putenv_s("VSOMEIP_CONFIGURATION", _config_file.c_str() @@ -170,7 +173,7 @@ void check_file(const std::string &_config_file, auto its_configuration_plugin = std::dynamic_pointer_cast(its_plugin); if (its_configuration_plugin) - its_configuration = its_configuration_plugin->get_configuration(EXPECTED_ROUTING_MANAGER_HOST); + its_configuration = its_configuration_plugin->get_configuration(EXPECTED_ROUTING_MANAGER_HOST, ""); } // 2. Did we get a configuration object? @@ -263,47 +266,47 @@ void check_file(const std::string &_config_file, if (its_channel_name == std::string("testname")) { EXPECT_EQ(2u, its_matches.size()); - for (const vsomeip::trace::match_t m : its_matches) { + for (const vsomeip::trace::match_t &m : its_matches) { EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || std::get<0>(m) == vsomeip::service_t(2222)); EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); - EXPECT_TRUE(f->is_positive_); + EXPECT_EQ(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); EXPECT_FALSE(f->is_range_); } } else if (its_channel_name == std::string("testname2")) { EXPECT_EQ(2u, its_matches.size()); - for (const vsomeip::trace::match_t m : its_matches) { + for (const vsomeip::trace::match_t &m : its_matches) { EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x3333) || std::get<0>(m) == vsomeip::service_t(4444)); EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); - EXPECT_FALSE(f->is_positive_); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); EXPECT_FALSE(f->is_range_); } } else if (its_channel_name == std::string("testname3")) { EXPECT_EQ(2u, its_matches.size()); - for (const vsomeip::trace::match_t m : its_matches) { + for (const vsomeip::trace::match_t &m : its_matches) { EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || std::get<0>(m) == vsomeip::service_t(0x3333)); EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || std::get<2>(m) == vsomeip::method_t(0x8888)); - EXPECT_FALSE(f->is_positive_); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); EXPECT_FALSE(f->is_range_); } } else if (its_channel_name == std::string("testname4")) { EXPECT_EQ(2u, its_matches.size()); - for (const vsomeip::trace::match_t m : its_matches) { + for (const vsomeip::trace::match_t &m : its_matches) { EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || std::get<0>(m) == vsomeip::service_t(0x3333)); EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0x0001)); EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || std::get<2>(m) == vsomeip::method_t(0x8888)); - EXPECT_FALSE(f->is_positive_); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); EXPECT_TRUE(f->is_range_); } } @@ -516,7 +519,7 @@ void check_file(const std::string &_config_file, // use 17000 instead of 1500 as configured max-local-payload size will be // increased to bigger max-reliable-payload-size std::uint32_t max_local_message_size( - 17000u + 16u + + VSOMEIP_SEND_COMMAND_SIZE); + 17000u + 16u + vsomeip::protocol::SEND_COMMAND_HEADER_SIZE); EXPECT_EQ(max_local_message_size, its_configuration->get_max_message_size_local()); EXPECT_EQ(11u, its_configuration->get_buffer_shrink_threshold()); EXPECT_EQ(14999u + 16u, its_configuration->get_max_message_size_reliable("10.10.10.10", 7777)); @@ -524,103 +527,120 @@ void check_file(const std::string &_config_file, EXPECT_EQ(15001u + 16, its_configuration->get_max_message_size_reliable("10.10.10.11", 7778)); // security - EXPECT_TRUE(its_configuration->check_routing_credentials(0x7788, 0x123, 0x456)); +#ifndef VSOMEIP_DISABLE_SECURITY + vsomeip_sec_client_t its_x123_x456 = utility::create_uds_client(0x123, 0x456); + EXPECT_TRUE(its_configuration->check_routing_credentials(0x7788, &its_x123_x456)); // GID does not match - EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, 0x123, 0x222)); + vsomeip_sec_client_t its_x123_x222 = utility::create_uds_client(0x123, 0x222); + EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, &its_x123_x222)); // UID does not match - EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, 0x333, 0x456)); + vsomeip_sec_client_t its_x333_x456 = utility::create_uds_client(0x333, 0x456); + EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, &its_x333_x456)); // client is not the routing manager - EXPECT_TRUE(its_configuration->check_routing_credentials(0x7777, 0x888, 0x999)); - - auto its_security = vsomeip::security_impl::get(); - EXPECT_TRUE(its_security->is_enabled()); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1234, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1235, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5676)); - - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1234, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1233, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1001, 1001, 0x1266, 0x1233, 0x5679)); + vsomeip_sec_client_t its_x888_x999 = utility::create_uds_client(0x888, 0x999); + EXPECT_TRUE(its_configuration->check_routing_credentials(0x7777, &its_x888_x999)); + + EXPECT_TRUE(its_configuration->is_security_enabled()); + vsomeip_sec_client_t its_1000_1000 = utility::create_uds_client(1000, 1000); + vsomeip_sec_client_t its_1001_1001 = utility::create_uds_client(1001, 1001); + vsomeip_sec_client_t its_2000_2000 = utility::create_uds_client(2000, 2000); + vsomeip_sec_client_t its_2001_2001 = utility::create_uds_client(2001, 2001); + vsomeip_sec_client_t its_4000_4000 = utility::create_uds_client(4000, 4000); + vsomeip_sec_client_t its_4001_4001 = utility::create_uds_client(4001, 4001); + vsomeip_sec_client_t its_5000_5000 = utility::create_uds_client(5000, 5000); + vsomeip_sec_client_t its_6000_6000 = utility::create_uds_client(6000, 6000); + vsomeip_sec_client_t its_7000_7000 = utility::create_uds_client(7000, 7000); + vsomeip_sec_client_t its_8000_8000 = utility::create_uds_client(8000, 8000); + vsomeip_sec_client_t its_9000_9000 = utility::create_uds_client(9000, 9000); + + auto its_security = vsomeip::policy_manager_impl::get(); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1234, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1235, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5676)); + + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1234, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1233, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1001_1001, 0x1233, 0x5679)); // explicitly denied offers - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1234, 0x5678)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1235, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1234, 0x5679)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1300, 0x1)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1300, 0x2)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5678)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5675)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5676)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5677)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1234, 0x5678)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1235, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1234, 0x5679)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1300, 0x1)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1300, 0x2)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5678)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5675)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5676)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5677)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5679)); // explicitly allowed requests of methods / events - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5678, 0x0001)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5678, 0x8002)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1346, 0x1234, 0x5688, 0x8002)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8006)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8001)); - - EXPECT_FALSE(its_security->is_client_allowed(2001, 2001, 0x1347, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2001, 2001, 0x1342, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5677, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5700, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8007)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5700, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1230, 0x5678, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1230, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5678, 0x0002)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1446, 0x1234, 0x5678, 0xFFFF)); - EXPECT_TRUE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5679, 0x0003)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5679, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5699, 0x9001)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5699, 0x9006)); - EXPECT_FALSE(its_security->is_client_allowed(4001, 4001, 0x1442, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4001, 4001, 0x1447, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5678, 0x8002)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5688, 0x8002)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8006)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8001)); + + EXPECT_FALSE(its_security->is_client_allowed(&its_2001_2001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2001_2001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5677, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5700, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8007)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5700, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1230, 0x5678, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1230, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5678, 0x0002)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5679, 0x0003)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5679, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5699, 0x9001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5699, 0x9006)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4001_4001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4001_4001, 0x1234, 0x5678, 0xFFFF)); // check that any method ID is allowed - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1237, 0x5678, 0x0001)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1237, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1237, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1237, 0x5678, 0xFFFF)); // check that any instance ID is allowed but only one method ID - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1238, 0x0004, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1238, 0x0004, 0x0002)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1238, 0x0004, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1238, 0x0004, 0x0002)); // DENY NOTHING policy // check that ANY_METHOD is allowed in a "deny nothing" policy - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0xFFFF)); // check that specific method ID is allowed in a "deny nothing" policy - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0x0001)); // ALLOW NOTHING policy // check that ANY_METHOD is denied in a "allow nothing" policy - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0xFFFF)); // check that specific method ID is denied in a "allow nothing" policy - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0x0001)); // DENY only one service instance and ANY_METHOD (0x01 - 0xFFFF) policy - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0x0001)); // allow only one service instance and ANY_METHOD policy - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0xFFFF)); - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0x0001)); // check request service - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0x00, true)); - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0x00, true)); - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0x00, true)); - EXPECT_TRUE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x2222, 0x5678, 0x00, true)); - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0x00, true)); + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0x00, true)); + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0x00, true)); + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0x00, true)); + EXPECT_TRUE(its_security->is_client_allowed(&its_7000_7000, 0x2222, 0x5678, 0x00, true)); + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0x00, true)); - EXPECT_TRUE(its_security->check_credentials(0x1277, 1000, 1000)); - EXPECT_FALSE(its_security->check_credentials(0x1277, 1001, 1001)); - EXPECT_TRUE(its_security->check_credentials(0x1278, 1000, 1000)); - EXPECT_TRUE(its_security->check_credentials(0x1278, 9000, 9000)); + EXPECT_TRUE(its_security->check_credentials(0x1277, &its_1000_1000)); + EXPECT_FALSE(its_security->check_credentials(0x1277, &its_1001_1001)); + EXPECT_TRUE(its_security->check_credentials(0x1278, &its_1000_1000)); + EXPECT_TRUE(its_security->check_credentials(0x1278, &its_9000_9000)); // Security update / removal whitelist EXPECT_TRUE(its_security->is_policy_removal_allowed(1000)); @@ -682,6 +702,7 @@ void check_file(const std::string &_config_file, boost::icl::interval_bounds::closed()), its_instances_methods); EXPECT_FALSE(its_security->is_policy_update_allowed(1000, _policy)); +#endif // !VSOMEIP_DISABLE_SECURITY // TCP connection setting: // max TCP connect time / max allowed number of aborted TCP endpoint restarts until forced restart diff --git a/test/configuration_tests/configuration-test.json b/test/network_tests/configuration_tests/configuration-test.json similarity index 100% rename from test/configuration_tests/configuration-test.json rename to test/network_tests/configuration_tests/configuration-test.json diff --git a/test/cpu_load_tests/conf/cpu_load_test_client_master.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in similarity index 100% rename from test/cpu_load_tests/conf/cpu_load_test_client_master.json.in rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in diff --git a/test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in similarity index 100% rename from test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in diff --git a/test/cpu_load_tests/conf/cpu_load_test_service_master.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in similarity index 100% rename from test/cpu_load_tests/conf/cpu_load_test_service_master.json.in rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in diff --git a/test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in similarity index 100% rename from test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in diff --git a/test/cpu_load_tests/cpu_load_measurer.cpp b/test/network_tests/cpu_load_tests/cpu_load_measurer.cpp similarity index 100% rename from test/cpu_load_tests/cpu_load_measurer.cpp rename to test/network_tests/cpu_load_tests/cpu_load_measurer.cpp diff --git a/test/cpu_load_tests/cpu_load_measurer.hpp b/test/network_tests/cpu_load_tests/cpu_load_measurer.hpp similarity index 100% rename from test/cpu_load_tests/cpu_load_measurer.hpp rename to test/network_tests/cpu_load_tests/cpu_load_measurer.hpp diff --git a/test/cpu_load_tests/cpu_load_test_client.cpp b/test/network_tests/cpu_load_tests/cpu_load_test_client.cpp similarity index 99% rename from test/cpu_load_tests/cpu_load_test_client.cpp rename to test/network_tests/cpu_load_tests/cpu_load_test_client.cpp index 05c8cf122..d1d5104e4 100644 --- a/test/cpu_load_tests/cpu_load_test_client.cpp +++ b/test/network_tests/cpu_load_tests/cpu_load_test_client.cpp @@ -319,7 +319,7 @@ TEST(someip_load_test, DISABLED_send_messages_and_measure_cpu_load) cpu_load_test_client test_client_(protocol, number_of_calls, payload_size, call_service_sync, shutdown_service); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { int i = 0; diff --git a/test/cpu_load_tests/cpu_load_test_globals.hpp b/test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp similarity index 100% rename from test/cpu_load_tests/cpu_load_test_globals.hpp rename to test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp diff --git a/test/cpu_load_tests/cpu_load_test_master_starter.sh b/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh similarity index 90% rename from test/cpu_load_tests/cpu_load_test_master_starter.sh rename to test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh index 138d00e38..30010c2ee 100755 --- a/test/cpu_load_tests/cpu_load_test_master_starter.sh +++ b/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh @@ -19,12 +19,9 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting cpu load test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./cpu_load_test_slave_starter.sh"' & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./cpu_load_test_slave_starter.sh"' & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./cpu_load_test_slave_starter.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./cpu_load_test_slave_starter.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat < +#include + +#include + +#include "debounce_test_client.hpp" + +static std::vector > > payloads__; + + +debounce_test_client::debounce_test_client(debounce_test_id_e _test_id) + : test_id_(_test_id), + index_(0), + is_available_(false), + runner_(std::bind(&debounce_test_client::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_client")) { +} + +bool +debounce_test_client::init() { + + bool its_result = app_->init(); + if (its_result) { + app_->register_availability_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + std::bind(&debounce_test_client::on_availability, this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, + std::bind(&debounce_test_client::on_message, this, + std::placeholders::_1)); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_2); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_4); + } + return (its_result); +} + +void +debounce_test_client::start() { + + app_->start(); +} + +void +debounce_test_client::stop() { + + app_->stop(); +} + +void +debounce_test_client::run() { + + { + std::unique_lock its_lock(run_mutex_); + while (!is_available_) { + auto its_status + = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); + EXPECT_EQ(its_status, std::cv_status::no_timeout); + if (its_status == std::cv_status::timeout) { + VSOMEIP_ERROR << __func__ << ": Debounce service did not become available after 15s."; + stop(); + return; + } + } + } + + VSOMEIP_INFO << __func__ << ": Running test."; + run_test(); + + unsubscribe_all(); + + VSOMEIP_INFO << __func__ << ": Stopping the service."; + stop_service(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + stop(); +} + +void +debounce_test_client::wait() { + + if (runner_.joinable()) + runner_.join(); +} + +void +debounce_test_client::on_availability( + vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + + if (_service == DEBOUNCE_SERVICE + && _instance == DEBOUNCE_INSTANCE) { + + if (_is_available) { + VSOMEIP_ERROR << __func__ << ": Debounce service becomes available."; + { + std::lock_guard its_lock(run_mutex_); + is_available_ = true; + } + run_condition_.notify_one(); + } else { + VSOMEIP_ERROR << __func__ << ": Debounce service becomes unavailable."; + is_available_ = false; + } + } +} + +void +debounce_test_client::on_message( + const std::shared_ptr &_message) { + + std::stringstream s; + s << "RECV: "; + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) + s << std::hex << std::setw(2) << std::setfill('0') + << (int)_message->get_payload()->get_data()[i] << " "; + VSOMEIP_DEBUG << s.str(); + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_FLAT) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + if (!is_equal || index_ == 5) + run_condition_.notify_one(); + } + + return; + } + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT_2 == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_INCREASE + || test_id_ == debounce_test_id_e::DTI_DECREASE) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + + if (!is_equal || index_ == 6) + run_condition_.notify_one(); + } + + return; + } + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT_4 == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_MASK) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + + if (!is_equal || index_ == 6) + run_condition_.notify_one(); + } + + return; + } +} + +bool +debounce_test_client::compare_payload( + const std::shared_ptr &_payload, + std::size_t _index) const { + + auto its_expected_payload = payloads__[test_id_][_index]; + return ((*_payload) == (*its_expected_payload)); +} + +void +debounce_test_client::run_test() { + + // Trigger the test + auto its_runtime = vsomeip::runtime::get(); + auto its_payload = its_runtime->create_payload(); + auto its_message = its_runtime->create_request(false); + its_message->set_service(DEBOUNCE_SERVICE); + its_message->set_instance(DEBOUNCE_INSTANCE); + its_message->set_method(DEBOUNCE_START_METHOD); + its_message->set_interface_version(DEBOUNCE_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_payload(its_payload); + app_->send(its_message); + + // Wait for the result + std::unique_lock its_lock(run_mutex_); + if (!is_available_) { + auto its_result = run_condition_.wait_for( + its_lock, std::chrono::milliseconds(5000)); + + EXPECT_EQ(its_result, std::cv_status::no_timeout); + } + + std::this_thread::sleep_for(std::chrono::seconds(2)); +} + +void +debounce_test_client::unsubscribe_all() { + + app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP); +} + +void +debounce_test_client::stop_service() { + + auto its_runtime = vsomeip::runtime::get(); + auto its_payload = its_runtime->create_payload(); + auto its_message = its_runtime->create_request(false); + its_message->set_service(DEBOUNCE_SERVICE); + its_message->set_instance(DEBOUNCE_INSTANCE); + its_message->set_method(DEBOUNCE_STOP_METHOD); + its_message->set_interface_version(DEBOUNCE_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_payload(its_payload); + app_->send(its_message); +} + + +TEST(debounce_test, flat) { + debounce_test_client its_client(debounce_test_id_e::DTI_FLAT); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, increase) { + debounce_test_client its_client(debounce_test_id_e::DTI_INCREASE); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, decrease) { + debounce_test_client its_client(debounce_test_id_e::DTI_DECREASE); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, mask) { + debounce_test_client its_client(debounce_test_id_e::DTI_MASK); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +int main(int argc, char** argv) { + + std::shared_ptr its_payload; + + // Flat test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + // Increase test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + // Decrease test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + // Mask test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/debounce_tests/debounce_test_client.hpp b/test/network_tests/debounce_tests/debounce_test_client.hpp new file mode 100644 index 000000000..0480ea3ca --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_client.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_CLIENT_HPP_ +#define DEBOUNCE_TEST_CLIENT_HPP_ + +#include +#include +#include + +#include + +#include + +#include "debounce_test_common.hpp" + +class debounce_test_client { +public: + debounce_test_client(debounce_test_id_e _test_id); + + bool init(); + void start(); + void stop(); + + void run(); + void wait(); + +private: + void on_availability( + vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available); + void on_message(const std::shared_ptr &_message); + + void run_test(); + void unsubscribe_all(); + void stop_service(); + + bool compare_payload(const std::shared_ptr &_payload, + std::size_t _index) const; + +private: + debounce_test_id_e test_id_; + size_t index_; + + bool is_available_; + + std::mutex run_mutex_; + std::condition_variable run_condition_; + + std::thread runner_; + std::shared_ptr app_; +}; + +#endif // DEBOUNCE_TEST_CLIENT_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_common.hpp b/test/network_tests/debounce_tests/debounce_test_common.hpp new file mode 100644 index 000000000..b4c5df62b --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_common.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_COMMON_HPP_ +#define DEBOUNCE_TEST_COMMON_HPP_ + +#include + +const vsomeip::service_t DEBOUNCE_SERVICE = 0xb657; +const vsomeip::instance_t DEBOUNCE_INSTANCE = 0x0003; +const vsomeip::method_t DEBOUNCE_START_METHOD = 0x0998; +const vsomeip::method_t DEBOUNCE_STOP_METHOD = 0x0999; +const vsomeip::event_t DEBOUNCE_EVENT = 0x8001; +const vsomeip::event_t DEBOUNCE_EVENT_2 = 0x8002; +const vsomeip::event_t DEBOUNCE_EVENT_4 = 0x8004; +const vsomeip::eventgroup_t DEBOUNCE_EVENTGROUP = 0x0005; +const vsomeip::major_version_t DEBOUNCE_MAJOR = 0x01; +const vsomeip::minor_version_t DEBOUNCE_MINOR = 0x01; + +enum debounce_test_id_e : uint8_t { + DTI_FLAT = 0x00, + DTI_INCREASE = 0x01, + DTI_DECREASE = 0x02, + DTI_MASK = 0x03 +}; + +#endif // DEBOUNCE_TEST_COMMON_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_master_starter.sh b/test/network_tests/debounce_tests/debounce_test_master_starter.sh new file mode 100755 index 000000000..534c2ff06 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_master_starter.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=debounce_test_client.json +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +sleep 1 + +./debounce_test_client & +PID_MASTER=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting debounce test on slave LXC debounce_test_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_test_slave_starter.sh\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_test_slave_starter.sh" & +else +cat < + +#include "debounce_test_service.hpp" + +debounce_test_service::debounce_test_service(debounce_test_id_e _test_id) + : test_id_(_test_id), + is_running_(true), + runner_(std::bind(&debounce_test_service::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_service")) { + +} + +bool +debounce_test_service::init() { + + bool is_initialized = app_->init(); + if (is_initialized) { + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, + std::bind(&debounce_test_service::on_start, this, + std::placeholders::_1)); + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, + std::bind(&debounce_test_service::on_stop, this, + std::placeholders::_1)); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + } + return (is_initialized); +} + +void +debounce_test_service::start() { + + app_->start(); +} + +void +debounce_test_service::stop() { + + app_->stop(); +} + +void +debounce_test_service::run() { + + { + std::unique_lock its_lock(run_mutex_); + auto its_result = run_condition_.wait_for( + its_lock, std::chrono::milliseconds(5000)); + if (its_result == std::cv_status::timeout) + return; + } + + start_test(); +} + +void +debounce_test_service::wait() { + + if (runner_.joinable()) + runner_.join(); +} + +void +debounce_test_service::on_start( + const std::shared_ptr &_message) { + + (void)_message; + + VSOMEIP_INFO << __func__ << ": Starting test " << std::dec << test_id_; + run_condition_.notify_one(); +} + + +void +debounce_test_service::on_stop( + const std::shared_ptr &_message) { + + (void)_message; + + VSOMEIP_INFO << __func__ << ": Received a STOP command."; + is_running_ = false; + stop(); +} + +void +debounce_test_service::start_test() { + + if (test_id_ == debounce_test_id_e::DTI_FLAT) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_INCREASE) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_DECREASE) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_MASK) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x12, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x21, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x25, 0x02, 0x03, 0x04, 0x05, 0x17, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + } +} + +TEST(debounce_test, flat) { + debounce_test_service its_service(debounce_test_id_e::DTI_FLAT); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, increase) { + debounce_test_service its_service(debounce_test_id_e::DTI_INCREASE); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, decrease) { + debounce_test_service its_service(debounce_test_id_e::DTI_DECREASE); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, mask) { + debounce_test_service its_service(debounce_test_id_e::DTI_MASK); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/debounce_tests/debounce_test_service.hpp b/test/network_tests/debounce_tests/debounce_test_service.hpp new file mode 100644 index 000000000..0271ae18c --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_service.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_SERVICE_HPP_ +#define DEBOUNCE_TEST_SERVICE_HPP_ + +#include +#include +#include +#include + +#include + +#include + +#include "debounce_test_common.hpp" + +class debounce_test_service { +public: + debounce_test_service(debounce_test_id_e _test_id); + + bool init(); + void start(); + void stop(); + + void run(); + void wait(); + +private: + void on_start(const std::shared_ptr &_message); + void on_stop(const std::shared_ptr &_message); + + void start_test(); + + debounce_test_id_e test_id_; + + std::mutex run_mutex_; + std::condition_variable run_condition_; + + std::atomic is_running_; + std::thread runner_; + std::shared_ptr app_; +}; + + +#endif // DEBOUNCE_TEST_SERVICE_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_slave_starter.sh b/test/network_tests/debounce_tests/debounce_test_slave_starter.sh new file mode 100755 index 000000000..ce5b230f6 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_slave_starter.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=debounce_test_service.json +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +sleep 1 + +./debounce_test_service & +PID_SLAVE=$! + +# Wait until all slaves are finished +for job in $PID_SLAVE +do + # Fail gets incremented if a client exits with a non-zero exit code + echo "waiting for $job" + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 3 + +# Check if everything went well +exit $FAIL diff --git a/test/e2e_tests/conf/e2e_profile_04_test_client_external.json.in b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in similarity index 100% rename from test/e2e_tests/conf/e2e_profile_04_test_client_external.json.in rename to test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in diff --git a/test/e2e_tests/conf/e2e_profile_04_test_service_external.json.in b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in similarity index 100% rename from test/e2e_tests/conf/e2e_profile_04_test_service_external.json.in rename to test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in diff --git a/test/e2e_tests/conf/e2e_test_client_external.json.in b/test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in similarity index 100% rename from test/e2e_tests/conf/e2e_test_client_external.json.in rename to test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in diff --git a/test/e2e_tests/conf/e2e_test_service_external.json.in b/test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in similarity index 100% rename from test/e2e_tests/conf/e2e_test_service_external.json.in rename to test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in diff --git a/test/e2e_tests/e2e_profile_04_test_client.cpp b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp similarity index 99% rename from test/e2e_tests/e2e_profile_04_test_client.cpp rename to test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp index 7056e168c..23c9c0610 100644 --- a/test/e2e_tests/e2e_profile_04_test_client.cpp +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp @@ -68,7 +68,7 @@ void e2e_profile_04_test_client::on_state(vsomeip::state_type_e _state) { if (_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, false); + app_->request_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE); // request event 0x8001, that is protected by E2E Profile 04 app_->request_event(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, diff --git a/test/e2e_tests/e2e_profile_04_test_client.hpp b/test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp similarity index 100% rename from test/e2e_tests/e2e_profile_04_test_client.hpp rename to test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp diff --git a/test/e2e_tests/e2e_profile_04_test_common.hpp b/test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp similarity index 100% rename from test/e2e_tests/e2e_profile_04_test_common.hpp rename to test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp diff --git a/test/e2e_tests/e2e_profile_04_test_external_master_start.sh b/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh similarity index 88% rename from test/e2e_tests/e2e_profile_04_test_external_master_start.sh rename to test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh index f3d6e3459..df2095b9b 100755 --- a/test/e2e_tests/e2e_profile_04_test_external_master_start.sh +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh @@ -31,12 +31,9 @@ PID_CLIENT=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external e2e profile 04 test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat < its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } + { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } - while (wait_until_service_available_) { - condition_.wait(its_lock); - } + while (wait_until_service_available_) { + condition_.wait(its_lock); + } - while (wait_until_subscription_accepted_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Subscription wasn't accepted in time!"; - break; + while (wait_until_subscription_accepted_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Subscription wasn't accepted in time!"; + break; + } } - } - // call notify method - auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); - its_message->set_service(service_info_.service_id); - its_message->set_instance(service_info_.instance_id); - its_message->set_method(service_info_.notify_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(std::vector({ - static_cast(test_mode_), - static_cast(number_events_to_send_)})); - its_message->set_payload(its_payload); - app_->send(its_message); - - while (wait_until_events_received_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Didn't receive events in time!"; - break; + // call notify method + auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); + its_message->set_service(service_info_.service_id); + its_message->set_instance(service_info_.instance_id); + its_message->set_method(service_info_.notify_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(std::vector({ + static_cast(test_mode_), + static_cast(number_events_to_send_)})); + its_message->set_payload(its_payload); + app_->send(its_message); + + while (wait_until_events_received_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Didn't receive events in time!"; + break; + } } - } - // shutdown service - its_message->set_method(service_info_.shutdown_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); - app_->send(its_message); + // shutdown service + its_message->set_method(service_info_.shutdown_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); + app_->send(its_message); - while (wait_until_shutdown_reply_received_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; - break; + while (wait_until_shutdown_reply_received_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; + break; + } } } VSOMEIP_INFO << "going down"; @@ -251,7 +253,7 @@ TEST(someip_event_test, subscribe_or_call_method_at_service) event_test_client its_sample(event_test::service, passed_mode, use_tcp); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/event_tests/event_test_globals.hpp b/test/network_tests/event_tests/event_test_globals.hpp similarity index 100% rename from test/event_tests/event_test_globals.hpp rename to test/network_tests/event_tests/event_test_globals.hpp diff --git a/test/event_tests/event_test_master_starter.sh b/test/network_tests/event_tests/event_test_master_starter.sh similarity index 85% rename from test/event_tests/event_test_master_starter.sh rename to test/network_tests/event_tests/event_test_master_starter.sh index e00639f68..61dc9bcc4 100755 --- a/test/event_tests/event_test_master_starter.sh +++ b/test/network_tests/event_tests/event_test_master_starter.sh @@ -18,7 +18,7 @@ TESTMODE=$1 COMMUNICATIONMODE=$2 export VSOMEIP_CONFIGURATION=event_test_master.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & PID_VSOMEIPD=$! ./event_test_client $TESTMODE $COMMUNICATIONMODE & @@ -28,12 +28,9 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./event_test_slave_starter.sh $COMMUNICATIONMODE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./event_test_slave_starter.sh $COMMUNICATIONMODE\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <get_return_code(), vsomeip::return_code_e::E_OK); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/header_factory_tests/header_factory_test_client.cpp b/test/network_tests/header_factory_tests/header_factory_test_client.cpp similarity index 99% rename from test/header_factory_tests/header_factory_test_client.cpp rename to test/network_tests/header_factory_tests/header_factory_test_client.cpp index 3ac4a06ea..3435dea90 100644 --- a/test/header_factory_tests/header_factory_test_client.cpp +++ b/test/network_tests/header_factory_tests/header_factory_test_client.cpp @@ -161,7 +161,7 @@ TEST(someip_header_factory_test, send_message_ten_times_test) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/header_factory_tests/header_factory_test_client.hpp b/test/network_tests/header_factory_tests/header_factory_test_client.hpp similarity index 100% rename from test/header_factory_tests/header_factory_test_client.hpp rename to test/network_tests/header_factory_tests/header_factory_test_client.hpp diff --git a/test/header_factory_tests/header_factory_test_client.json b/test/network_tests/header_factory_tests/header_factory_test_client.json similarity index 100% rename from test/header_factory_tests/header_factory_test_client.json rename to test/network_tests/header_factory_tests/header_factory_test_client.json diff --git a/test/header_factory_tests/header_factory_test_client_start.sh b/test/network_tests/header_factory_tests/header_factory_test_client_start.sh similarity index 100% rename from test/header_factory_tests/header_factory_test_client_start.sh rename to test/network_tests/header_factory_tests/header_factory_test_client_start.sh diff --git a/test/header_factory_tests/header_factory_test_send_receive_starter.sh b/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh similarity index 100% rename from test/header_factory_tests/header_factory_test_send_receive_starter.sh rename to test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh diff --git a/test/header_factory_tests/header_factory_test_service.cpp b/test/network_tests/header_factory_tests/header_factory_test_service.cpp similarity index 99% rename from test/header_factory_tests/header_factory_test_service.cpp rename to test/network_tests/header_factory_tests/header_factory_test_service.cpp index d60c74343..4caca7aa3 100644 --- a/test/header_factory_tests/header_factory_test_service.cpp +++ b/test/network_tests/header_factory_tests/header_factory_test_service.cpp @@ -161,7 +161,7 @@ TEST(someip_header_factory_test, reveice_message_ten_times_test) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/header_factory_tests/header_factory_test_service.hpp b/test/network_tests/header_factory_tests/header_factory_test_service.hpp similarity index 100% rename from test/header_factory_tests/header_factory_test_service.hpp rename to test/network_tests/header_factory_tests/header_factory_test_service.hpp diff --git a/test/header_factory_tests/header_factory_test_service.json b/test/network_tests/header_factory_tests/header_factory_test_service.json similarity index 100% rename from test/header_factory_tests/header_factory_test_service.json rename to test/network_tests/header_factory_tests/header_factory_test_service.json diff --git a/test/header_factory_tests/header_factory_test_service_start.sh b/test/network_tests/header_factory_tests/header_factory_test_service_start.sh similarity index 100% rename from test/header_factory_tests/header_factory_test_service_start.sh rename to test/network_tests/header_factory_tests/header_factory_test_service_start.sh diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in similarity index 100% rename from test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in rename to test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in diff --git a/test/initial_event_tests/initial_event_test_availability_checker.cpp b/test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp similarity index 99% rename from test/initial_event_tests/initial_event_test_availability_checker.cpp rename to test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp index 4fc3085d6..f05b5920b 100644 --- a/test/initial_event_tests/initial_event_test_availability_checker.cpp +++ b/test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp @@ -139,7 +139,7 @@ TEST(someip_initial_event_test, wait_for_availability_and_exit) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/initial_event_tests/initial_event_test_client.cpp b/test/network_tests/initial_event_tests/initial_event_test_client.cpp similarity index 99% rename from test/initial_event_tests/initial_event_test_client.cpp rename to test/network_tests/initial_event_tests/initial_event_test_client.cpp index ef215f16d..ba549ab03 100644 --- a/test/initial_event_tests/initial_event_test_client.cpp +++ b/test/network_tests/initial_event_tests/initial_event_test_client.cpp @@ -15,7 +15,7 @@ #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -443,7 +443,6 @@ class initial_event_test_client { sigaddset(&handler_mask, SIGABRT); pthread_sigmask(SIG_UNBLOCK, &handler_mask, NULL); - struct sigaction sa_new, sa_old; sa_new.sa_handler = signal_handler; sa_new.sa_flags = 0; @@ -453,9 +452,6 @@ class initial_event_test_client { ::sigaction(SIGTERM, &sa_new, &sa_old); ::sigaction(SIGABRT, &sa_new, &sa_old); - - - { std::lock_guard its_lock(signal_mutex_); wait_for_signal_handler_registration_ = false; @@ -482,7 +478,8 @@ class initial_event_test_client { while (wait_for_stop_) { stop_condition_.wait_for(its_lock, std::chrono::milliseconds(100)); } - VSOMEIP_ERROR << "(" << std::dec << its_call_number << ") [" << std::setw(4) << std::setfill('0') << std::hex + VSOMEIP_ERROR << "(" << std::dec << its_call_number << ") [" + << std::setw(4) << std::setfill('0') << std::hex << client_number_ << "] Received notifications from all services, going down"; } @@ -567,7 +564,7 @@ TEST(someip_initial_event_test, wait_for_initial_events_of_all_services) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { // Block all signals diff --git a/test/initial_event_tests/initial_event_test_globals.hpp b/test/network_tests/initial_event_tests/initial_event_test_globals.hpp similarity index 100% rename from test/initial_event_tests/initial_event_test_globals.hpp rename to test/network_tests/initial_event_tests/initial_event_test_globals.hpp diff --git a/test/initial_event_tests/initial_event_test_master_starter.sh b/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh similarity index 89% rename from test/initial_event_tests/initial_event_test_master_starter.sh rename to test/network_tests/initial_event_tests/initial_event_test_master_starter.sh index 85607c4ef..9d52e3ff7 100755 --- a/test/initial_event_tests/initial_event_test_master_starter.sh +++ b/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh @@ -28,11 +28,9 @@ print_starter_message () { if [ ! -z "$USE_LXC_TEST" ]; then echo "starting initial event test on slave LXC with params $CLIENT_JSON_FILE $REMAINING_OPTIONS" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\" >> $WS_ROOT/slave_test_output 2>&1" & else cat <get_session() << "] shutdown method called"; - - VSOMEIP_ERROR << "stop_service::" << __func__ - << ": (1)"; std::lock_guard its_lock(stop_mutex_); - VSOMEIP_ERROR << "stop_service::" << __func__ - << ": (2)"; wait_for_stop_ = false; stop_condition_.notify_one(); } @@ -201,7 +196,13 @@ class initial_event_test_stop_service { { std::unique_lock its_lock(mutex_); while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); + auto its_reason = condition_.wait_for(its_lock, std::chrono::milliseconds(250)); + if (its_reason == std::cv_status::timeout) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + wait_until_shutdown_method_called_ = false; + } } } } @@ -266,7 +267,7 @@ TEST(someip_initial_event_test, wait_for_stop_method_to_be_called) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in similarity index 100% rename from test/magic_cookies_tests/conf/magic_cookies_test_client.json.in rename to test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in similarity index 100% rename from test/magic_cookies_tests/conf/magic_cookies_test_service.json.in rename to test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in diff --git a/test/magic_cookies_tests/magic_cookies_test_client.cpp b/test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp similarity index 99% rename from test/magic_cookies_tests/magic_cookies_test_client.cpp rename to test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp index dc02309bd..89a002905 100644 --- a/test/magic_cookies_tests/magic_cookies_test_client.cpp +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp @@ -20,7 +20,7 @@ class magic_cookies_test_client { public: magic_cookies_test_client() - : app_(new vsomeip::application_impl("")), + : app_(new vsomeip::application_impl("", "")), is_blocked_(false), sent_messages_good_(8), sent_messages_bad_(7), diff --git a/test/magic_cookies_tests/magic_cookies_test_client_start.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh similarity index 100% rename from test/magic_cookies_tests/magic_cookies_test_client_start.sh rename to test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh diff --git a/test/magic_cookies_tests/magic_cookies_test_service.cpp b/test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp similarity index 100% rename from test/magic_cookies_tests/magic_cookies_test_service.cpp rename to test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp diff --git a/test/magic_cookies_tests/magic_cookies_test_service_start.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh similarity index 100% rename from test/magic_cookies_tests/magic_cookies_test_service_start.sh rename to test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh diff --git a/test/magic_cookies_tests/magic_cookies_test_starter.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh similarity index 89% rename from test/magic_cookies_tests/magic_cookies_test_starter.sh rename to test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh index d05a37189..1e9cfc4d6 100755 --- a/test/magic_cookies_tests/magic_cookies_test_starter.sh +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh @@ -17,12 +17,9 @@ FAIL=0 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./magic_cookies_test_client_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./magic_cookies_test_client_start.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./magic_cookies_test_client_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./magic_cookies_test_client_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & else cat <(io_)), + work_(std::make_shared(io_)), io_thread_(std::bind(&malicious_data::io_run, this)) {} protected: @@ -49,8 +49,8 @@ class malicious_data : public ::testing::Test { io_.run(); } - boost::asio::io_service io_; - std::shared_ptr work_; + boost::asio::io_context io_; + std::shared_ptr work_; std::thread io_thread_; }; @@ -1570,7 +1570,7 @@ TEST_F(malicious_data, wrong_header_fields_udp) udp_socket.close(ec); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); if(argc < 3) { diff --git a/test/malicious_data_tests/malicious_data_test_service.cpp b/test/network_tests/malicious_data_tests/malicious_data_test_service.cpp similarity index 99% rename from test/malicious_data_tests/malicious_data_test_service.cpp rename to test/network_tests/malicious_data_tests/malicious_data_test_service.cpp index 735f0f65b..0227acb0b 100644 --- a/test/malicious_data_tests/malicious_data_test_service.cpp +++ b/test/network_tests/malicious_data_tests/malicious_data_test_service.cpp @@ -164,7 +164,7 @@ TEST(someip_malicious_data_test, block_subscription_handler) } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/npdu_tests/conf/npdu_test_client_no_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in similarity index 100% rename from test/npdu_tests/conf/npdu_test_client_no_npdu.json.in rename to test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in diff --git a/test/npdu_tests/conf/npdu_test_client_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in similarity index 100% rename from test/npdu_tests/conf/npdu_test_client_npdu.json.in rename to test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in diff --git a/test/npdu_tests/conf/npdu_test_service_no_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in similarity index 100% rename from test/npdu_tests/conf/npdu_test_service_no_npdu.json.in rename to test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in diff --git a/test/npdu_tests/conf/npdu_test_service_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in similarity index 100% rename from test/npdu_tests/conf/npdu_test_service_npdu.json.in rename to test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in diff --git a/test/npdu_tests/npdu_test_client.cpp b/test/network_tests/npdu_tests/npdu_test_client.cpp similarity index 99% rename from test/npdu_tests/npdu_test_client.cpp rename to test/network_tests/npdu_tests/npdu_test_client.cpp index ca29aa6b2..d89d4f43b 100644 --- a/test/npdu_tests/npdu_test_client.cpp +++ b/test/network_tests/npdu_tests/npdu_test_client.cpp @@ -476,7 +476,7 @@ TEST(someip_npdu_test, send_different_payloads) if (its_plugin) { auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); if (its_config_plugin) { - its_configuration = its_config_plugin->get_configuration(""); + its_configuration = its_config_plugin->get_configuration("",""); } } if (!its_configuration) { @@ -530,7 +530,7 @@ TEST(someip_npdu_test, send_different_payloads) } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { std::string tcp_enable("--TCP"); diff --git a/test/npdu_tests/npdu_test_client.hpp b/test/network_tests/npdu_tests/npdu_test_client.hpp similarity index 100% rename from test/npdu_tests/npdu_test_client.hpp rename to test/network_tests/npdu_tests/npdu_test_client.hpp diff --git a/test/npdu_tests/npdu_test_client_no_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh similarity index 100% rename from test/npdu_tests/npdu_test_client_no_npdu_start.sh rename to test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh diff --git a/test/npdu_tests/npdu_test_client_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh similarity index 100% rename from test/npdu_tests/npdu_test_client_npdu_start.sh rename to test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh diff --git a/test/npdu_tests/npdu_test_globals.hpp b/test/network_tests/npdu_tests/npdu_test_globals.hpp similarity index 100% rename from test/npdu_tests/npdu_test_globals.hpp rename to test/network_tests/npdu_tests/npdu_test_globals.hpp diff --git a/test/npdu_tests/npdu_test_rmd.cpp b/test/network_tests/npdu_tests/npdu_test_rmd.cpp similarity index 99% rename from test/npdu_tests/npdu_test_rmd.cpp rename to test/network_tests/npdu_tests/npdu_test_rmd.cpp index 1174a91aa..8e5451bd4 100644 --- a/test/npdu_tests/npdu_test_rmd.cpp +++ b/test/network_tests/npdu_tests/npdu_test_rmd.cpp @@ -83,7 +83,7 @@ void npdu_test_rmd::on_message_shutdown( (void)_request; std::shared_ptr request = vsomeip::runtime::get()->create_request(false); #ifdef RMD_CLIENT_SIDE - static int counter = 0; + static uint32_t counter = 0; counter++; VSOMEIP_INFO << counter << " of " << npdu_test::client_ids_clients.size() << " clients are finished."; diff --git a/test/npdu_tests/npdu_test_rmd.hpp b/test/network_tests/npdu_tests/npdu_test_rmd.hpp similarity index 100% rename from test/npdu_tests/npdu_test_rmd.hpp rename to test/network_tests/npdu_tests/npdu_test_rmd.hpp diff --git a/test/npdu_tests/npdu_test_service.cpp b/test/network_tests/npdu_tests/npdu_test_service.cpp similarity index 99% rename from test/npdu_tests/npdu_test_service.cpp rename to test/network_tests/npdu_tests/npdu_test_service.cpp index ccbdd66cd..b4ee9840d 100644 --- a/test/npdu_tests/npdu_test_service.cpp +++ b/test/network_tests/npdu_tests/npdu_test_service.cpp @@ -92,7 +92,7 @@ void npdu_test_service::stop() VSOMEIP_INFO << "Stopping..."; if (!undershot_debounce_times_.empty()) { std::chrono::microseconds sum(0); - for (const auto& t : undershot_debounce_times_) { + for (const auto t : undershot_debounce_times_) { sum += t; } double average = static_cast(sum.count())/static_cast(undershot_debounce_times_.size()); @@ -234,7 +234,7 @@ TEST(someip_npdu_test, offer_service_and_check_debounce_times) if (its_plugin) { auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); if (its_config_plugin) { - its_configuration = its_config_plugin->get_configuration(""); + its_configuration = its_config_plugin->get_configuration("",""); } } if (!its_configuration) { @@ -286,7 +286,7 @@ TEST(someip_npdu_test, offer_service_and_check_debounce_times) test_service.join_shutdown_thread(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { int i = 1; diff --git a/test/npdu_tests/npdu_test_service.hpp b/test/network_tests/npdu_tests/npdu_test_service.hpp similarity index 100% rename from test/npdu_tests/npdu_test_service.hpp rename to test/network_tests/npdu_tests/npdu_test_service.hpp diff --git a/test/npdu_tests/npdu_test_service_no_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh similarity index 100% rename from test/npdu_tests/npdu_test_service_no_npdu_start.sh rename to test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh diff --git a/test/npdu_tests/npdu_test_service_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh similarity index 100% rename from test/npdu_tests/npdu_test_service_npdu_start.sh rename to test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh diff --git a/test/npdu_tests/npdu_test_starter.sh b/test/network_tests/npdu_tests/npdu_test_starter.sh similarity index 90% rename from test/npdu_tests/npdu_test_starter.sh rename to test/network_tests/npdu_tests/npdu_test_starter.sh index c405adc36..51904c9ed 100755 --- a/test/npdu_tests/npdu_test_starter.sh +++ b/test/network_tests/npdu_tests/npdu_test_starter.sh @@ -71,13 +71,9 @@ start_services if [ ! -z "$USE_LXC_TEST" ]; then echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./npdu_test_client_npdu_start.sh $*\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./npdu_test_client_npdu_start.sh $*\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./npdu_test_client_npdu_start.sh $*" & -elif [ ! -z "$JENKINS" ]; then - echo "starting npdu_test on slave Docker" - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./npdu_test_client_npdu_start.sh $*\" >> $WS_ROOT/slave_test_output 2>&1" & - else sleep 1 cat <> $WS_ROOT/slave_test_output 2>&1" & else cat <> $WS_ROOT/slave_test_output 2>&1" & + echo "Waiting for 5s" + sleep 5 + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./offer_test_external_slave_starter.sh" & else cat <> $WS_ROOT/slave_test_output 2>&1" & + echo "Waiting for 5s" + sleep 5 + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./offer_test_external_sd_msg_sender $DOCKER_IP" & else cat < #ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" +#include "../../implementation/configuration/include/internal_android.hpp" #else -#include "../../configuration/include/internal.hpp" +#include "../../implementation/configuration/include/internal.hpp" #endif // ANDROID #include "offer_test_globals.hpp" @@ -255,7 +255,7 @@ TEST(someip_offer_test, subscribe_or_call_method_at_service) offer_test_client its_sample(offer_test::service, passed_mode); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/offer_tests/offer_test_external_sd_msg_sender.cpp b/test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp similarity index 74% rename from test/offer_tests/offer_test_external_sd_msg_sender.cpp rename to test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp index cc75b8deb..db9446e57 100644 --- a/test/offer_tests/offer_test_external_sd_msg_sender.cpp +++ b/test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp @@ -14,27 +14,16 @@ static char* passed_address; TEST(someip_offer_test, send_offer_service_sd_message) { try { - boost::asio::io_service io; - boost::system::error_code ec; +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::io_service io; +#else + boost::asio::io_context io; +#endif boost::asio::ip::udp::socket::endpoint_type target_sd( boost::asio::ip::address::from_string(std::string(passed_address)), 30490); - - boost::asio::ip::udp::socket udp_socket(io); - - boost::asio::ip::udp::endpoint rx_endpoint_(boost::asio::ip::udp::v4(), 30490); - udp_socket.open(rx_endpoint_.protocol(), ec); - - if(ec) - std::cout <<" udp_socket open create error "< #ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" +#include "../../implementation/configuration/include/internal_android.hpp" #else -#include "../../configuration/include/internal.hpp" +#include "../../implementation/configuration/include/internal.hpp" #endif #include "offered_services_info_test_globals.hpp" @@ -300,7 +300,7 @@ TEST(someip_offered_services_info_test, check_offered_services) offered_services_info_test_client its_sample(offer_test::service, offer_test::remote_service, passed_mode); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/offered_services_info_test/offered_services_info_test_globals.hpp b/test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp similarity index 100% rename from test/offered_services_info_test/offered_services_info_test_globals.hpp rename to test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp diff --git a/test/offered_services_info_test/offered_services_info_test_local.json b/test/network_tests/offered_services_info_test/offered_services_info_test_local.json similarity index 100% rename from test/offered_services_info_test/offered_services_info_test_local.json rename to test/network_tests/offered_services_info_test/offered_services_info_test_local.json diff --git a/test/offered_services_info_test/offered_services_info_test_local_starter.sh b/test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh similarity index 100% rename from test/offered_services_info_test/offered_services_info_test_local_starter.sh rename to test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh diff --git a/test/offered_services_info_test/offered_services_info_test_service.cpp b/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp similarity index 98% rename from test/offered_services_info_test/offered_services_info_test_service.cpp rename to test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp index a77b074ec..3e0465c97 100644 --- a/test/offered_services_info_test/offered_services_info_test_service.cpp +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp @@ -20,9 +20,9 @@ #include #ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" +#include "../../implementation/configuration/include/internal_android.hpp" #else -#include "../../configuration/include/internal.hpp" +#include "../../implementation/configuration/include/internal.hpp" #endif // ANDROID #include "offered_services_info_test_globals.hpp" @@ -249,7 +249,7 @@ TEST(someip_offered_services_info_test, check_offered_services_as_rm_impl) offer_test_service its_sample(offer_test::service, offer_test::remote_service); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/payload_tests/conf/external_local_payload_test_client_external.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in similarity index 100% rename from test/payload_tests/conf/external_local_payload_test_client_external.json.in rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in diff --git a/test/payload_tests/conf/external_local_payload_test_client_local.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in similarity index 100% rename from test/payload_tests/conf/external_local_payload_test_client_local.json.in rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in diff --git a/test/payload_tests/conf/external_local_payload_test_service.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in similarity index 100% rename from test/payload_tests/conf/external_local_payload_test_service.json.in rename to test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in diff --git a/test/payload_tests/external_local_payload_test_client_external_start.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh similarity index 100% rename from test/payload_tests/external_local_payload_test_client_external_start.sh rename to test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh diff --git a/test/payload_tests/external_local_payload_test_client_external_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh similarity index 92% rename from test/payload_tests/external_local_payload_test_client_external_starter.sh rename to test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh index f6c2744c4..af044cfde 100755 --- a/test/payload_tests/external_local_payload_test_client_external_starter.sh +++ b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh @@ -16,9 +16,9 @@ FAIL=0 # Parameter 2: number of TCP/UDP sockets the process should have open check_tcp_udp_sockets_are_open () { - # Check that the passed pid/process does listen on at least one TCP/UDP socket + # Check that the passed pid/process does listen on at least one TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] @@ -30,10 +30,10 @@ check_tcp_udp_sockets_are_open () # Parameter 1: the pid to check check_tcp_udp_sockets_are_closed () { - # Check that the passed pid/process does not listen on any TCP/UDP socket + # Check that the passed pid/process does not listen on any TCP/UDP socket # or has any active connection via a TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] @@ -58,13 +58,10 @@ SERIVCE_PID=$! # to finish the test successfully if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_payload_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_payload_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat < /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] @@ -30,10 +30,10 @@ check_tcp_udp_sockets_are_open () # Parameter 1: the pid to check check_tcp_udp_sockets_are_closed () { - # Check that the passed pid/process does not listen on any TCP/UDP socket + # Check that the passed pid/process does not listen on any TCP/UDP socket # or has any active connection via a TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] @@ -75,13 +75,10 @@ wait $CLIENT_PID || ((FAIL+=1)) # to finish the test successfully if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_payload_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_payload_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <(io_)), + work_(std::make_shared(io_)), io_thread_(std::bind(&pending_subscription::io_run, this)) {} protected: @@ -46,8 +46,8 @@ class pending_subscription : public ::testing::Test { io_.run(); } - boost::asio::io_service io_; - std::shared_ptr work_; + boost::asio::io_context io_; + std::shared_ptr work_; std::thread io_thread_; }; @@ -1701,7 +1701,7 @@ TEST_F(pending_subscription, send_request_to_sd_port) udp_socket.close(ec); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); if(argc < 4) { diff --git a/test/pending_subscription_tests/pending_subscription_test_service.cpp b/test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp similarity index 99% rename from test/pending_subscription_tests/pending_subscription_test_service.cpp rename to test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp index d68686c15..53b2cde2c 100644 --- a/test/pending_subscription_tests/pending_subscription_test_service.cpp +++ b/test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp @@ -354,7 +354,7 @@ TEST(someip_pending_subscription_test, block_subscription_handler) } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/readme.txt b/test/network_tests/readme.txt similarity index 100% rename from test/readme.txt rename to test/network_tests/readme.txt diff --git a/test/restart_routing_tests/restart_routing_test_autoconfig.json b/test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json similarity index 100% rename from test/restart_routing_tests/restart_routing_test_autoconfig.json rename to test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json diff --git a/test/restart_routing_tests/restart_routing_test_client.cpp b/test/network_tests/restart_routing_tests/restart_routing_test_client.cpp similarity index 100% rename from test/restart_routing_tests/restart_routing_test_client.cpp rename to test/network_tests/restart_routing_tests/restart_routing_test_client.cpp diff --git a/test/restart_routing_tests/restart_routing_test_client.hpp b/test/network_tests/restart_routing_tests/restart_routing_test_client.hpp similarity index 100% rename from test/restart_routing_tests/restart_routing_test_client.hpp rename to test/network_tests/restart_routing_tests/restart_routing_test_client.hpp diff --git a/test/restart_routing_tests/restart_routing_test_client.json b/test/network_tests/restart_routing_tests/restart_routing_test_client.json similarity index 100% rename from test/restart_routing_tests/restart_routing_test_client.json rename to test/network_tests/restart_routing_tests/restart_routing_test_client.json diff --git a/test/restart_routing_tests/restart_routing_test_client_start.sh b/test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh similarity index 100% rename from test/restart_routing_tests/restart_routing_test_client_start.sh rename to test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh diff --git a/test/restart_routing_tests/restart_routing_test_service.cpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp similarity index 99% rename from test/restart_routing_tests/restart_routing_test_service.cpp rename to test/network_tests/restart_routing_tests/restart_routing_test_service.cpp index 35ab01a8d..67621cd1e 100644 --- a/test/restart_routing_tests/restart_routing_test_service.cpp +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp @@ -125,7 +125,7 @@ TEST(someip_restart_routing_test, send_response_for_every_request) { } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/restart_routing_tests/restart_routing_test_service.hpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp similarity index 100% rename from test/restart_routing_tests/restart_routing_test_service.hpp rename to test/network_tests/restart_routing_tests/restart_routing_test_service.hpp diff --git a/test/restart_routing_tests/restart_routing_test_service.json b/test/network_tests/restart_routing_tests/restart_routing_test_service.json similarity index 100% rename from test/restart_routing_tests/restart_routing_test_service.json rename to test/network_tests/restart_routing_tests/restart_routing_test_service.json diff --git a/test/restart_routing_tests/restart_routing_test_service_start.sh b/test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh similarity index 100% rename from test/restart_routing_tests/restart_routing_test_service_start.sh rename to test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh diff --git a/test/restart_routing_tests/restart_routing_test_starter.sh b/test/network_tests/restart_routing_tests/restart_routing_test_starter.sh similarity index 96% rename from test/restart_routing_tests/restart_routing_test_starter.sh rename to test/network_tests/restart_routing_tests/restart_routing_test_starter.sh index 9d74c36c4..cffd14c53 100755 --- a/test/restart_routing_tests/restart_routing_test_starter.sh +++ b/test/network_tests/restart_routing_tests/restart_routing_test_starter.sh @@ -21,7 +21,7 @@ echo "----------------------------------------------" export VSOMEIP_CONFIGURATION=restart_routing_test_autoconfig.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! sleep 2 @@ -61,7 +61,7 @@ echo " restart routingmanagerd " echo "----------------------------------------------" sleep 2 -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! wait $SERIVCE_PID || ((FAIL+=1)) @@ -156,7 +156,7 @@ echo "----------------------------------------------" sleep 2 export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! # Start the service @@ -200,7 +200,7 @@ echo "----------------------------------------------" sleep 2 export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! wait $SERIVCE_PID || ((FAIL+=1)) @@ -230,7 +230,7 @@ echo "----------------------------------------------" sleep 2 export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! # Start the service @@ -279,7 +279,7 @@ echo "----------------------------------------------" sleep 2 export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & DAEMON_PID=$! echo "----------------------------------------------" diff --git a/test/routing_tests/conf/external_local_routing_test_client_external.json.in b/test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in similarity index 87% rename from test/routing_tests/conf/external_local_routing_test_client_external.json.in rename to test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in index 958f196d8..0aaa664aa 100644 --- a/test/routing_tests/conf/external_local_routing_test_client_external.json.in +++ b/test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in @@ -33,7 +33,10 @@ } ], - "routing" : "external_local_routing_test_client_external", + "routing": { + "enabled": false, + "host": "external_local_routing_test_client_external" + }, "service-discovery" : { "enable" : "false", diff --git a/test/routing_tests/conf/external_local_routing_test_service.json.in b/test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in similarity index 100% rename from test/routing_tests/conf/external_local_routing_test_service.json.in rename to test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in diff --git a/test/routing_tests/conf/local_routing_test_starter.sh.bat.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in similarity index 100% rename from test/routing_tests/conf/local_routing_test_starter.sh.bat.in rename to test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in diff --git a/test/routing_tests/conf/local_routing_test_starter.sh.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in similarity index 96% rename from test/routing_tests/conf/local_routing_test_starter.sh.in rename to test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in index 9e104805e..d5b83f4b0 100755 --- a/test/routing_tests/conf/local_routing_test_starter.sh.in +++ b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in @@ -15,10 +15,10 @@ FAIL=0 # Parameter 1: the pid to check check_tcp_udp_sockets_are_closed () { - # Check that the service does not listen on any TCP/UDP socket + # Check that the service does not listen on any TCP/UDP socket # or has any active connection via a TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] @@ -35,7 +35,7 @@ check_tcp_udp_sockets_are_closed () export VSOMEIP_CONFIGURATION=local_routing_test_service.json # start daemon -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & PID_VSOMEIPD=$! WAIT_PIDS=() @@ -70,7 +70,7 @@ kill $PID_VSOMEIPD sleep 1 # Check if client and server both exited successfully and the service didnt't -# have any open +# have any open if [ $FAIL -eq 0 ] then exit 0 diff --git a/test/routing_tests/external_local_routing_test_client_external_start.sh b/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh similarity index 73% rename from test/routing_tests/external_local_routing_test_client_external_start.sh rename to test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh index b267b47f9..098c777f7 100755 --- a/test/routing_tests/external_local_routing_test_client_external_start.sh +++ b/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -ex # Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -6,4 +6,12 @@ export VSOMEIP_APPLICATION_NAME=external_local_routing_test_client_external export VSOMEIP_CONFIGURATION=external_local_routing_test_client_external.json -./local_routing_test_client +./local_routing_test_client & +client=$! + +for _ in {1..100} +do + find /tmp -ls + lsof -nw -p "$client" || continue +done +wait "$client" diff --git a/test/routing_tests/external_local_routing_test_service.cpp b/test/network_tests/routing_tests/external_local_routing_test_service.cpp similarity index 99% rename from test/routing_tests/external_local_routing_test_service.cpp rename to test/network_tests/routing_tests/external_local_routing_test_service.cpp index c35716598..46b8138ff 100644 --- a/test/routing_tests/external_local_routing_test_service.cpp +++ b/test/network_tests/routing_tests/external_local_routing_test_service.cpp @@ -176,7 +176,7 @@ TEST(someip_external_local_routing_test, receive_ten_messages_over_local_and_ext } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/routing_tests/external_local_routing_test_service.hpp b/test/network_tests/routing_tests/external_local_routing_test_service.hpp similarity index 100% rename from test/routing_tests/external_local_routing_test_service.hpp rename to test/network_tests/routing_tests/external_local_routing_test_service.hpp diff --git a/test/routing_tests/external_local_routing_test_service_start.sh b/test/network_tests/routing_tests/external_local_routing_test_service_start.sh similarity index 100% rename from test/routing_tests/external_local_routing_test_service_start.sh rename to test/network_tests/routing_tests/external_local_routing_test_service_start.sh diff --git a/test/routing_tests/external_local_routing_test_starter.sh b/test/network_tests/routing_tests/external_local_routing_test_starter.sh similarity index 91% rename from test/routing_tests/external_local_routing_test_starter.sh rename to test/network_tests/routing_tests/external_local_routing_test_starter.sh index 7b3d37b58..c67114fc4 100755 --- a/test/routing_tests/external_local_routing_test_starter.sh +++ b/test/network_tests/routing_tests/external_local_routing_test_starter.sh @@ -15,9 +15,9 @@ FAIL=0 # Parameter 1: the pid to check check_tcp_udp_sockets_are_open () { - # Check that the service does listen on at least one TCP/UDP socket + # Check that the service does listen on at least one TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -lt 1 ] @@ -29,10 +29,10 @@ check_tcp_udp_sockets_are_open () # Parameter 1: the pid to check check_tcp_udp_sockets_are_closed () { - # Check that the service does not listen on any TCP/UDP socket + # Check that the service does not listen on any TCP/UDP socket # or has any active connection via a TCP/UDP socket # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and + # program filters the netstat output down to the protocol (1st field) and # the PID/Program name (last field) fields. SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] @@ -78,13 +78,10 @@ if [ $CLIENT_STILL_THERE -ne 0 ] then if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external_local_routing_test_starter.sh on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_routing_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_routing_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_routing_test_client_external_start.sh" & - elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_routing_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & else cat < #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -57,7 +57,7 @@ std::vector its_modes({ class someip_tp : public ::testing::TestWithParam { public: someip_tp() : - work_(std::make_shared(io_)), + work_(std::make_shared(io_)), io_thread_(std::bind(&someip_tp::io_run, this)), session_(0x0), sd_session_(0x0), @@ -346,8 +346,8 @@ class someip_tp : public ::testing::TestWithParam { MIXED_RANDOM, }; - boost::asio::io_service io_; - std::shared_ptr work_; + boost::asio::io_context io_; + std::shared_ptr work_; std::thread io_thread_; std::vector fragments_request_to_master_; std::vector fragments_response_of_master_; @@ -1357,7 +1357,7 @@ TEST_P(someip_tp, send_in_mode) udp_server_socket.close(ec); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); if(argc < 3) { diff --git a/test/someip_tp_tests/someip_tp_test_service.cpp b/test/network_tests/someip_tp_tests/someip_tp_test_service.cpp similarity index 99% rename from test/someip_tp_tests/someip_tp_test_service.cpp rename to test/network_tests/someip_tp_tests/someip_tp_test_service.cpp index abc1af38f..26fdf6de0 100644 --- a/test/someip_tp_tests/someip_tp_test_service.cpp +++ b/test/network_tests/someip_tp_tests/someip_tp_test_service.cpp @@ -382,7 +382,7 @@ TEST(someip_someip_tp_test, echo_requests) } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in similarity index 100% rename from test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp similarity index 100% rename from test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp rename to test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh similarity index 88% rename from test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh rename to test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh index a53104f3a..8569a10b9 100755 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh +++ b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh @@ -42,13 +42,10 @@ sleep 3 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting subscribe_notify_one_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <> $WS_ROOT/slave_test_output 2>&1" & - else cat <register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); + app_->register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::ANY_EVENT, handler); std::set its_eventgroups; its_eventgroups.insert(i.eventgroup_id); - app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD, reliability_type_); + app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, + vsomeip::event_type_e::ET_FIELD, reliability_type_); other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; @@ -475,7 +477,7 @@ TEST(someip_subscribe_notify_test, send_ten_notifications_to_service) } } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh similarity index 100% rename from test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh rename to test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh diff --git a/test/suspend_resume_tests/conf/suspend_resume_test_client.json.in b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in similarity index 100% rename from test/suspend_resume_tests/conf/suspend_resume_test_client.json.in rename to test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in diff --git a/test/suspend_resume_tests/conf/suspend_resume_test_service.json.in b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in similarity index 100% rename from test/suspend_resume_tests/conf/suspend_resume_test_service.json.in rename to test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in diff --git a/test/suspend_resume_tests/suspend_resume_test.hpp b/test/network_tests/suspend_resume_tests/suspend_resume_test.hpp similarity index 100% rename from test/suspend_resume_tests/suspend_resume_test.hpp rename to test/network_tests/suspend_resume_tests/suspend_resume_test.hpp diff --git a/test/suspend_resume_tests/suspend_resume_test_client.cpp b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp similarity index 99% rename from test/suspend_resume_tests/suspend_resume_test_client.cpp rename to test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp index ca2956c74..11ae5787b 100644 --- a/test/suspend_resume_tests/suspend_resume_test_client.cpp +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp @@ -229,11 +229,11 @@ TEST(suspend_resume_test, fast) its_client.run_test(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } -#endif // _WIN32 +#endif diff --git a/test/suspend_resume_tests/suspend_resume_test_master_starter.sh b/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh similarity index 84% rename from test/suspend_resume_tests/suspend_resume_test_master_starter.sh rename to test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh index 39a8d7357..44b1b7485 100755 --- a/test/suspend_resume_tests/suspend_resume_test_master_starter.sh +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh @@ -17,7 +17,7 @@ export VSOMEIP_APPLICATION_NAME=suspend_resume_test_service export VSOMEIP_CONFIGURATION=suspend_resume_test_service.json # start daemon -../examples/routingmanagerd/./routingmanagerd & +../../examples/routingmanagerd/./routingmanagerd & PID_VSOMEIPD=$! # start the service @@ -28,19 +28,16 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting suspend_resume_test_slave_starter.sh on slave LXC with parameters $SLAVE_JSON_FILE" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./suspend_resume_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./suspend_resume_test_slave_starter.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./suspend_resume_test_slave_starter.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./suspend_resume_test_slave_starter.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - else cat < should be rejected as there is already a service instance -# running in the network - -export VSOMEIP_CONFIGURATION=offer_test_external_slave.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -echo "calling availabiliy checker" - -./offer_test_service_availability_checker & - -PID_AVAILABILITY_CHECKER=$! - -echo "waiting for offer_test_service_availability_checker" - -# wait until the services on the remote node were started as well -wait $PID_AVAILABILITY_CHECKER - -# kill the routing manager services -kill $PID_VSOMEIPD - -./offer_test_external_sd_msg_sender $1 & - - - diff --git a/test/offer_tests/offer_test_service_availability_checker.cpp b/test/offer_tests/offer_test_service_availability_checker.cpp deleted file mode 100644 index 3cef64f9f..000000000 --- a/test/offer_tests/offer_test_service_availability_checker.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - - -class offer_test_service_availability_checker { -public: - offer_test_service_availability_checker(struct offer_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_for_stop_(true), - stop_thread_(std::bind(&offer_test_service_availability_checker::wait_for_stop, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_service_availability_checker::on_state, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&offer_test_service_availability_checker::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - - app_->start(); - } - - ~offer_test_service_availability_checker() { - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "MY Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "MY Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - - void wait_for_stop() { - VSOMEIP_INFO << " MY offer_test_service_availability_check wait_for_stop() "; - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - //VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - // << client_number_ << "] all services are available. Going down"; - VSOMEIP_INFO << " MY offer_test_service_availability_check is going down "; - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; -}; - -TEST(someip_offer_test_external, wait_for_availability_and_exit) -{ - offer_test_service_availability_checker its_sample( - offer_test::service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt new file mode 100644 index 000000000..ed63f6fff --- /dev/null +++ b/test/unit_tests/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +project ("unit_tests_bin" LANGUAGES CXX) + +file (GLOB SRCS main.cpp **/*.cpp ../common/utility.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Threads REQUIRED) +find_package(Boost 1.55 COMPONENTS filesystem system REQUIRED) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable (${PROJECT_NAME} ${SRCS} ) +target_link_libraries ( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest +) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/main.cpp b/test/unit_tests/main.cpp new file mode 100644 index 000000000..3f704af2b --- /dev/null +++ b/test/unit_tests/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + // Test execution + int ret = RUN_ALL_TESTS(); + + // Exit + return ret; +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_check_credentials.cpp b/test/unit_tests/security_tests/ut_check_credentials.cpp new file mode 100644 index 000000000..7696892b7 --- /dev/null +++ b/test/unit_tests/security_tests/ut_check_credentials.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4004201; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4004200; +} + +TEST(check_credentials_test, check_no_policies_loaded) { + + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //no policies loaded -> check credentials will return false independent of the uid or gid + ASSERT_TRUE(its_manager->is_audit()); + ASSERT_FALSE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid)); +} + +TEST(check_credentials_test, check_policies_loaded) { + + std::unique_ptr its_manager( + new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + + utility::read_data(utility::get_all_files_in_dir( + utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) + its_manager->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + //the check_credentials_ and the policy_enabled_ variables should be set to true + ASSERT_FALSE(its_manager->is_audit()); + ASSERT_TRUE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + //invalid uid and gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //invalid uid and valid gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //valid uid and invalid gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //valid uid and gid -> the check must return true + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid)); +} + +// check_credentials with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. +TEST(check_credentials_test, check_policies_loaded_in_audit_mode) { + + std::unique_ptr its_manager( + new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir( + utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //the check_credentials_ variable is force to be false + utility::force_check_credentials(policy_elements, "false"); + + for (const auto& e : policy_elements) + its_manager->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + //expect check_credentials_ false and the policy_enabled_ true + ASSERT_TRUE(its_manager->is_audit()); + ASSERT_TRUE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid_valid = utility::create_uds_client(invalid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_valid_invalid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + // is expected check_credentials method always return true + //invalid uid and gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //invalid uid and valid gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid_valid)); + + //valid uid and invalid gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid_invalid)); + + //valid uid and gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid)); +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_check_routing_credentials.cpp b/test/unit_tests/security_tests/ut_check_routing_credentials.cpp new file mode 100644 index 000000000..ef9040d59 --- /dev/null +++ b/test/unit_tests/security_tests/ut_check_routing_credentials.cpp @@ -0,0 +1,85 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4003017; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 5002; +} + +TEST(check_routing_credentials, check_policies_loaded) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) + security->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, valid_gid); + + //valid uid and gid -> the check must return true + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid)); + + //invalid gid and valid gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_valid_uid_invalid_gid)); + + //invalid uid and valid gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_invalid_uid_valid_gid)); + + //invalid uid and gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_invalid)); +} + +// check_routing_credentials with policies loaded in lazy mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_routing_credentials' switch has to be set to false. +TEST(check_routing_credentials, check_policies_loaded_lazy_load) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // load policies in lazy mode so that check_routing_credentials is false + for (const auto& e : policy_elements) + security->load(e, true); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, valid_gid); + + //expect check_routing_credentials_ false so method always returns true + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid_uid_invalid_gid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_invalid_uid_valid_gid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_invalid)); +} diff --git a/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp b/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp new file mode 100644 index 000000000..efcb826d6 --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp @@ -0,0 +1,62 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::client_t client = 10; +vsomeip_v3::client_t alternate_client = 11; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +vsomeip_v3::uid_t uid_3 = 2; +vsomeip_v3::gid_t gid_3 = 2; +} + +TEST(get_client_to_sec_client_mapping, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_2 = utility::create_uds_client(uid_2, gid_2); + vsomeip_sec_client_t its_sec_client_uid_gid_3 = utility::create_uds_client(uid_3, gid_3); + + // Client and uid_gid should not be stored yet. + EXPECT_FALSE(security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_1)); + + // Add client and uid_gid mappings. + security->store_client_to_sec_client_mapping(client, &its_sec_client_uid_gid_1); + + // uid_gid and uid_gid_2 should not be equal. + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_2.client.uds_client.group); + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_2.client.uds_client.user); + + // Client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_2)); + + // uid_gid and uid_gid_2 should be equal if get was successful. + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_2.client.uds_client.group); + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_2.client.uds_client.user); + + // Alternate_client is not stored, this should return false. + EXPECT_FALSE(security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_1)); + + // Add alternate client and uid_gid mappings. + security->store_client_to_sec_client_mapping(alternate_client, &its_sec_client_uid_gid_1); + + // uid_gid and uid_gid_3 should not be equal. + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_3.client.uds_client.group); + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_3.client.uds_client.user); + + // Alternate client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_3)); + + // uid_gid and uid_gid_3 should be equal if get was successful. + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_3.client.uds_client.group); + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_3.client.uds_client.user); + } diff --git a/test/unit_tests/security_tests/ut_get_clients.cpp b/test/unit_tests/security_tests/ut_get_clients.cpp new file mode 100644 index 000000000..093200c90 --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_clients.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::unordered_set clients; +std::unordered_set local_clients; +vsomeip_v3::client_t client_1 = 10; +vsomeip_v3::client_t client_2 = 11; +vsomeip_v3::client_t client_3 = 12; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +TEST(get_clients, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid, gid); + + // Local_clients has now one client(10). + local_clients.insert(client_1); + + // Clients should be empty. + EXPECT_TRUE(clients.empty()); + + // Should do nothing because there is not a client to uid_gid mapping yet. + security->get_clients(uid, gid, clients); + + // clients should still be empty. + EXPECT_TRUE(clients.empty()); + + // Stores client to uid_gid_mapping. + security->store_client_to_sec_client_mapping(client_1, &its_sec_client_uid_gid); + security->get_clients(uid, gid, clients); + + // Clients and local_clients should be equal and have the same client(10). + EXPECT_EQ(clients, local_clients); + + // Repeat with two more clients. + security->store_client_to_sec_client_mapping(client_2, &its_sec_client_uid_gid); + security->store_client_to_sec_client_mapping(client_3, &its_sec_client_uid_gid); + + local_clients.insert(client_2); + local_clients.insert(client_3); + + security->get_clients(uid, gid, clients); + + // Clients and local_clients should be equal and have the same 3 clients(10,11,12). + EXPECT_EQ(clients, local_clients); +} diff --git a/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp b/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp new file mode 100644 index 000000000..96ae41605 --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +} + +TEST(get_sec_client_to_clients_mapping, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set clients_1; + clients_1.insert(client); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + // Client and uid_gid should not be stored yet. + EXPECT_FALSE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_1)); + + // Add client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid, client); + + std::set clients_2; + + // Clients and clients_2 should not be equal. + EXPECT_NE(clients_1, clients_2); + + // Client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_2)); + + // Clients and clients_2 should be equal if get was successful. + EXPECT_EQ(clients_1, clients_2); + + // Alternate_uid_gid is not stored, this should return false. + EXPECT_FALSE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_1)); + + // Add alternate client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid_alternate, client); + + std::set clients_3; + + // Clients and clients_3 should not be equal. + EXPECT_NE(clients_1, clients_3); + + // Alternate client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_3)); + + // Clients and clients_3 should be equal if get was successful. + EXPECT_EQ(clients_1, clients_3); +} diff --git a/test/unit_tests/security_tests/ut_is_client_allowed.cpp b/test/unit_tests/security_tests/ut_is_client_allowed.cpp new file mode 100644 index 000000000..ab6515343 --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_client_allowed.cpp @@ -0,0 +1,149 @@ +#include +#include "gtest/gtest.h" +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::uid_t uid_1 = 4003031; + vsomeip_v3::gid_t gid_1 = 4003031; + vsomeip_v3::service_t service_1 = 0xf913; + + vsomeip_v3::service_t service_2 = 0x41; // service not defined in policies + + vsomeip_v3::instance_t instance = 0x03; + vsomeip_v3::instance_t instance_2 = 0x04; + vsomeip_v3::method_t method = 0x04; + vsomeip_v3::method_t method_2 = 0x05; + + vsomeip_v3::gid_t invalid_uid = 1; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::uid_t ANY_UID = 0xFFFFFFFF; + vsomeip_v3::gid_t ANY_GID = 0xFFFFFFFF; + + vsomeip_v3::gid_t deny_uid = 9999; + vsomeip_v3::gid_t deny_gid = 9999; + vsomeip_v3::service_t deny_service = 0x40; +} + +TEST(is_client_allowed_test, check_no_policies_loaded) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //no policies loaded -> is_client_allowed must return true + ASSERT_FALSE(its_manager->is_enabled()); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method)); +} + +TEST(is_client_allowed_test, check_policies_loaded) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(its_manager->is_enabled()); + ASSERT_FALSE(its_manager->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_uid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + //valid credential for valid service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service / instance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service but with a different instance or method + // is_client_allowed return true because it's define ANY_INSTANCE and ANY_METHOD in the policy + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance_2, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method_2)); + + //invalid credential for the service / istance / method + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_invalid_uid, service_1, instance, method)); + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_invalid_gid, service_1, instance, method)); + + //ANY_UID and ANY_GID + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_any, service_1, instance, method)); + + // test deny client + // deny client with credentials for the service + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method)); + // credencials exists in deny policy, but not for that service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, service_2, instance, method)); +} + + +// is_client_allowed with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. + TEST(is_client_allowed_test, check_policies_loaded_in_audit_mode) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + utility::force_check_credentials(policy_elements, "false"); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are false + ASSERT_TRUE(its_manager->is_enabled()); + ASSERT_TRUE(its_manager->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_uid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + // is expected is_client_allowed method always returns true + // valid credential for valid service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service / instance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service but with a different instance or method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance_2, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method_2)); + + // invalid credential for the service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid_uid, service_1, instance, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid_gid, service_1, instance, method)); + + // ANY_UID and ANY_GID + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_any, service_1, instance, method)); + + // test deny client + // deny client with credentials for the service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method)); + // credencials exists in deny policy, but not for that service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, service_2, instance, method)); +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_is_offer_allowed.cpp b/test/unit_tests/security_tests/ut_is_offer_allowed.cpp new file mode 100644 index 000000000..f60d4ed3c --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_offer_allowed.cpp @@ -0,0 +1,153 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" +namespace{ + +vsomeip_v3::uid_t uid_1 = 4003016; +vsomeip_v3::gid_t gid_1 = 4003016; +vsomeip_v3::service_t service_1 = 0xf8c2; + +vsomeip_v3::service_t deny_service = 0x40; + +vsomeip_v3::instance_t instance = 0x03; +vsomeip_v3::instance_t any_instance = 0xfffe; + +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::uid_t ANY_UID = 0xFFFFFFFF; +vsomeip_v3::gid_t ANY_GID = 0xFFFFFFFF; + +vsomeip_v3::gid_t deny_uid = 9000; +vsomeip_v3::gid_t deny_gid = 9000; +} + +TEST(is_offer_allowed, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + ASSERT_FALSE(security->is_enabled()); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + // no policies loaded -> is_offer_allowed must return true + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); +} + +TEST(is_offer_allowed, check_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + for (const auto &e : policy_elements) + { + security->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(security->is_enabled()); + ASSERT_FALSE(security->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + + // valid credential for valid service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, instance)); + + // request with the same credentials and service but with a different instance + // is_offer_allowed return true because it's define ANY_INSTANCE in the policy + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, any_instance)); + + // invalid credential for the service / instance + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_invalid_uid_valid_gid, service_1, instance)); + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_valid_uid_invalid_gid, service_1, instance)); + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); + + // test deny offer + // deny client with credentials for the service + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_deny, deny_service, instance)); + // credentials exists in deny policy, but not for that service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, service_1, instance)); + + // ANY_UID and ANY_GID + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_any, service_1, instance)); +} + +// is_offer_allowed with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. + +TEST(is_offer_allowed, check_policies_loaded_in_audit_mode) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + utility::force_check_credentials(policy_elements, "false"); + + for (const auto &e : policy_elements) + { + security->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(security->is_enabled()); + ASSERT_TRUE(security->is_audit()); + + // valid credential for valid service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, instance)); + + // request with the same credentials and service but with a different instance + // is_offer_allowed return true because it's define ANY_INSTANCE in the policy + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, any_instance)); + + // invalid credential for the service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid_uid_valid_gid, service_1, instance)); + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid_uid_invalid_gid, service_1, instance)); + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); + + // test deny offer + // deny client with credentials for the service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, deny_service, instance)); + // credentials exists in deny policy, but not for that service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, service_1, instance)); + + // ANY_UID and ANY_GID + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_any, service_1, instance)); +} diff --git a/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp b/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp new file mode 100644 index 000000000..20c6ba5e4 --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp @@ -0,0 +1,221 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; + +vsomeip_v3::uid_t valid_uid { 0 }; +vsomeip_v3::uid_t invalid_uid { 1234567 }; + +vsomeip_v3::gid_t valid_gid { 0 }; + +vsomeip_v3::service_t valid_service { 0xf913 }; +vsomeip_v3::service_t invalid_service { 0x41 }; +} + +TEST(is_policy_update_allowed, check_whitelist_disabled) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + // NO REQUESTS IN POLICY ---------------------------------------------------------------------// + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id when check_whitelist is " + "disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id when check_whitelist is " + "disabled!"; + + // ONLY VALID REQUESTS IN POLICY -------------------------------------------------------------// + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id and valid request when " + "check_whitelist is disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and valid request when " + "check_whitelist is disabled!"; + + // INVALID REQUESTS IN POLICY ----------------------------------------------------------------// + + // Add a invalid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id and invalid request when " + "check_whitelist is disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and invalid request when " + "check_whitelist is disabled!"; +} + +TEST(is_policy_update_allowed, check_whitelist_enabled) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the policy into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + // NO REQUESTS IN POLICY ---------------------------------------------------------------------// + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id!"; + + // ONLY VALID REQUESTS IN POLICY -------------------------------------------------------------// + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id and valid request!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and valid request!"; + + // INVALID REQUESTS IN POLICY ----------------------------------------------------------------// + + // Add invalid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id and invalid request!"; + + EXPECT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to deny policy update with valid user id and invalid request!"; +} + +TEST(is_policy_update_allowed, null_policy) +{ + // Test objects. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + std::shared_ptr policy = nullptr; + + // NO POLICIES LOADED ------------------------------------------------------------------------// + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when no policies are loaded!"; + + EXPECT_TRUE(security->is_policy_update_allowed(0, policy)) + << "Denied update of policy when security whitelist is not loaded!"; + + // LOADED POLICY W/O SECURITY WHITELIST ------------------------------------------------------// + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the policy into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + security->load(policy_elements.at(0), false); + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when a policy without a security whitelist was loaded!"; + + EXPECT_TRUE(security->is_policy_update_allowed(0, policy)) + << "Denied update of policy when security whitelist is not loaded!"; + + // LOADED POLICY W/ SECURITY WHITELIST -------------------------------------------------------// + + // Add a security whitelist to the policy. + + utility::add_security_whitelist(policy_elements.at(0), true); + + security->load(policy_elements.at(0), false); + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when a policy with a security whitelist was loaded!"; + + EXPECT_FALSE(security->is_policy_update_allowed(0, policy)) + << "Allowed update of invalid policy!"; +} diff --git a/test/unit_tests/security_tests/ut_load_policies.cpp b/test/unit_tests/security_tests/ut_load_policies.cpp new file mode 100644 index 000000000..83d7b3a80 --- /dev/null +++ b/test/unit_tests/security_tests/ut_load_policies.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +vsomeip_v3::uid_t valid_uid = 4002200; +vsomeip_v3::gid_t valid_gid = 4003014; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_policies, and check its changes using other methods. +// The remove_security_policy method checks if there is any loaded policy. +// The is_audit method checks the check_credentials value. +// No test was created for allow_remote_clients because it was inacessible. + +TEST(load_policies, any_policies_present) +{ + // LOADED POLICIES --------------------------------------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + // Using load function to indirectly call load_policies. + security->load(policy_elements.at(0)); + + // Check that the policies were loaded from the file by trying to remove one of the loaded + // policies. + // If the policy is present, remove_security_policy returns true. + ASSERT_TRUE(security->remove_security_policy(valid_uid,valid_gid)) + << "Trying to remove a policy that is supposed to exist, but doesn't"; + + // POLICIES NOT LOADED -----------------------------------------------------------------------// + // Remove all the policies from the file. + policy_elements.at(0).tree_.get_child("security").erase("policies"); + + // Using load function to indirectly call load_policies. + security->load(policy_elements.at(0)); + + // Check that no policies were loaded. + ASSERT_FALSE(security->remove_security_policy(valid_uid,valid_gid)) + << "Trying to remove a policy should not exist, but it exists"; +} + +TEST(load_policies, check_credentials) +{ + // CHECK CREDENTIALS NOT SET -----------------------------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + security->load(policy_elements.at(0)); + + // Check that the check_credentials value was not set, using the is_audit method. + ASSERT_TRUE(security->is_audit()) + << "Check credentials value should be false when no value is loaded"; + + // CHECK CREDENTIALS SET TRUE ----------------------------------------------------------------// + + // Load the check credentials value as false. + bool check_credentials_value {true}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + security->load(policy_elements.at(0)); + + // Check that the check_credentials flag was not set internally, using the is_audit method. + ASSERT_FALSE(security->is_audit()) + << "Check credentials flag should be true when the check_credential value is loaded as" + "true"; + + // CHECK CREDENTIALS SET FALSE ---------------------------------------------------------------// + + // Load the check credentials value as false. + check_credentials_value = false; + policy_elements.at(0).tree_.put("security.check_credentials", check_credentials_value); + security->load(policy_elements.at(0)); + + // Check that the check_credentials flag was set false, using the is_audit method. + ASSERT_TRUE(security->is_audit()) + << "Check credentials flag should be false when the check_credential value is loaded as" + "false"; +} diff --git a/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp b/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp new file mode 100644 index 000000000..5fcd5dae7 --- /dev/null +++ b/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp @@ -0,0 +1,218 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +vsomeip_v3::service_t valid_service_id = 0xf91f; +vsomeip_v3::service_t invalid_service_id = 0xf923; +vsomeip_v3::uid_t valid_uid = 4017205; +vsomeip_v3::uid_t invalid_uid = 111111; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_security_update_whitelist, and check its changes using other methods. +// The is_policy_removal_allowed method checks if a selected uid is present in the whitelist. +// The is_policy_update_allowed method checks if a selected service_id is present in the whitelist. + +TEST(load_security_update_whitelist, check_uids) +{ + // LOADED POLICY W/O UIDS ON SECURITY WHITELIST ---------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with an empty list of user uids. + std::vector user_ids; + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + // Check that the valid and invalid uids are not present in the whitelist by calling a method + // that verifies that condition. + ASSERT_FALSE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist unexpectedly holds a valid uid"; + + ASSERT_FALSE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist unexpectedly holds an invalid uid"; + + // LOADED POLICY WITH UIDS ON SECURITY WHITELIST ---------------------------------------------// + utility::get_policy_uids(policy_elements.at(0), user_ids); + + // Add a security whitelist with list of user uids loaded. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + // Check that the valid and invalid uids are not present in the whitelist by calling a method + // that verifies that condition. + ASSERT_TRUE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist expected to hold a valid uid"; + + ASSERT_FALSE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist unexpectedly holds an invalid uid"; +} + +TEST(load_security_update_whitelist, check_service_ids) +{ + // LOADED POLICY W/O SERVICE IDS ON SECURITY WHITELIST -------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + // Add a security whitelist with an empty list of service ids. + std::vector services; + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + std::shared_ptr policy(std::make_shared()); + + vsomeip::service_t its_service(valid_service_id); + vsomeip::service_t its_invalid_service(invalid_service_id); + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist unexpectedly holds a valid service_id"; + + // Add an invalid request to the policy + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist unexpectedly holds an invalid service_id"; + + // LOADED POLICY WITH SERVICE IDS ON SECURITY WHITELIST --------------------------------------// + utility::get_policy_services(policy_elements.at(0), services); + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + security->load(policy_elements.at(0)); + + // Reset the policies pointer to add a correct serviceid and an incorrect one. + policy->requests_.clear(); + + // Add a valid request to the policy. + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist expected to hold a valid service_id"; + + // Add an invalid request to the policy. + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "The whitelist unexpectedly holds an invalid service_id"; +} + +TEST(load_security_update_whitelist, check_whitelist_disabled) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with check_whitelist disabled. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, false); + + security->load(policy_elements.at(0)); + + std::shared_ptr policy(std::make_shared()); + + vsomeip::service_t its_service(valid_service_id); + vsomeip::service_t its_invalid_service(invalid_service_id); + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + ASSERT_TRUE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist is disabled, a valid uid should be allowed to be removed"; + + ASSERT_TRUE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist is disabled, an invalid uid should be allowed to be removed"; + + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist is disabled, a valid service_id should be allowed to be updated"; + + // Add an invalid request to the policy. + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist is disabled, a valid service_id should be allowed to be updated"; +} diff --git a/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp b/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp new file mode 100644 index 000000000..3aff27a85 --- /dev/null +++ b/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace +{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +TEST(remove_client_to_sec_client_mapping, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + // client and uid_gid should not be stored yet + EXPECT_FALSE(security->get_client_to_sec_client_mapping (client, its_sec_client)); + + // client and uid_gid should not be stored yet + EXPECT_FALSE(security->remove_client_to_sec_client_mapping(client)); + + // add client and uid_gid mappings + security->store_client_to_sec_client_mapping(client, &its_sec_client); + security->store_sec_client_to_client_mapping(&its_sec_client, client); + + // client and uid_gid mapping should be returned + EXPECT_TRUE(security->get_client_to_sec_client_mapping(client, its_sec_client)); + + // client and uid_gid mapping should be in the vector and able to be removed + EXPECT_TRUE(security->remove_client_to_sec_client_mapping(client)); + + // client and uid_gid should be removed from the vector + EXPECT_FALSE(security->get_client_to_sec_client_mapping(client, its_sec_client)); +} diff --git a/test/unit_tests/security_tests/ut_remove_security_policy.cpp b/test/unit_tests/security_tests/ut_remove_security_policy.cpp new file mode 100644 index 000000000..b3d677018 --- /dev/null +++ b/test/unit_tests/security_tests/ut_remove_security_policy.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4002200; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 4003014; +} + +TEST(remove_security_policy_test, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // no policies loaded -> remove_security_policy will return true independent of the uid or gid + EXPECT_FALSE(security->remove_security_policy(valid_uid, valid_gid)); + EXPECT_FALSE(security->remove_security_policy(invalid_uid, valid_gid)); + EXPECT_FALSE(security->remove_security_policy(valid_uid, invalid_gid)); + EXPECT_FALSE(security->remove_security_policy(invalid_uid, invalid_gid)); +} + +TEST(remove_security_policy_test, check_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + + for (const auto &e : policy_elements) + security->load(e, false); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // the check_credentials_ and the policy_enabled_ variables should be set to true + ASSERT_FALSE(security->is_audit()); + ASSERT_TRUE(security->is_enabled()); + + // invalid uid and gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(invalid_uid, invalid_gid)); + + // invalid uid and valid gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(invalid_uid, valid_gid)); + + // valid uid and invalid gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(valid_uid, invalid_gid)); + + // valid uid and gid -> remove_security_policy must return true + EXPECT_TRUE(security->remove_security_policy(valid_uid, valid_gid)); +} diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 17003a5be..8756f3f24 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - # vsomeip_ctrl add_executable(vsomeip_ctrl EXCLUDE_FROM_ALL vsomeip_ctrl.cpp) target_link_libraries(vsomeip_ctrl diff --git a/vsomeip.pc.in b/vsomeip.pc.in index 9049c80ca..f717a120d 100644 --- a/vsomeip.pc.in +++ b/vsomeip.pc.in @@ -8,4 +8,3 @@ Description: New SOME/IP stack, feature complete Version: @VSOMEIP_VERSION@ Libs: -L${libdir} -lvsomeip Cflags: -I${includedir} - diff --git a/vsomeip3.pc.in b/vsomeip3.pc.in index 27888e75d..fa54522b5 100644 --- a/vsomeip3.pc.in +++ b/vsomeip3.pc.in @@ -8,4 +8,3 @@ Description: New SOME/IP stack, feature complete Version: @VSOMEIP_VERSION@ Libs: -L${libdir} -lvsomeip3 Cflags: -I${includedir} -