summaryrefslogtreecommitdiff
path: root/implementation
diff options
context:
space:
mode:
authorDiogo Pedrosa <diogo12pedrosa@gmail.com>2023-03-09 17:57:35 +0000
committerDiogo Pedrosa <diogo12pedrosa@gmail.com>2023-03-10 14:41:51 +0000
commit826ebb8d352245a36ecaec32b6af61e7abf4696e (patch)
treed4e984dd100f3257ce784c9e30aefb6e60a93ab5 /implementation
parentfc73f40fa1501dc53210c63cb7c0d7623d106370 (diff)
downloadvSomeIP-826ebb8d352245a36ecaec32b6af61e7abf4696e.tar.gz
vsomeip 3.3.0
Diffstat (limited to 'implementation')
-rw-r--r--implementation/compat/runtime/src/application_impl.cpp2
-rw-r--r--implementation/configuration/include/application_configuration.hpp42
-rw-r--r--implementation/configuration/include/client.hpp2
-rw-r--r--implementation/configuration/include/configuration.hpp93
-rw-r--r--implementation/configuration/include/configuration_element.hpp12
-rw-r--r--implementation/configuration/include/configuration_impl.hpp166
-rw-r--r--implementation/configuration/include/configuration_plugin.hpp12
-rw-r--r--implementation/configuration/include/configuration_plugin_impl.hpp9
-rw-r--r--implementation/configuration/include/debounce.hpp4
-rw-r--r--implementation/configuration/include/e2e.hpp6
-rw-r--r--implementation/configuration/include/event.hpp19
-rw-r--r--implementation/configuration/include/eventgroup.hpp2
-rw-r--r--implementation/configuration/include/internal.hpp.in144
-rw-r--r--implementation/configuration/include/internal_android.hpp142
-rw-r--r--implementation/configuration/include/routing.hpp71
-rw-r--r--implementation/configuration/include/service.hpp13
-rw-r--r--implementation/configuration/include/service_instance_range.hpp2
-rw-r--r--implementation/configuration/include/trace.hpp7
-rw-r--r--implementation/configuration/include/watchdog.hpp2
-rw-r--r--implementation/configuration/src/configuration_impl.cpp1155
-rw-r--r--implementation/configuration/src/configuration_plugin_impl.cpp38
-rw-r--r--implementation/e2e_protection/include/buffer/buffer.hpp2
-rw-r--r--implementation/e2e_protection/include/crc/crc.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp3
-rw-r--r--implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp3
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp10
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp11
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp2
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp4
-rw-r--r--implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp2
-rw-r--r--implementation/e2e_protection/include/e2exf/config.hpp2
-rw-r--r--implementation/e2e_protection/src/buffer/buffer.cpp2
-rw-r--r--implementation/e2e_protection/src/crc/crc.cpp9
-rw-r--r--implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp2
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp10
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp10
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp10
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp27
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp11
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp32
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp10
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp10
-rw-r--r--implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp11
-rw-r--r--implementation/e2e_protection/src/e2exf/config.cpp2
-rw-r--r--implementation/endpoints/include/buffer.hpp49
-rw-r--r--implementation/endpoints/include/client_endpoint.hpp9
-rw-r--r--implementation/endpoints/include/client_endpoint_impl.hpp51
-rw-r--r--implementation/endpoints/include/credentials.hpp11
-rw-r--r--implementation/endpoints/include/endpoint.hpp19
-rw-r--r--implementation/endpoints/include/endpoint_definition.hpp2
-rw-r--r--implementation/endpoints/include/endpoint_host.hpp22
-rw-r--r--implementation/endpoints/include/endpoint_impl.hpp12
-rw-r--r--implementation/endpoints/include/endpoint_manager_base.hpp41
-rw-r--r--implementation/endpoints/include/endpoint_manager_impl.hpp73
-rw-r--r--implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp118
-rw-r--r--implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp74
-rw-r--r--implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp166
-rw-r--r--implementation/endpoints/include/local_uds_client_endpoint_impl.hpp (renamed from implementation/endpoints/include/local_client_endpoint_impl.hpp)45
-rw-r--r--implementation/endpoints/include/local_uds_server_endpoint_impl.hpp (renamed from implementation/endpoints/include/local_server_endpoint_impl.hpp)118
-rw-r--r--implementation/endpoints/include/netlink_connector.hpp36
-rw-r--r--implementation/endpoints/include/server_endpoint_impl.hpp81
-rw-r--r--implementation/endpoints/include/tcp_client_endpoint_impl.hpp15
-rw-r--r--implementation/endpoints/include/tcp_server_endpoint_impl.hpp36
-rw-r--r--implementation/endpoints/include/tp.hpp13
-rw-r--r--implementation/endpoints/include/tp_message.hpp2
-rw-r--r--implementation/endpoints/include/tp_reassembler.hpp11
-rw-r--r--implementation/endpoints/include/udp_client_endpoint_impl.hpp22
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp48
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp186
-rw-r--r--implementation/endpoints/include/virtual_server_endpoint_impl.hpp19
-rw-r--r--implementation/endpoints/src/client_endpoint_impl.cpp338
-rw-r--r--implementation/endpoints/src/credentials.cpp105
-rw-r--r--implementation/endpoints/src/endpoint_definition.cpp2
-rw-r--r--implementation/endpoints/src/endpoint_impl.cpp30
-rw-r--r--implementation/endpoints/src/endpoint_manager_base.cpp267
-rw-r--r--implementation/endpoints/src/endpoint_manager_impl.cpp336
-rw-r--r--implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp382
-rw-r--r--implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp897
-rw-r--r--implementation/endpoints/src/local_uds_client_endpoint_impl.cpp (renamed from implementation/endpoints/src/local_client_endpoint_impl.cpp)180
-rw-r--r--implementation/endpoints/src/local_uds_server_endpoint_impl.cpp (renamed from implementation/endpoints/src/local_server_endpoint_impl.cpp)596
-rw-r--r--implementation/endpoints/src/netlink_connector.cpp65
-rw-r--r--implementation/endpoints/src/server_endpoint_impl.cpp529
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp99
-rw-r--r--implementation/endpoints/src/tcp_server_endpoint_impl.cpp171
-rw-r--r--implementation/endpoints/src/tp.cpp19
-rw-r--r--implementation/endpoints/src/tp_message.cpp4
-rw-r--r--implementation/endpoints/src/tp_reassembler.cpp5
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp96
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp617
-rw-r--r--implementation/endpoints/src/virtual_server_endpoint_impl.cpp20
-rw-r--r--implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp1043
-rw-r--r--implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp1989
-rw-r--r--implementation/helper/1.66/boost/asio/basic_socket_ext.hpp1760
-rw-r--r--implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp1760
-rw-r--r--implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp924
-rw-r--r--implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp565
-rw-r--r--implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp592
-rw-r--r--implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp302
-rw-r--r--implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp302
-rw-r--r--implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp230
-rw-r--r--implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp302
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp138
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp138
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp141
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp141
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp135
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp135
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp517
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp514
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp531
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp529
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp42
-rw-r--r--implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp47
-rw-r--r--implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp62
-rw-r--r--implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp95
-rw-r--r--implementation/helper/1.66/boost/asio/ip/udp_ext.hpp115
-rw-r--r--implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp93
-rw-r--r--implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp415
-rw-r--r--implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp1118
-rw-r--r--implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp2381
-rw-r--r--implementation/helper/1.70/boost/asio/basic_socket_ext.hpp1859
-rw-r--r--implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp1859
-rw-r--r--implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp996
-rw-r--r--implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp586
-rw-r--r--implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp588
-rw-r--r--implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp302
-rw-r--r--implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp302
-rw-r--r--implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp230
-rw-r--r--implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp303
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp140
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp140
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp145
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp145
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp138
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp138
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp521
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp521
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp508
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp508
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp42
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp43
-rw-r--r--implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp62
-rw-r--r--implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp95
-rw-r--r--implementation/helper/1.70/boost/asio/ip/udp_ext.hpp115
-rw-r--r--implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp93
-rw-r--r--implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp1118
-rw-r--r--implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp2381
-rw-r--r--implementation/helper/1.74/boost/asio/basic_socket_ext.hpp1859
-rw-r--r--implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp1859
-rw-r--r--implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp996
-rw-r--r--implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp586
-rw-r--r--implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp588
-rw-r--r--implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp302
-rw-r--r--implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp302
-rw-r--r--implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp234
-rw-r--r--implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp307
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp162
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp162
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp153
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp148
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp144
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp145
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp524
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp524
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp508
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp508
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp43
-rw-r--r--implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp44
-rw-r--r--implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp62
-rw-r--r--implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp95
-rw-r--r--implementation/helper/1.74/boost/asio/ip/udp_ext.hpp115
-rw-r--r--implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp93
-rw-r--r--implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp1118
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp2381
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_ext.hpp1859
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp1859
-rw-r--r--implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp996
-rw-r--r--implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp586
-rw-r--r--implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp588
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp302
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp302
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp234
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp307
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp162
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp162
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp153
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp148
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp144
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp145
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp524
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp524
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp508
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp508
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp43
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp44
-rw-r--r--implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp62
-rw-r--r--implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp95
-rw-r--r--implementation/helper/1.76/boost/asio/ip/udp_ext.hpp115
-rw-r--r--implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp93
-rw-r--r--implementation/helper/boost/asio/basic_datagram_socket_ext.hpp (renamed from implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp (renamed from implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/basic_stream_socket_ext.hpp (renamed from implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/datagram_socket_service_ext.hpp (renamed from implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp (renamed from implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp)0
-rw-r--r--implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp (renamed from implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp)0
-rw-r--r--implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp (renamed from implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp)76
-rw-r--r--implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp (renamed from implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactor_op_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/socket_ops_ext.hpp (renamed from implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp (renamed from implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp)0
-rw-r--r--implementation/helper/boost/asio/ip/udp_ext.hpp (renamed from implementation/helper/1.55/boost/asio/ip/udp_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/local/stream_protocol_ext.hpp (renamed from implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/socket_acceptor_service_ext.hpp (renamed from implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp)0
-rw-r--r--implementation/helper/boost/asio/stream_socket_service_ext.hpp (renamed from implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp)0
-rw-r--r--implementation/logger/include/logger_impl.hpp8
-rw-r--r--implementation/logger/src/logger_impl.cpp17
-rw-r--r--implementation/logger/src/message.cpp100
-rw-r--r--implementation/message/include/deserializer.hpp3
-rw-r--r--implementation/message/include/message_base_impl.hpp2
-rw-r--r--implementation/message/include/message_header_impl.hpp2
-rw-r--r--implementation/message/include/message_impl.hpp14
-rw-r--r--implementation/message/include/payload_impl.hpp2
-rw-r--r--implementation/message/include/serializer.hpp9
-rw-r--r--implementation/message/src/deserializer.cpp29
-rw-r--r--implementation/message/src/message_base_impl.cpp2
-rw-r--r--implementation/message/src/message_header_impl.cpp2
-rw-r--r--implementation/message/src/message_impl.cpp44
-rw-r--r--implementation/message/src/payload_impl.cpp2
-rw-r--r--implementation/message/src/serializer.cpp2
-rw-r--r--implementation/plugin/include/plugin_manager.hpp8
-rw-r--r--implementation/plugin/include/plugin_manager_impl.hpp12
-rw-r--r--implementation/plugin/src/plugin_manager.cpp2
-rw-r--r--implementation/plugin/src/plugin_manager_impl.cpp70
-rw-r--r--implementation/protocol/include/assign_client_ack_command.hpp33
-rw-r--r--implementation/protocol/include/assign_client_command.hpp38
-rw-r--r--implementation/protocol/include/command.hpp46
-rw-r--r--implementation/protocol/include/deregister_application_command.hpp24
-rw-r--r--implementation/protocol/include/distribute_security_policies_command.hpp44
-rw-r--r--implementation/protocol/include/dummy_command.hpp28
-rw-r--r--implementation/protocol/include/expire_command.hpp33
-rw-r--r--implementation/protocol/include/multiple_services_command_base.hpp37
-rw-r--r--implementation/protocol/include/offer_service_command.hpp24
-rw-r--r--implementation/protocol/include/offered_services_request_command.hpp33
-rw-r--r--implementation/protocol/include/offered_services_response_command.hpp23
-rw-r--r--implementation/protocol/include/ping_command.hpp24
-rw-r--r--implementation/protocol/include/pong_command.hpp24
-rw-r--r--implementation/protocol/include/protocol.hpp142
-rw-r--r--implementation/protocol/include/register_application_command.hpp33
-rw-r--r--implementation/protocol/include/register_event.hpp67
-rw-r--r--implementation/protocol/include/register_events_command.hpp40
-rw-r--r--implementation/protocol/include/registered_ack_command.hpp24
-rw-r--r--implementation/protocol/include/release_service_command.hpp39
-rw-r--r--implementation/protocol/include/remove_security_policy_command.hpp41
-rw-r--r--implementation/protocol/include/remove_security_policy_response_command.hpp24
-rw-r--r--implementation/protocol/include/request_service_command.hpp23
-rw-r--r--implementation/protocol/include/resend_provided_events_command.hpp33
-rw-r--r--implementation/protocol/include/routing_info_command.hpp36
-rw-r--r--implementation/protocol/include/routing_info_entry.hpp59
-rw-r--r--implementation/protocol/include/security_policy_response_command_base.hpp38
-rw-r--r--implementation/protocol/include/send_command.hpp52
-rw-r--r--implementation/protocol/include/service_command_base.hpp45
-rw-r--r--implementation/protocol/include/simple_command.hpp30
-rw-r--r--implementation/protocol/include/stop_offer_service_command.hpp24
-rw-r--r--implementation/protocol/include/subscribe_ack_command.hpp24
-rw-r--r--implementation/protocol/include/subscribe_ack_command_base.hpp57
-rw-r--r--implementation/protocol/include/subscribe_command.hpp39
-rw-r--r--implementation/protocol/include/subscribe_command_base.hpp59
-rw-r--r--implementation/protocol/include/subscribe_nack_command.hpp24
-rw-r--r--implementation/protocol/include/suspend_command.hpp24
-rw-r--r--implementation/protocol/include/unregister_event_command.hpp49
-rw-r--r--implementation/protocol/include/unsubscribe_ack_command.hpp47
-rw-r--r--implementation/protocol/include/unsubscribe_command.hpp33
-rw-r--r--implementation/protocol/include/update_security_credentials_command.hpp39
-rw-r--r--implementation/protocol/include/update_security_policy_command.hpp42
-rw-r--r--implementation/protocol/include/update_security_policy_response_command.hpp24
-rw-r--r--implementation/protocol/src/assign_client_ack_command.cpp79
-rw-r--r--implementation/protocol/src/assign_client_command.cpp83
-rw-r--r--implementation/protocol/src/command.cpp66
-rw-r--r--implementation/protocol/src/deregister_application_command.cpp19
-rw-r--r--implementation/protocol/src/distribute_security_policies_command.cpp130
-rw-r--r--implementation/protocol/src/dummy_command.cpp40
-rw-r--r--implementation/protocol/src/expire_command.cpp64
-rw-r--r--implementation/protocol/src/multiple_services_command_base.cpp119
-rw-r--r--implementation/protocol/src/offer_service_command.cpp17
-rw-r--r--implementation/protocol/src/offered_services_request_command.cpp78
-rw-r--r--implementation/protocol/src/offered_services_response_command.cpp17
-rw-r--r--implementation/protocol/src/ping_command.cpp17
-rw-r--r--implementation/protocol/src/pong_command.cpp17
-rw-r--r--implementation/protocol/src/register_application_command.cpp81
-rw-r--r--implementation/protocol/src/register_event.cpp82
-rw-r--r--implementation/protocol/src/register_events_command.cpp110
-rw-r--r--implementation/protocol/src/registered_ack_command.cpp17
-rw-r--r--implementation/protocol/src/release_service_command.cpp101
-rw-r--r--implementation/protocol/src/remove_security_policy_command.cpp114
-rw-r--r--implementation/protocol/src/remove_security_policy_response_command.cpp18
-rw-r--r--implementation/protocol/src/request_service_command.cpp17
-rw-r--r--implementation/protocol/src/resend_provided_events_command.cpp80
-rw-r--r--implementation/protocol/src/routing_info_command.cpp98
-rw-r--r--implementation/protocol/src/routing_info_entry.cpp304
-rw-r--r--implementation/protocol/src/security_policy_response_command_base.cpp80
-rw-r--r--implementation/protocol/src/send_command.cpp149
-rw-r--r--implementation/protocol/src/service_command_base.cpp130
-rw-r--r--implementation/protocol/src/simple_command.cpp48
-rw-r--r--implementation/protocol/src/stop_offer_service_command.cpp17
-rw-r--r--implementation/protocol/src/subscribe_ack_command.cpp17
-rw-r--r--implementation/protocol/src/subscribe_ack_command_base.cpp174
-rw-r--r--implementation/protocol/src/subscribe_command.cpp144
-rw-r--r--implementation/protocol/src/subscribe_command_base.cpp146
-rw-r--r--implementation/protocol/src/subscribe_nack_command.cpp17
-rw-r--r--implementation/protocol/src/suspend_command.cpp17
-rw-r--r--implementation/protocol/src/unregister_event_command.cpp135
-rw-r--r--implementation/protocol/src/unsubscribe_ack_command.cpp139
-rw-r--r--implementation/protocol/src/unsubscribe_command.cpp64
-rw-r--r--implementation/protocol/src/update_security_credentials_command.cpp103
-rw-r--r--implementation/protocol/src/update_security_policy_command.cpp120
-rw-r--r--implementation/protocol/src/update_security_policy_response_command.cpp18
-rw-r--r--implementation/routing/include/event.hpp50
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp4
-rw-r--r--implementation/routing/include/function_types.hpp7
-rw-r--r--implementation/routing/include/remote_subscription.hpp3
-rw-r--r--implementation/routing/include/routing_host.hpp13
-rw-r--r--implementation/routing/include/routing_manager.hpp43
-rw-r--r--implementation/routing/include/routing_manager_adapter.hpp2
-rw-r--r--implementation/routing/include/routing_manager_base.hpp126
-rw-r--r--implementation/routing/include/routing_manager_client.hpp (renamed from implementation/routing/include/routing_manager_proxy.hpp)107
-rw-r--r--implementation/routing/include/routing_manager_host.hpp30
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp155
-rw-r--r--implementation/routing/include/routing_manager_stub.hpp136
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp96
-rw-r--r--implementation/routing/include/serviceinfo.hpp8
-rw-r--r--implementation/routing/include/types.hpp18
-rw-r--r--implementation/routing/src/event.cpp615
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp72
-rw-r--r--implementation/routing/src/remote_subscription.cpp3
-rw-r--r--implementation/routing/src/routing_manager_base.cpp346
-rw-r--r--implementation/routing/src/routing_manager_client.cpp2890
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp1160
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp2734
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp2550
-rw-r--r--implementation/routing/src/serviceinfo.cpp14
-rw-r--r--implementation/runtime/include/application_impl.hpp117
-rw-r--r--implementation/runtime/include/runtime_impl.hpp4
-rw-r--r--implementation/runtime/src/application_impl.cpp837
-rw-r--r--implementation/runtime/src/runtime.cpp21
-rw-r--r--implementation/runtime/src/runtime_impl.cpp17
-rw-r--r--implementation/security/include/policy.hpp2
-rw-r--r--implementation/security/include/policy_manager_impl.hpp177
-rw-r--r--implementation/security/include/security.hpp73
-rw-r--r--implementation/security/include/security_impl.hpp114
-rw-r--r--implementation/security/src/policy.cpp9
-rw-r--r--implementation/security/src/policy_manager.cpp6
-rw-r--r--implementation/security/src/policy_manager_impl.cpp1446
-rw-r--r--implementation/security/src/security.cpp140
-rw-r--r--implementation/security/src/security_impl.cpp1196
-rw-r--r--implementation/service_discovery/include/configuration_option_impl.hpp4
-rw-r--r--implementation/service_discovery/include/constants.hpp2
-rw-r--r--implementation/service_discovery/include/defines.hpp4
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/deserializer.hpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/entry_impl.hpp2
-rw-r--r--implementation/service_discovery/include/enumeration_types.hpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/eventgroupentry_impl.hpp2
-rw-r--r--implementation/service_discovery/include/ip_option_impl.hpp4
-rw-r--r--implementation/service_discovery/include/ipv4_option_impl.hpp10
-rw-r--r--implementation/service_discovery/include/ipv6_option_impl.hpp4
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/load_balancing_option_impl.hpp4
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/message_element_impl.hpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/message_impl.hpp10
-rw-r--r--implementation/service_discovery/include/option_impl.hpp5
-rw-r--r--implementation/service_discovery/include/primitive_types.hpp12
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/include/protection_option_impl.hpp4
-rw-r--r--implementation/service_discovery/include/remote_subscription_ack.hpp2
-rw-r--r--implementation/service_discovery/include/request.hpp2
-rw-r--r--implementation/service_discovery/include/runtime.hpp2
-rw-r--r--implementation/service_discovery/include/runtime_impl.hpp2
-rw-r--r--implementation/service_discovery/include/selective_option_impl.hpp4
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp14
-rw-r--r--implementation/service_discovery/include/service_discovery_host.hpp16
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp49
-rw-r--r--implementation/service_discovery/include/serviceentry_impl.hpp2
-rw-r--r--implementation/service_discovery/include/subscription.hpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/configuration_option_impl.cpp8
-rw-r--r--implementation/service_discovery/src/deserializer.cpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/entry_impl.cpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/eventgroupentry_impl.cpp14
-rw-r--r--implementation/service_discovery/src/ip_option_impl.cpp6
-rw-r--r--implementation/service_discovery/src/ipv4_option_impl.cpp6
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/ipv6_option_impl.cpp6
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/load_balancing_option_impl.cpp6
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/message_element_impl.cpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/message_impl.cpp19
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/option_impl.cpp10
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/protection_option_impl.cpp6
-rw-r--r--implementation/service_discovery/src/remote_subscription_ack.cpp2
-rw-r--r--implementation/service_discovery/src/request.cpp2
-rw-r--r--implementation/service_discovery/src/runtime_impl.cpp2
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/selective_option_impl.cpp6
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp292
-rw-r--r--[-rwxr-xr-x]implementation/service_discovery/src/serviceentry_impl.cpp2
-rw-r--r--implementation/service_discovery/src/subscription.cpp4
-rw-r--r--implementation/tracing/include/channel_impl.hpp23
-rw-r--r--implementation/tracing/include/connector_impl.hpp10
-rw-r--r--implementation/tracing/include/defines.hpp2
-rw-r--r--implementation/tracing/include/enumeration_types.hpp5
-rw-r--r--implementation/tracing/include/header.hpp2
-rw-r--r--implementation/tracing/src/channel_impl.cpp82
-rw-r--r--implementation/tracing/src/connector_impl.cpp112
-rw-r--r--implementation/tracing/src/header.cpp2
-rw-r--r--implementation/utility/include/byteorder.hpp12
-rw-r--r--implementation/utility/include/criticalsection.hpp2
-rw-r--r--implementation/utility/include/utility.hpp83
-rw-r--r--implementation/utility/src/criticalsection.cpp2
-rw-r--r--implementation/utility/src/utility.cpp173
-rw-r--r--implementation/utility/src/wrappers.cpp38
433 files changed, 20078 insertions, 65230 deletions
diff --git a/implementation/compat/runtime/src/application_impl.cpp b/implementation/compat/runtime/src/application_impl.cpp
index ce65136..f1934e4 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 0000000..f20afd5
--- /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 <map>
+#include <set>
+
+#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/plugin.hpp>
+
+#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<plugin_type_e, std::set<std::string> > 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 872974f..5c0805d 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 e107e17..ef597e1 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 <vsomeip/defines.hpp>
#include <vsomeip/plugin.hpp>
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/vsomeip_sec.h>
#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 @@ public:
#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 @@ public:
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 @@ public:
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<std::pair<port_t, port_t> > 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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
virtual void set_configuration_path(const std::string &_path) = 0;
+ virtual std::map<std::string, std::string> get_additional_data(
+ const std::string &_application_name,
+ const std::string &_plugin_name) = 0;
+
//E2E
virtual std::map<e2exf::data_identifier_t, std::shared_ptr<cfg::e2e>> get_e2e_configuration() const = 0;
virtual bool is_e2e_enabled() const = 0;
@@ -199,17 +212,18 @@ public:
virtual uint32_t get_log_status_interval() const = 0;
// TTL factor
- typedef std::uint32_t ttl_factor_t;
- typedef std::map<service_t, std::map<instance_t, ttl_factor_t>> ttl_map_t;
+ using ttl_factor_t = std::uint32_t;
+ using ttl_map_t = std::map<service_t, std::map<instance_t, ttl_factor_t>>;
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<cfg::debounce> get_debounce(
+ virtual std::shared_ptr<debounce_filter_t> 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 @@ public:
const boost::asio::ip::address& _address, std::uint16_t _port,
bool _reliable) const = 0;
- typedef std::pair<std::uint16_t, std::uint16_t> port_range_t;
+ using port_range_t = std::pair<std::uint16_t, std::uint16_t>;
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 @@ public:
>
>
>
- > 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 @@ public:
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 @@ public:
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 7daf9d7..2b650e3 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 cb6c284..9ae1c79 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 <list>
#include <map>
#include <memory>
#include <mutex>
-#include <vector>
#include <unordered_set>
-#include <list>
+#include <vector>
#include <boost/property_tree/ptree.hpp>
-#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<configuration_impl> {
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 @@ public:
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 @@ public:
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 @@ public:
uint16_t _remote_port, bool _reliable,
std::map<bool, std::set<uint16_t> > &_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<std::pair<port_t, port_t> > 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 @@ public:
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 @@ public:
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<plugin_type_e, std::set<std::string>> get_plugins(
const std::string &_name) const;
@@ -189,7 +204,8 @@ public:
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<debounce> get_debounce(
+ VSOMEIP_EXPORT std::shared_ptr<debounce_filter_t> 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 @@ public:
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 @@ public:
VSOMEIP_EXPORT partition_id_t get_partition_id(
service_t _service, instance_t _instance) const;
+ VSOMEIP_EXPORT std::map<std::string, std::string> 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<std::string> &_input,
std::vector<configuration_element> &_elements,
std::set<std::string> &_failed,
+ bool _mandatory_only, bool _read_second_level = false);
+#ifndef VSOMEIP_DISABLE_POLICY
+ void load_policy_data(const std::string &_input,
+ std::vector<configuration_element> &_elements,
+ std::set<std::string> &_failed,
bool _mandatory_only);
-
+#endif // !VSOMEIP_DISABLE_POLICY
bool load_data(const std::vector<configuration_element> &_elements,
bool _load_mandatory, bool _load_optional);
bool load_logging(const configuration_element &_element,
std::set<std::string> &_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 @@ private:
std::map<plugin_type_e, std::set<std::string>> 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 @@ private:
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 @@ private:
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<event_t, std::shared_ptr<debounce>> &_debounces);
+ std::map<event_t, std::shared_ptr<debounce_filter_t> > &_debounces);
void load_event_debounce(const boost::property_tree::ptree &_tree,
- std::map<event_t, std::shared_ptr<debounce>> &_debounces);
+ std::map<event_t, std::shared_ptr<debounce_filter_t> > &_debounces);
void load_event_debounce_ignore(const boost::property_tree::ptree &_tree,
std::map<std::size_t, byte_t> &_ignore);
void load_acceptances(const configuration_element &_element);
@@ -354,8 +398,8 @@ private:
instance_t _instance) const;
std::shared_ptr<service> find_service(service_t _service, instance_t _instance) const;
std::shared_ptr<service> 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<service> find_service(service_t _service,
+ const std::string &_address, std::uint16_t _port) const;
std::shared_ptr<eventgroup> 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 @@ private:
const std::string default_unicast_;
bool is_loaded_;
bool is_logging_loaded_;
- bool is_overlay_;
std::set<std::string> mandatory_;
@@ -404,6 +447,7 @@ protected:
// 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 @@ protected:
std::string logfile_;
vsomeip_v3::logger::level_e loglevel_;
- std::map<std::string,
- std::tuple<
- client_t,
- std::size_t, // max dispatchers
- std::size_t, // max dispatch time
- std::size_t, // thread count
- std::size_t, // request debouncing
- std::map<
- plugin_type_e,
- std::set<std::string>
- >, // 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_t> client_identifiers_;
@@ -446,7 +476,7 @@ protected:
std::list< std::shared_ptr<client> > clients_;
- std::string routing_host_;
+ routing_t routing_;
bool is_sd_enabled_;
std::string sd_protocol_;
@@ -523,11 +553,12 @@ protected:
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 @@ protected:
ttl_map_t ttl_factors_offers_;
ttl_map_t ttl_factors_subscriptions_;
- std::map<service_t, std::map<instance_t, std::map<event_t, std::shared_ptr<debounce>>>> debounces_;
+ debounce_configuration_t debounces_;
std::map<std::string, std::map<std::uint16_t, endpoint_queue_limit_t>> endpoint_queue_limits_;
endpoint_queue_limit_t endpoint_queue_limit_external_;
@@ -581,6 +612,7 @@ protected:
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 @@ protected:
partition_id_t
>
> partitions_;
+
+ std::string path_;
+
+ std::map<std::string,
+ std::map<std::string,
+ std::map<std::string,
+ std::string
+ >
+ >
+ > 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 583c3d8..3ffc968 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<configuration> get_configuration(const std::string &_name) = 0;
+ virtual ~configuration_plugin() = default;
+ virtual std::shared_ptr<configuration> 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 fd95628..3fcfbef 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 @@ public:
configuration_plugin_impl();
virtual ~configuration_plugin_impl();
- std::shared_ptr<configuration> get_configuration(const std::string &_name);
+ std::shared_ptr<configuration> get_configuration(const std::string &_name,
+ const std::string &_path);
private:
std::mutex mutex_;
std::shared_ptr<cfg::configuration_impl> default_;
-#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS
+#if 0
std::map<std::string, std::shared_ptr<cfg::configuration_impl> > 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 dc61514..30ad984 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 705c92d..8345c2a 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<std::string, std::string> custom_parameters_t;
+ using custom_parameters_t = std::map<std::string, std::string, std::less<>>;
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 84dc5a0..1e35a85 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<std::weak_ptr<eventgroup> > 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 1402b51..328a02d 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 efd9ba0..91cd1ee 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 <cstdint>
#include <limits>
+#include <memory>
+
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/structured_types.hpp>
#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 <pthread.h>
#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<std::uint32_t>::max)();
@@ -230,8 +144,6 @@ const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits<std::uint32_
const std::uint32_t ANY_UID = 0xFFFFFFFF;
const std::uint32_t ANY_GID = 0xFFFFFFFF;
-typedef std::pair<std::uint32_t, std::uint32_t> 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<service_t,
+ std::map<instance_t, std::map<event_t, std::shared_ptr<debounce_filter_t>>>>;
+
+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 8ecd2b5..1efa0fa 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 <cstdint>
#include <limits>
+#include <memory>
+
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/structured_types.hpp>
#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 <pthread.h>
@@ -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<std::uint32_
const std::uint32_t ANY_UID = 0xFFFFFFFF;
const std::uint32_t ANY_GID = 0xFFFFFFFF;
-typedef std::pair<std::uint32_t, std::uint32_t> 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<service_t,
+ std::map<instance_t,
+ std::map<event_t,
+ std::shared_ptr<debounce_filter_t>
+ >
+ >
+> 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 0000000..4ffc3b9
--- /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 <boost/asio/ip/address.hpp>
+
+#include <vsomeip/internal/logger.hpp>
+#include <vsomeip/primitive_types.hpp>
+
+#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<std::pair<port_t, port_t> > 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 8077f8e..af84880 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<method_t, std::array<std::chrono::nanoseconds, 2>> npdu_time_configuration_t;
+ using npdu_time_configuration_t = std::map<method_t, std::array<std::chrono::nanoseconds, 2>>;
npdu_time_configuration_t debounce_times_requests_;
npdu_time_configuration_t debounce_times_responses_;
- std::shared_ptr<servicegroup> group_;
std::map<event_t, std::shared_ptr<event> > events_;
std::map<eventgroup_t, std::shared_ptr<eventgroup> > eventgroups_;
// SOME/IP-TP
- std::set<method_t> tp_segment_messages_client_to_service_;
- std::set<method_t> tp_segment_messages_service_to_client_;
+ std::map<method_t, std::pair<uint16_t, uint32_t> > tp_client_config_;
+ std::map<method_t, std::pair<uint16_t, uint32_t> > tp_service_config_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/service_instance_range.hpp b/implementation/configuration/include/service_instance_range.hpp
index a585d7a..9ae162f 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 c9eb8cb..a83aa81 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 <vsomeip/primitive_types.hpp>
#include <vsomeip/trace.hpp>
+#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<trace_channel_t> channels_;
- bool is_positive_;
+ vsomeip_v3::trace::filter_type_e ftype_;
bool is_range_;
std::vector<vsomeip_v3::trace::match_t> matches_;
};
diff --git a/implementation/configuration/include/watchdog.hpp b/implementation/configuration/include/watchdog.hpp
index 9fe81ff..5c9de1c 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 6fdbb67..2a8f632 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 <cctype>
#include <fstream>
#include <functional>
+#include <limits>
#include <set>
#include <sstream>
-#include <limits>
#include <utility>
#define WIN32_LEAN_AND_MEAN
+#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
+#include <boost/asio/ip/address.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <vsomeip/constants.hpp>
#include <vsomeip/plugins/application_plugin.hpp>
#include <vsomeip/plugins/pre_configuration_plugin.hpp>
#include <vsomeip/internal/logger.hpp>
+#include <vsomeip/structured_types.hpp>
#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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(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<std::string> its_input;
+ std::set<std::string> its_failed;
+ std::vector<configuration_element> 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<std::string> &_input,
std::vector<configuration_element> &_elements, std::set<std::string> &_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<std::string, bool> 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<configuration_element> &_elements, std::set<std::string> &_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<configuration_element> &_elements,
bool _load_mandatory, bool _load_optional) {
@@ -513,6 +592,7 @@ bool configuration_impl::load_data(const std::vector<configuration_element> &_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<bool>("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<std::pair<port_t, port_t> > its_invalid_ranges;
+ std::set<std::pair<port_t, port_t> > 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 (...) {
@@ -652,6 +784,140 @@ configuration_impl::load_routing(const configuration_element &_element) {
}
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 {
auto its_applications = _element.tree_.get_child("applications");
@@ -676,10 +942,8 @@ void configuration_impl::load_application_data(
std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME);
std::map<plugin_type_e, std::set<std::string>> 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<plugin_type_e, std::set<std::string>> configuration_impl::load_plugins(
const boost::property_tree::ptree &_tree,
- const std::string& _application_name) {
+ const std::string &_application_name) {
std::map<plugin_type_e, std::set<std::string>> its_plugins;
std::string its_name("");
std::string its_type;
@@ -788,6 +1059,19 @@ std::map<plugin_type_e, std::set<std::string>> 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::map<plugin_type_e, std::set<std::string
#endif
if (_plugin_data.type_ == "application_plugin") {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
its_library += ".";
its_library += (VSOMEIP_APPLICATION_PLUGIN_VERSION + '0');
#endif
_plugins[plugin_type_e::APPLICATION_PLUGIN].insert(its_library);
} else if (_plugin_data.type_ == "configuration_plugin") {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
its_library += ".";
its_library += (VSOMEIP_PRE_CONFIGURATION_PLUGIN_VERSION + '0');
#endif
@@ -931,7 +1215,12 @@ void configuration_impl::load_trace_filter(
has_channel = true;
} else if(its_key == "type") {
std::string its_value = i->second.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<std::string>("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<std::string>("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<std::string>("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<std::string>("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<uint32_t>::max()
+ << (std::numeric_limits<uint32_t>::digits - prefix_))
+ & std::numeric_limits<uint32_t>::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<std::string>("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<std::string>("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<std::string>("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<std::string>("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<major_version_t>(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<event> 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<event>(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<event> its_event = std::make_shared<event>(
+ 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<event>(its_event_id);
+ its_event = std::make_shared<event>(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<int>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::pair<port_t, port_t> >
+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<std::pair<service_t, instance_t> >
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<client> 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<bool, std::set<uint16_t> > &_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<service> 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<service>
+configuration_impl::find_service(service_t _service,
+ const std::string &_address, std::uint16_t _port) const {
+
+ std::shared_ptr<service> 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<plugin_type_e, std::set<std::string>> configuration_impl::get_plugins(
const std::string &_name) const {
- std::map<plugin_type_e, std::set<std::string>> result;
+
+ std::map<plugin_type_e, std::set<std::string>> 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<std::string, std::string> 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<event_t, std::shared_ptr<debounce>> its_debounces;
+ std::map<event_t, std::shared_ptr<debounce_filter_t>> 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<event_t, std::shared_ptr<debounce>> &_debounces) {
+ std::map<event_t, std::shared_ptr<debounce_filter_t> > &_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<event_t, std::shared_ptr<debounce>> &_debounces) {
+ std::map<event_t, std::shared_ptr<debounce_filter_t> > &_debounces) {
+
event_t its_event(0);
- std::shared_ptr<debounce> its_debounce = std::make_shared<debounce>();
+ auto its_debounce = std::make_shared<debounce_filter_t>();
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<std::uint16_t>::closed(30491, 30499);
- const auto its_optional_client_spare = boost::icl::interval<std::uint16_t>::closed(30898, 30998);
- const auto its_optional_server = boost::icl::interval<std::uint16_t>::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<std::uint16_t>::closed(32491, 32499);
- const auto its_secure_client_spare = boost::icl::interval<std::uint16_t>::closed(32898, 32998);
- const auto its_secure_server = boost::icl::interval<std::uint16_t>::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<debounce> configuration_impl::get_debounce(
+std::shared_ptr<debounce_filter_t>
+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<std::mutex> 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<std::mutex> 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<std::string> its_input;
- std::vector<configuration_element> its_elements;
- std::set<std::string> 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 df175f3..2293c09 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>
-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<std::mutex> its_lock(mutex_);
if (!default_) {
- default_ = std::make_shared<cfg::configuration_impl>();
+ default_ = std::make_shared<cfg::configuration_impl>(_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<cfg::configuration_impl>(
- *(its_configuration.get()));
- its_configuration->load_overlay(_name);
- configurations_[_name] = its_configuration;
- }
+#if 0
+ std::shared_ptr<cfg::configuration_impl> its_configuration;
+ auto its_iterator = configurations_.find(_name);
+ if (its_iterator != configurations_.end()) {
+ its_configuration = its_iterator->second;
+ } else {
+ its_configuration = std::make_shared<cfg::configuration_impl>(_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 8583ede..95205f8 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 b8d5688..de0ccec 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 41d7487..51e42e1 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 @@ public:
} // 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 62db2e2..631f87f 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 @@ private:
} // 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 4184996..8f97113 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 54b2d5c..097d9f5 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 13bd524..7e37993 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 c16eb10..2ed3ebd 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 <map>
+
#include "../profile04/profile_04.hpp"
#include "../profile_interface/checker.hpp"
@@ -20,14 +22,14 @@ public:
// [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 @@ private:
std::mutex check_mutex_;
profile_config config_;
- uint16_t counter_;
+ std::map<instance_t, uint16_t> 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 88be05c..11a7ee7 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 fd4a6e7..eab0a9a 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 <map>
#include <mutex>
+
#include "../profile04/profile_04.hpp"
#include "../profile_interface/protector.hpp"
@@ -19,20 +21,21 @@ public:
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<instance_t, uint16_t> 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 e233205..94d5456 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 244989d..0a97ff1 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 a2ec5d1..2396b5a 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 12cb6b7..1bdf447 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 5fa018c..5079e7e 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 4b02971..20c63d5 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 a022d8c..9c10504 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 d50310b..6d82622 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 60ddb6c..18c7ec7 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<uint8_t>(lookup_table_profile_01_[static_cast<uint8_t>((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<uint8_t>(lookup_table_profile_01_[static_cast<uint8_t>((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 111e126..0d05fca 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 a5d75d8..d70dac6 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 <vsomeip/internal/logger.hpp>
-#include <iostream>
-#include <sstream>
-#include <string>
#include <iomanip>
#include <algorithm>
+#include <vsomeip/internal/logger.hpp>
+#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 358dd4e..032bac0 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 <iostream>
-#include <sstream>
-#include <string>
-#include <iomanip>
+#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 e5cb4ba..0f514a0 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 <vsomeip/internal/logger.hpp>
-#include <iostream>
-#include <sstream>
-#include <string>
#include <iomanip>
+#include <vsomeip/internal/logger.hpp>
+#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 c9761ca..88c0192 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 <iomanip>
#include <vsomeip/internal/logger.hpp>
-#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<size_t>(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 05ab5e9..43a9380 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 <iomanip>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#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 a9287f2..bc7d0db 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 <iomanip>
-#include "../../../../../e2e_protection/include/e2e/profile/profile04/protector.hpp"
-
#include <vsomeip/internal/logger.hpp>
-#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<uint16_t>(_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 9916a2f..bce5af9 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 <vsomeip/internal/logger.hpp>
-#include <iostream>
-#include <sstream>
-#include <string>
#include <iomanip>
#include <algorithm>
+#include <vsomeip/internal/logger.hpp>
+#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 5ab53ca..4e2936e 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 <iostream>
-#include <sstream>
-#include <string>
-#include <iomanip>
+#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 c71f91f..1fd0ccb 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 <iostream>
-#include <sstream>
-#include <string>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
+#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 20a3b71..6f124d3 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 af0582d..089a526 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 <memory>
#include <set>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+#define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <boost/asio/steady_timer.hpp>
#include <vsomeip/defines.hpp>
#include <vsomeip/primitive_types.hpp>
-#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<byte_t> message_buffer_t;
-typedef std::shared_ptr<message_buffer_t> message_buffer_ptr_t;
+using message_buffer_t = std::vector<byte_t>;
+using message_buffer_ptr_t = std::shared_ptr<message_buffer_t>;
+#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<message_buffer_t>()),
- 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<boost::asio::steady_timer>(_io)) {};
+ train()
+ : buffer_(std::make_shared<message_buffer_t>()),
+ 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<message_buffer_t>();
+ 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<std::pair<service_t, method_t> > 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<boost::asio::steady_timer> departure_timer_;
- std::set<std::pair<service_t, method_t> > 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 3429a92..372a122 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 518e696..f7e7567 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 <atomic>
#include <condition_variable>
#include <deque>
#include <mutex>
#include <vector>
-#include <atomic>
#include <chrono>
+#include <thread>
#include <boost/array.hpp>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/utility.hpp>
@@ -35,13 +35,13 @@ template<typename Protocol>
class client_endpoint_impl: public endpoint_impl<Protocol>, public client_endpoint,
public std::enable_shared_from_this<client_endpoint_impl<Protocol> > {
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>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _configuration);
@@ -56,7 +56,7 @@ public:
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 @@ public:
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 @@ protected:
CONNECTED,
ESTABLISHED
};
- message_buffer_ptr_t get_front();
- virtual void send_queued(message_buffer_ptr_t _buffer) = 0;
+ std::pair<message_buffer_ptr_t, uint32_t> get_front();
+ virtual void send_queued(std::pair<message_buffer_ptr_t, uint32_t> &_entry) = 0;
virtual void get_configured_times_from_endpoint(
service_t _service, method_t _method,
std::chrono::nanoseconds *_debouncing,
@@ -103,10 +104,13 @@ protected:
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<Protocol>::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> &_train,
+ bool _queue_size_zero_on_entry);
+ void update_last_departure();
protected:
mutable std::mutex socket_mutex_;
@@ -121,10 +125,20 @@ protected:
std::atomic<cei_state_e> state_;
std::atomic<std::uint32_t> reconnect_counter_;
- // send data
- train train_;
+ std::mutex connecting_timer_mutex_;
+ boost::asio::steady_timer connecting_timer_;
+ std::atomic<uint32_t> connecting_timeout_;
+
- std::deque<message_buffer_ptr_t> queue_;
+ // send data
+ std::shared_ptr<train> train_;
+ std::map<std::chrono::steady_clock::time_point,
+ std::deque<std::shared_ptr<train> > > dispatched_trains_;
+ boost::asio::steady_timer dispatch_timer_;
+ std::chrono::steady_clock::time_point last_departure_;
+ std::atomic<bool> has_last_departure_;
+
+ std::deque<std::pair<message_buffer_ptr_t, uint32_t> > queue_;
std::size_t queue_size_;
mutable std::mutex mutex_;
@@ -133,7 +147,7 @@ protected:
std::atomic<std::uint16_t> 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 @@ private:
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 2fe9060..bb4ee44 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 <tuple>
+
+#include <boost/optional.hpp>
+
#include <vsomeip/primitive_types.hpp>
namespace vsomeip_v3 {
@@ -16,9 +20,10 @@ public:
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<client_t, uid_t, gid_t, std::string>;
+ static boost::optional<received_t> 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 3eafc3a..f3a76b7 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<void()> error_handler_t;
- typedef std::function<void(const std::shared_ptr<endpoint>&, service_t)> prepare_stop_handler_t;
+ using error_handler_t = std::function<void()>;
+ using prepare_stop_handler_t = std::function<void(const std::shared_ptr<endpoint>&, 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 @@ public:
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<byte_t>& _cmd_header, const byte_t *_data,
- uint32_t _size) = 0;
virtual bool send_to(const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size) = 0;
virtual bool send_error(const std::shared_ptr<endpoint_definition> _target,
@@ -62,7 +55,7 @@ public:
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 5a7e9eb..2dca226 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 2af1697..e5ca6d1 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> 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> _endpoint) = 0;
virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint) = 0;
- virtual bool on_bind_error(std::shared_ptr<endpoint> _endpoint, uint16_t _remote_port) = 0;
+ virtual bool on_bind_error(std::shared_ptr<endpoint> _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 76f4698..730c290 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 <mutex>
#include <atomic>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include "buffer.hpp"
@@ -26,12 +25,12 @@ class routing_host;
template<typename Protocol>
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>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _configuration);
@@ -50,7 +49,7 @@ public:
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 @@ public:
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 @@ protected:
};
// Reference to service context
- boost::asio::io_service &service_;
+ boost::asio::io_context &io_;
// References to hosts
std::weak_ptr<endpoint_host> endpoint_host_;
diff --git a/implementation/endpoints/include/endpoint_manager_base.hpp b/implementation/endpoints/include/endpoint_manager_base.hpp
index aa21269..fec39cc 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 <unordered_set>
#include <memory>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <vsomeip/primitive_types.hpp>
@@ -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>& _configuration);
virtual ~endpoint_manager_base() = default;
@@ -44,23 +48,31 @@ public:
std::unordered_set<client_t> get_connected_clients() const;
- std::shared_ptr<local_server_endpoint_impl> create_local_server(
+ std::shared_ptr<endpoint> create_local_server(
const std::shared_ptr<routing_host> &_routing_host);
// endpoint_host interface
virtual void on_connect(std::shared_ptr<endpoint> _endpoint);
virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint);
- virtual bool on_bind_error(std::shared_ptr<endpoint> _endpoint, uint16_t _remote_port);
+ virtual bool on_bind_error(std::shared_ptr<endpoint> _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<client_t, std::shared_ptr<endpoint>> get_local_endpoints() const;
@@ -68,14 +80,23 @@ private:
std::shared_ptr<endpoint> create_local_unlocked(client_t _client);
std::shared_ptr<endpoint> find_local_unlocked(client_t _client);
+ bool get_local_server_port(port_t &_port, const std::set<port_t> &_used_ports) const;
+
protected:
routing_manager_base* const rm_;
- boost::asio::io_service& io_;
+ boost::asio::io_context &io_;
std::shared_ptr<configuration> 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<client_t, std::shared_ptr<endpoint> > 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 3354947..a354fb5 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 <condition_variable>
+#include <queue>
+#include <thread>
+
#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>& _configuration);
- ~endpoint_manager_impl() = default;
+ ~endpoint_manager_impl();
std::shared_ptr<endpoint> find_or_create_remote_client(service_t _service,
instance_t _instance,
@@ -66,9 +70,10 @@ public:
void print_status() const;
- std::shared_ptr<local_server_endpoint_impl> create_local_server(
- bool* _is_socket_activated,
- const std::shared_ptr<routing_host>& _routing_host);
+ bool create_routing_root(
+ std::shared_ptr<endpoint> &_root,
+ bool &_is_socket_activated,
+ const std::shared_ptr<routing_host> &_host);
instance_t find_instance(service_t _service,
endpoint* const _endpoint) const;
@@ -83,17 +88,30 @@ public:
void on_connect(std::shared_ptr<endpoint> _endpoint);
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
bool on_bind_error(std::shared_ptr<endpoint> _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<bool, std::set<port_t> > &_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<endpoint> find_remote_client(service_t _service,
instance_t _instance,
@@ -105,40 +123,49 @@ private:
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<service_t, std::map<instance_t,
std::map<bool, std::shared_ptr<endpoint_definition>>>> remote_service_info_;
- typedef std::map<service_t, std::map<instance_t,
- std::map<bool, std::shared_ptr<endpoint>>>> remote_services_t;
+ using remote_services_t =
+ std::map<service_t, std::map<instance_t, std::map<bool, std::shared_ptr<endpoint>>>>;
remote_services_t remote_services_;
- typedef std::map<boost::asio::ip::address,
- std::map<uint16_t,
- std::map<bool,
- std::map<partition_id_t,
- std::shared_ptr<endpoint>
- >
- >
- >
- > client_endpoints_by_ip_t;
+ using client_endpoints_by_ip_t =
+ std::map<boost::asio::ip::address,
+ std::map<std::uint16_t,
+ std::map<bool, std::map<partition_id_t, std::shared_ptr<endpoint>>>>>;
client_endpoints_by_ip_t client_endpoints_by_ip_;
std::map<service_t, std::map<endpoint *, instance_t> > service_instances_;
std::map<service_t, std::map<boost::asio::ip::address, instance_t> > service_instances_multicast_;
- std::map<bool, std::set<uint16_t>> used_client_ports_;
+ std::map<boost::asio::ip::address,
+ std::map<port_t,
+ std::map<bool, std::set<port_t> >
+ >
+ > used_client_ports_;
std::mutex used_client_ports_mutex_;
// Server endpoints for local services
- typedef std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint>>> server_endpoints_t;
+ using server_endpoints_t = std::map<std::uint16_t, std::map<bool, std::shared_ptr<endpoint>>>;
server_endpoints_t server_endpoints_;
// Multicast endpoint info (notifications)
std::map<service_t, std::map<instance_t,
std::shared_ptr<endpoint_definition>>> multicast_info;
+
+ // Socket option processing (join, leave)
+ std::mutex options_mutex_;
+ bool is_processing_options_;
+ std::condition_variable options_condition_;
+ std::queue<multicast_option_t> 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 0000000..38e1662
--- /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 <boost/asio/local/stream_protocol.hpp>
+
+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<size_t>(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 0000000..45b6e72
--- /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 <boost/asio/ip/tcp.hpp>
+
+#include <vsomeip/defines.hpp>
+
+#include "client_endpoint_impl.hpp"
+
+namespace vsomeip_v3 {
+
+using local_tcp_client_endpoint_base_impl = client_endpoint_impl<boost::asio::ip::tcp>;
+
+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> &_endpoint_host,
+ const std::shared_ptr<routing_host> &_routing_host,
+ const endpoint_type &_local,
+ const endpoint_type &_remote,
+ boost::asio::io_context &_io,
+ const std::shared_ptr<configuration> &_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<message_buffer_ptr_t, uint32_t> &_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 0000000..d4b27c3
--- /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 <map>
+#include <thread>
+#include <condition_variable>
+#include <memory>
+
+#include <boost/asio/ip/tcp.hpp>
+
+#include <vsomeip/defines.hpp>
+
+#include "buffer.hpp"
+#include "server_endpoint_impl.hpp"
+
+namespace vsomeip_v3 {
+
+using local_tcp_server_endpoint_base_impl = server_endpoint_impl<boost::asio::ip::tcp>;
+
+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>& _endpoint_host,
+ const std::shared_ptr<routing_host>& _routing_host,
+ const endpoint_type& _local,
+ boost::asio::io_context &_io,
+ const std::shared_ptr<configuration>& _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<endpoint_definition>,
+ const byte_t *_data, uint32_t _size);
+ bool send_error(const std::shared_ptr<endpoint_definition> _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<connection> {
+
+ public:
+ using ptr = std::shared_ptr<connection>;
+
+ static ptr create(const std::shared_ptr<local_tcp_server_endpoint_impl>& _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<std::mutex> 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<local_tcp_server_endpoint_impl>& _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<local_tcp_server_endpoint_impl> 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<client_t, connection::ptr>;
+ 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> &_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
index 3eae191..74ba316 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 <boost/asio/io_service.hpp>
#include <boost/asio/local/stream_protocol.hpp>
-#ifdef _WIN32
-#include <boost/asio/ip/tcp.hpp>
-#endif
-
#include <vsomeip/defines.hpp>
#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>& _endpoint_host,
- const std::shared_ptr<routing_host>& _routing_host,
- const endpoint_type& _remote,
- boost::asio::io_service &_io,
- const std::shared_ptr<configuration>& _configuration);
+using local_uds_client_endpoint_base_impl =
+ client_endpoint_impl<boost::asio::local::stream_protocol>;
- 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>& _endpoint_host,
+ const std::shared_ptr<routing_host>& _routing_host,
+ const endpoint_type& _remote,
+ boost::asio::io_context &_io,
+ const std::shared_ptr<configuration>& _configuration);
+ virtual ~local_uds_client_endpoint_impl();
void start();
void stop();
@@ -55,14 +42,12 @@ public:
// 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<byte_t>& _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<message_buffer_ptr_t, uint32_t> &_entry);
void send_magic_cookie();
@@ -85,4 +70,4 @@ private:
} // 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
index 8fbb619..256d866 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 <map>
#include <thread>
#include <condition_variable>
#include <memory>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/local/stream_protocol_ext.hpp>
-
-
-#ifdef _WIN32
-#include <boost/asio/ip/tcp.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/local/stream_protocol_ext.hpp>
+#else
+# include <boost/asio/local/stream_protocol.hpp>
#endif
#include <vsomeip/defines.hpp>
+#include <vsomeip/vsomeip_sec.h>
#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>& _endpoint_host,
- const std::shared_ptr<routing_host>& _routing_host,
- const endpoint_type& _local,
- boost::asio::io_service &_io,
- const std::shared_ptr<configuration>& _configuration,
- bool _is_routing_endpoint);
-
- local_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
- const std::shared_ptr<routing_host>& _routing_host,
- const endpoint_type& _local,
- boost::asio::io_service &_io,
- int native_socket,
- const std::shared_ptr<configuration>& _configuration,
- bool _is_routing_endpoint);
-
- virtual ~local_server_endpoint_impl();
+ local_uds_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
+ const std::shared_ptr<routing_host>& _routing_host,
+ const endpoint_type& _local,
+ boost::asio::io_context &_io,
+ const std::shared_ptr<configuration>& _configuration,
+ bool _is_routing_endpoint);
+
+ local_uds_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
+ const std::shared_ptr<routing_host>& _routing_host,
+ const endpoint_type& _local,
+ boost::asio::io_context &_io,
+ int native_socket,
+ const std::shared_ptr<configuration>& _configuration,
+ bool _is_routing_endpoint);
+
+ virtual ~local_uds_server_endpoint_impl();
void start();
void stop();
@@ -68,7 +64,7 @@ public:
const byte_t *_data, uint32_t _size);
bool send_error(const std::shared_ptr<endpoint_definition> _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 @@ private:
class connection: public std::enable_shared_from_this<connection> {
public:
- typedef std::shared_ptr<connection> ptr;
+ using ptr = std::shared_ptr<connection>;
- static ptr create(const std::shared_ptr<local_server_endpoint_impl>& _server,
+ static ptr create(const std::shared_ptr<local_uds_server_endpoint_impl>& _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<std::mutex> 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<local_server_endpoint_impl>& _server,
+ connection(const std::shared_ptr<local_uds_server_endpoint_impl>& _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<local_server_endpoint_impl> server_;
+ local_uds_server_endpoint_impl::socket_type socket_;
+ std::weak_ptr<local_uds_server_endpoint_impl> server_;
const std::uint32_t recv_buffer_size_initial_;
const std::uint32_t max_message_size_;
@@ -148,21 +147,20 @@ private:
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<client_t, connection::ptr> connections_t;
+ using connections_t = std::map<client_t, connection::ptr>;
std::mutex connections_mutex_;
connections_t connections_;
@@ -177,11 +175,11 @@ private:
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 @@ private:
} // 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 bb484b8..0a7c94e 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 <sys/socket.h>
#include <linux/netlink.h>
@@ -15,7 +15,6 @@
#include <map>
#include <mutex>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/basic_raw_socket.hpp>
#include <boost/asio/ip/address.hpp>
@@ -27,23 +26,23 @@ template <typename Protocol>
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<unsigned int>(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<unsigned int>(group);
- sockaddr.nl_pid = static_cast<unsigned int>(pid);
+ sockaddr.nl_pid = 0;
}
/// Copy constructor.
@@ -124,25 +123,31 @@ public:
return PF_NETLINK;
}
- typedef nl_endpoint<nl_protocol> endpoint;
- typedef boost::asio::basic_raw_socket<nl_protocol> socket;
+ using endpoint = nl_endpoint<nl_protocol>;
+ using socket = boost::asio::basic_raw_socket<nl_protocol>;
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<netlink_connector> {
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 @@ private:
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 dfa22e6..b7ee74d 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 <vector>
#include <boost/array.hpp>
-#include <boost/asio/io_service.hpp>
#include "buffer.hpp"
#include "endpoint_impl.hpp"
@@ -26,14 +25,33 @@ template<typename Protocol>
class server_endpoint_impl: public endpoint_impl<Protocol>,
public std::enable_shared_from_this<server_endpoint_impl<Protocol> > {
public:
- typedef typename Protocol::socket socket_type;
- typedef typename Protocol::endpoint endpoint_type;
- typedef typename std::map<endpoint_type, std::pair<size_t, std::deque<message_buffer_ptr_t>>> 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<train>()),
+ dispatch_timer_(std::make_shared<boost::asio::steady_timer>(_io)),
+ has_last_departure_(false),
+ queue_size_(0) {
+ }
+
+ std::shared_ptr<train> train_;
+ std::map<std::chrono::steady_clock::time_point,
+ std::deque<std::shared_ptr<train> > > dispatched_trains_;
+ std::shared_ptr<boost::asio::steady_timer> dispatch_timer_;
+ std::chrono::steady_clock::time_point last_departure_;
+ bool has_last_departure_;
+
+ std::deque<std::pair<message_buffer_ptr_t, uint32_t> > queue_;
+ std::size_t queue_size_;
+ };
+
+ using target_data_type = typename std::map<endpoint_type, endpoint_data_type>;
+ using target_data_iterator_type = typename target_data_type::iterator;
server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _configuration);
@@ -49,11 +67,10 @@ public:
bool send(const std::vector<byte_t>& _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>& _train);
+ bool flush(target_data_iterator_type _it);
size_t get_queue_size() const;
@@ -63,16 +80,15 @@ public:
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>& _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 @@ protected:
typename endpoint_impl<Protocol>::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>& _train,
- bool _queue_size_zero_on_entry);
- queue_iterator_type find_or_create_queue_unlocked(const endpoint_type& _target);
- std::shared_ptr<train> find_or_create_train_unlocked(const endpoint_type& _target);
+ bool queue_train(const target_data_iterator_type _it,
+ const std::shared_ptr<train> &_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<client_t,
- std::map<std::tuple<session_t, service_t, instance_t>, endpoint_type>
- > requests_;
+protected:
+ std::mutex clients_mutex_;
+ std::map<client_t, std::map<session_t, endpoint_type> > clients_;
- std::map<endpoint_type, std::shared_ptr<train>> trains_;
+ target_data_type targets_;
std::map<service_t, endpoint::prepare_stop_handler_t> prepare_stop_handlers_;
@@ -116,12 +129,18 @@ protected:
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>& _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 137571c..8a314bc 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<boost::asio::ip::tcp>;
class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl {
public:
@@ -26,7 +25,7 @@ public:
const std::shared_ptr<routing_host>& _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>& _configuration);
virtual ~tcp_client_endpoint_impl();
@@ -42,7 +41,7 @@ public:
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<message_buffer_ptr_t, uint32_t> &_entry);
void get_configured_times_from_endpoint(
service_t _service, method_t _method,
std::chrono::nanoseconds *_debouncing,
@@ -63,8 +62,8 @@ private:
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 bf0e1b9..1a2cf4e 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<boost::asio::ip::tcp>;
class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl {
@@ -29,7 +28,7 @@ public:
tcp_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _local,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _configuration);
virtual ~tcp_server_endpoint_impl();
@@ -40,14 +39,14 @@ public:
const byte_t *_data, uint32_t _size);
bool send_error(const std::shared_ptr<endpoint_definition> _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_definition>& _endpoint);
+ VSOMEIP_EXPORT bool is_established_to(const std::shared_ptr<endpoint_definition>& _endpoint);
bool get_default_target(service_t, endpoint_type &) const;
@@ -64,14 +63,17 @@ private:
class connection: public std::enable_shared_from_this<connection> {
public:
- typedef std::shared_ptr<connection> ptr;
+ using ptr = std::shared_ptr<connection>;
static ptr create(const std::weak_ptr<tcp_server_endpoint_impl>& _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<std::mutex> get_socket_lock();
@@ -79,11 +81,11 @@ private:
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 @@ private:
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 @@ private:
std::mutex acceptor_mutex_;
boost::asio::ip::tcp::acceptor acceptor_;
std::mutex connections_mutex_;
- typedef std::map<endpoint_type, connection::ptr> connections_t;
+ using connections_t = std::map<endpoint_type, connection::ptr>;
connections_t connections_;
const std::uint32_t buffer_shrink_threshold_;
const std::uint16_t local_port_;
@@ -145,7 +147,7 @@ private:
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 0e3a9d0..ec185b2 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<message_buffer_ptr_t> 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<message_buffer_ptr_t>;
const std::uint8_t TP_FLAG = 0x20;
@@ -49,9 +49,10 @@ public:
}
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 269a1f1..13aef2d 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 aaf61c5..5e50c8c 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 <mutex>
#include <memory>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <boost/asio/ip/address.hpp>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <vsomeip/primitive_types.hpp>
@@ -25,7 +30,7 @@ namespace tp {
class tp_reassembler : public std::enable_shared_from_this<tp_reassembler> {
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 3a3fdcb..56fcc20 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 <memory>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/ip/udp.hpp>
@@ -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<boost::asio::ip::udp>;
class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl {
@@ -32,7 +30,7 @@ public:
const std::shared_ptr<routing_host>& _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>& _configuration);
virtual ~udp_client_endpoint_impl();
@@ -48,10 +46,10 @@ public:
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<message_buffer_ptr_t, uint32_t> &_entry);
void get_configured_times_from_endpoint(
service_t _service, method_t _method,
std::chrono::nanoseconds *_debouncing,
@@ -59,8 +57,8 @@ private:
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 @@ private:
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::tp_reassembler> tp_reassembler_;
};
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
index fef09dc..dd7e224 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 <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
#include <boost/asio/ip/udp_ext.hpp>
-
-#include <atomic>
+#else
+#include <boost/asio/ip/udp.hpp>
+#endif
#include <vsomeip/defines.hpp>
@@ -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<boost::asio::ip::udp_ext>;
+#else
+using udp_server_endpoint_base_impl =
+ server_endpoint_impl<boost::asio::ip::udp>;
+#endif
class udp_server_endpoint_impl: public udp_server_endpoint_base_impl {
@@ -28,7 +33,7 @@ public:
udp_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _local,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _configuration);
virtual ~udp_server_endpoint_impl();
@@ -41,7 +46,7 @@ public:
const byte_t *_data, uint32_t _size);
bool send_error(const std::shared_ptr<endpoint_definition> _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 @@ public:
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 @@ private:
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<socket_type> multicast_socket_;
std::unique_ptr<endpoint_type> multicast_local_;
endpoint_type multicast_remote_;
@@ -110,6 +119,9 @@ private:
mutable std::mutex default_targets_mutex_;
std::map<service_t, endpoint_type> default_targets_;
+ boost::asio::ip::address netmask_;
+ unsigned short prefix_;
+
const std::uint16_t local_port_;
std::shared_ptr<tp::tp_reassembler> 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 0000000..71fad4d
--- /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 <iomanip>
+
+#include <boost/asio/ip/udp.hpp>
+
+#include <vsomeip/internal/logger.hpp>
+
+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<void(boost::system::error_code const &_error, std::size_t _size,
+ std::uint8_t, const boost::asio::ip::address &)>;
+
+ 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<size_t>(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 adf3972..98b3958 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 <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <vsomeip/primitive_types.hpp>
@@ -20,12 +25,12 @@ public:
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 @@ public:
void set_connected(bool _connected);
bool send(const byte_t *_data, uint32_t _size);
- bool send(const std::vector<byte_t>& _cmd_header, const byte_t *_data,
- uint32_t _size);
bool send_to(const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size);
bool send_error(const std::shared_ptr<endpoint_definition> _target,
@@ -61,7 +64,7 @@ public:
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 @@ private:
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 66b3138..6850f66 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<Protocol>::client_endpoint_impl(
const std::shared_ptr<routing_host>& _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>& _configuration)
@@ -41,7 +41,10 @@ client_endpoint_impl<Protocol>::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<train>()),
+ dispatch_timer_(_io),
+ has_last_departure_(false),
queue_size_(0),
was_not_connected_(false),
local_port_(0),
@@ -50,26 +53,31 @@ client_endpoint_impl<Protocol>::client_endpoint_impl(
template<typename Protocol>
client_endpoint_impl<Protocol>::~client_endpoint_impl() {
+
}
template<typename Protocol>
bool client_endpoint_impl<Protocol>::is_client() const {
+
return true;
}
template<typename Protocol>
bool client_endpoint_impl<Protocol>::is_established() const {
+
return state_ == cei_state_e::ESTABLISHED;
}
template<typename Protocol>
bool client_endpoint_impl<Protocol>::is_established_or_connected() const {
+
return (state_ == cei_state_e::ESTABLISHED
|| state_ == cei_state_e::CONNECTED);
}
template<typename Protocol>
void client_endpoint_impl<Protocol>::set_established(bool _established) {
+
if (_established) {
if (state_ != cei_state_e::CONNECTING) {
std::lock_guard<std::mutex> its_lock(socket_mutex_);
@@ -86,6 +94,7 @@ void client_endpoint_impl<Protocol>::set_established(bool _established) {
template<typename Protocol>
void client_endpoint_impl<Protocol>::set_connected(bool _connected) {
+
if (_connected) {
std::lock_guard<std::mutex> its_lock(socket_mutex_);
if (socket_->is_open()) {
@@ -100,7 +109,8 @@ void client_endpoint_impl<Protocol>::set_connected(bool _connected) {
template<typename Protocol>
void client_endpoint_impl<Protocol>::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<Protocol>::stop() {
}
template<typename Protocol>
-message_buffer_ptr_t client_endpoint_impl<Protocol>::get_front() {
- message_buffer_ptr_t its_buffer;
+std::pair<message_buffer_ptr_t, uint32_t>
+client_endpoint_impl<Protocol>::get_front() {
+
+ std::pair<message_buffer_ptr_t, uint32_t> its_entry;
if (queue_.size())
- its_buffer = queue_.front();
+ its_entry = queue_.front();
- return (its_buffer);
+ return (its_entry);
}
@@ -142,6 +154,7 @@ template<typename Protocol>
bool client_endpoint_impl<Protocol>::send_to(
const std::shared_ptr<endpoint_definition> _target, const byte_t *_data,
uint32_t _size) {
+
(void)_target;
(void)_data;
(void)_size;
@@ -154,6 +167,7 @@ template<typename Protocol>
bool client_endpoint_impl<Protocol>::send_error(
const std::shared_ptr<endpoint_definition> _target, const byte_t *_data,
uint32_t _size) {
+
(void)_target;
(void)_data;
(void)_size;
@@ -165,9 +179,11 @@ bool client_endpoint_impl<Protocol>::send_error(
template<typename Protocol>
bool client_endpoint_impl<Protocol>::send(const uint8_t *_data, uint32_t _size) {
+
std::lock_guard<std::mutex> 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<Protocol>::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<Protocol>::send(const uint8_t *_data, uint32_t _size)
// STEP 4: Check if the passenger enters an empty train
const std::pair<service_t, method_t> 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<Protocol>::max_message_size_) {
+ if (train_->buffer_->size() + _size > endpoint_impl<Protocol>::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<Protocol>::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>();
+ 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<Protocol>::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<typename Protocol>
void client_endpoint_impl<Protocol>::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<Protocol>::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<typename Protocol>
-void client_endpoint_impl<Protocol>::wait_until_debounce_time_reached() const {
- const std::chrono::nanoseconds time_since_last_departure =
- std::chrono::duration_cast<std::chrono::nanoseconds>(
- 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<Protocol>::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<typename Protocol>
@@ -363,24 +365,58 @@ bool client_endpoint_impl<Protocol>::send(const std::vector<byte_t>& _cmd_header
template<typename Protocol>
bool client_endpoint_impl<Protocol>::flush() {
- bool is_successful(true);
+
+ bool has_queued(true);
+ bool is_current_train(true);
+
std::lock_guard<std::mutex> 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<train> 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<typename Protocol>
void client_endpoint_impl<Protocol>::connect_cbk(
boost::system::error_code const &_error) {
+
+ if (_error != boost::asio::error::timed_out) {
+ std::lock_guard<std::mutex> its_lock(connecting_timer_mutex_);
+ connecting_timer_.cancel();
+ }
+
if (_error == boost::asio::error::operation_aborted
|| endpoint_impl<Protocol>::sending_blocked_) {
// endpoint was stopped
@@ -416,10 +452,10 @@ void client_endpoint_impl<Protocol>::connect_cbk(
if (was_not_connected_) {
was_not_connected_ = false;
std::lock_guard<std::mutex> 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<Protocol>::connect_cbk(
template<typename Protocol>
void client_endpoint_impl<Protocol>::wait_connect_cbk(
boost::system::error_code const &_error) {
+
if (!_error && !client_endpoint_impl<Protocol>::sending_blocked_) {
auto self = this->shared_from_this();
strand_.dispatch(std::bind(&client_endpoint_impl::connect,
@@ -443,18 +480,32 @@ void client_endpoint_impl<Protocol>::wait_connect_cbk(
}
template<typename Protocol>
+void client_endpoint_impl<Protocol>::wait_connecting_cbk(
+ boost::system::error_code const &_error) {
+ if (!_error && !client_endpoint_impl<Protocol>::sending_blocked_) {
+ connect_cbk(boost::asio::error::timed_out);
+ }
+}
+
+template<typename Protocol>
void client_endpoint_impl<Protocol>::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<std::mutex> 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<Protocol>::send_cbk(
template<typename Protocol>
void client_endpoint_impl<Protocol>::flush_cbk(
boost::system::error_code const &_error) {
+
if (!_error) {
(void) flush();
}
@@ -570,15 +622,17 @@ void client_endpoint_impl<Protocol>::flush_cbk(
template<typename Protocol>
void client_endpoint_impl<Protocol>::shutdown_and_close_socket(bool _recreate_socket) {
+
std::lock_guard<std::mutex> its_lock(socket_mutex_);
shutdown_and_close_socket_unlocked(_recreate_socket);
}
template<typename Protocol>
void client_endpoint_impl<Protocol>::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<Protocol>::shutdown_and_close_socket_unlocked(bool _re
socket_->close(its_error);
}
if (_recreate_socket) {
- socket_.reset(new socket_type(endpoint_impl<Protocol>::service_));
+ socket_.reset(new socket_type(endpoint_impl<Protocol>::io_));
}
}
template<typename Protocol>
bool client_endpoint_impl<Protocol>::get_remote_address(
boost::asio::ip::address &_address) const {
+
(void)_address;
return false;
}
template<typename Protocol>
std::uint16_t client_endpoint_impl<Protocol>::get_remote_port() const {
+
return 0;
}
template<typename Protocol>
std::uint16_t client_endpoint_impl<Protocol>::get_local_port() const {
+
return local_port_;
}
template<typename Protocol>
void client_endpoint_impl<Protocol>::set_local_port(uint16_t _port) {
+
local_port_ = _port;
}
template<typename Protocol>
void client_endpoint_impl<Protocol>::start_connect_timer() {
+
std::lock_guard<std::mutex> its_lock(connect_timer_mutex_);
connect_timer_.expires_from_now(
std::chrono::milliseconds(connect_timeout_));
@@ -627,8 +686,20 @@ void client_endpoint_impl<Protocol>::start_connect_timer() {
}
template<typename Protocol>
+void client_endpoint_impl<Protocol>::start_connecting_timer() {
+
+ std::lock_guard<std::mutex> its_lock(connecting_timer_mutex_);
+ connecting_timer_.expires_from_now(
+ std::chrono::milliseconds(connecting_timeout_));
+ connecting_timer_.async_wait(
+ std::bind(&client_endpoint_impl<Protocol>::wait_connecting_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+}
+
+template<typename Protocol>
typename endpoint_impl<Protocol>::cms_ret_e client_endpoint_impl<Protocol>::check_message_size(
const std::uint8_t * const _data, std::uint32_t _size) {
+
typename endpoint_impl<Protocol>::cms_ret_e ret(endpoint_impl<Protocol>::cms_ret_e::MSG_OK);
if (endpoint_impl<Protocol>::max_message_size_ != MESSAGE_SIZE_UNLIMITED
&& _size > endpoint_impl<Protocol>::max_message_size_) {
@@ -640,11 +711,20 @@ typename endpoint_impl<Protocol>::cms_ret_e client_endpoint_impl<Protocol>::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<Protocol>::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<Protocol>::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<Protocol>::max_message_size_ << " Bytes.";
ret = endpoint_impl<Protocol>::cms_ret_e::MSG_TOO_BIG;
@@ -654,6 +734,7 @@ typename endpoint_impl<Protocol>::cms_ret_e client_endpoint_impl<Protocol>::chec
template<typename Protocol>
bool client_endpoint_impl<Protocol>::check_queue_limit(const uint8_t *_data, std::uint32_t _size) const {
+
if (endpoint_impl<Protocol>::queue_limit_ != QUEUE_SIZE_UNLIMITED
&& queue_size_ + _size > endpoint_impl<Protocol>::queue_limit_) {
service_t its_service(0);
@@ -692,31 +773,84 @@ bool client_endpoint_impl<Protocol>::check_queue_limit(const uint8_t *_data, std
}
template<typename Protocol>
-void client_endpoint_impl<Protocol>::queue_train(bool _queue_size_zero_on_entry) {
- queue_.push_back(train_.buffer_);
- queue_size_ += train_.buffer_->size();
- train_.buffer_ = std::make_shared<message_buffer_t>();
+void client_endpoint_impl<Protocol>::queue_train(
+ const std::shared_ptr<train> &_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<typename Protocol>
size_t client_endpoint_impl<Protocol>::get_queue_size() const {
+
std::lock_guard<std::mutex> its_lock(mutex_);
return queue_size_;
}
+template<typename Protocol>
+void client_endpoint_impl<Protocol>::start_dispatch_timer(
+ const std::chrono::steady_clock::time_point &_now) {
+
+ // Choose the next train
+ std::shared_ptr<train> 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<std::chrono::nanoseconds>(
+ 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<Protocol>::flush_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+}
+
+template<typename Protocol>
+void client_endpoint_impl<Protocol>::cancel_dispatch_timer() {
+
+ boost::system::error_code ec;
+ dispatch_timer_.cancel(ec);
+}
+
+template<typename Protocol>
+void client_endpoint_impl<Protocol>::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<boost::asio::local::stream_protocol>;
#endif
template class client_endpoint_impl<boost::asio::ip::tcp>;
template class client_endpoint_impl<boost::asio::ip::udp>;
} // namespace vsomeip_v3
-
diff --git a/implementation/endpoints/src/credentials.cpp b/implementation/endpoints/src/credentials.cpp
index 3b9762c..70d8dcc 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 <cerrno>
+#include <cstring>
#include <sys/socket.h>
#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::received_t> 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<struct ucred*>(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 9547836..ff6ff7b 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 4bb2fc0..9835315 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 <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp>
-#include <boost/asio/ip/udp_ext.hpp>
#include <boost/asio/local/stream_protocol.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
#include <boost/asio/local/stream_protocol_ext.hpp>
+#include <boost/asio/ip/udp_ext.hpp>
+#endif
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
@@ -24,11 +26,11 @@ endpoint_impl<Protocol>::endpoint_impl(
const std::shared_ptr<endpoint_host>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _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<Protocol>::get_use_count() {
}
template<typename Protocol>
-void endpoint_impl<Protocol>::register_error_handler(error_handler_t _error_handler) {
+void endpoint_impl<Protocol>::register_error_handler(const error_handler_t &_error_handler) {
std::lock_guard<std::mutex> its_lock(error_handler_mutex_);
this->error_handler_ = _error_handler;
}
+template<typename Protocol>
+instance_t endpoint_impl<Protocol>::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<boost::asio::local::stream_protocol>;
+#if VSOMEIP_BOOST_VERSION < 106600
template class endpoint_impl<boost::asio::local::stream_protocol_ext>;
+template class endpoint_impl<boost::asio::ip::udp_ext>;
+#endif
#endif
template class endpoint_impl<boost::asio::ip::tcp>;
template class endpoint_impl<boost::asio::ip::udp>;
-template class endpoint_impl<boost::asio::ip::udp_ext>;
} // namespace vsomeip_v3
diff --git a/implementation/endpoints/src/endpoint_manager_base.cpp b/implementation/endpoints/src/endpoint_manager_base.cpp
index cfddc87..b8e18af 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 <iomanip>
namespace vsomeip_v3 {
-endpoint_manager_base::endpoint_manager_base(routing_manager_base* const _rm,
- boost::asio::io_service& _io,
- const std::shared_ptr<configuration>& _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>& _configuration)
+ : rm_(_rm),
+ io_(_io),
+ configuration_(_configuration),
+ local_port_(ILLEGAL_PORT) {
+ is_local_routing_ = configuration_->is_local_routing();
}
std::shared_ptr<endpoint> endpoint_manager_base::create_local(client_t _client) {
@@ -72,47 +80,81 @@ std::unordered_set<client_t> endpoint_manager_base::get_connected_clients() cons
return clients;
}
-std::shared_ptr<local_server_endpoint_impl> endpoint_manager_base::create_local_server(
- const std::shared_ptr<routing_host>& _routing_host) {
- std::shared_ptr<local_server_endpoint_impl> its_server_endpoint;
+std::shared_ptr<endpoint> endpoint_manager_base::create_local_server(
+ const std::shared_ptr<routing_host> &_routing_host) {
+ std::shared_ptr<endpoint> 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<local_server_endpoint_impl>(
- 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<local_uds_server_endpoint_impl>(
+ 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<std::mutex> its_lock(create_local_server_endpoint_mutex_);
+ ::unlink(its_path.str().c_str());
+ port_t its_port;
+ std::set<port_t> 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<local_tcp_server_endpoint_impl>(
+ 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> _endpoint) {
@@ -123,23 +165,27 @@ void endpoint_manager_base::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
rm_->on_disconnect(_endpoint);
}
-bool endpoint_manager_base::on_bind_error(std::shared_ptr<endpoint> _endpoint, uint16_t _remote_port) {
+bool endpoint_manager_base::on_bind_error(std::shared_ptr<endpoint> _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<client_t, std::shared_ptr<endpoint>>
endpoint_manager_base::get_local_endpoints() const {
std::lock_guard<std::mutex> 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> endpoint_manager_base::create_local_unlocked(client_t _client) {
+std::shared_ptr<endpoint>
+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<local_client_endpoint_impl> 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<endpoint> 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<local_client_endpoint_impl>(
+ its_endpoint = std::make_shared<local_uds_client_endpoint_impl>(
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<local_tcp_client_endpoint_impl>(
+ 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> endpoint_manager_base::find_local_unlocked(client_t _client) {
@@ -237,4 +317,43 @@ std::shared_ptr<endpoint> 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<port_t> &_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 dbb2107..a47234c 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 <vsomeip/internal/logger.hpp>
+#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>& _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<std::mutex> its_guard(options_mutex_);
+ is_processing_options_ = false;
+ options_condition_.notify_one();
+ }
+ options_thread_.join();
}
std::shared_ptr<endpoint> endpoint_manager_impl::find_or_create_remote_client(
@@ -266,9 +287,7 @@ std::shared_ptr<endpoint> 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<std::recursive_mutex> its_lock(endpoint_mutex_);
std::shared_ptr<endpoint_definition> 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<local_server_endpoint_impl>
-endpoint_manager_impl::create_local_server(
- bool* _is_socket_activated,
- const std::shared_ptr<routing_host>& _routing_host) {
- std::shared_ptr<local_server_endpoint_impl> its_endpoint;
+bool
+endpoint_manager_impl::create_routing_root(
+ std::shared_ptr<endpoint> &_root,
+ bool &_is_socket_activated,
+ const std::shared_ptr<routing_host> &_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 <local_uds_server_endpoint_impl>(
+ 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 <local_server_endpoint_impl>(
- 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 <local_uds_server_endpoint_impl>(
+ 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 <local_tcp_server_endpoint_impl>(
+ 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 <local_server_endpoint_impl>(
- 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 <local_tcp_server_endpoint_impl>(
+ 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> _endpoint) {
if (!is_reliable) {
static_cast<routing_manager_impl*>(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<routing_manager_impl*>(rm_)->service_endpoint_disconnected(
its_service.first, its_instance.first,
@@ -820,7 +900,9 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
}
}
-bool endpoint_manager_impl::on_bind_error(std::shared_ptr<endpoint> _endpoint, std::uint16_t _remote_port) {
+bool endpoint_manager_impl::on_bind_error(std::shared_ptr<endpoint> _endpoint,
+ const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) {
+
std::lock_guard<std::recursive_mutex> 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> _endpoint, s
uint16_t its_new_local_port(ILLEGAL_PORT);
std::unique_lock<std::mutex> 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<bool, std::set<port_t> > 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<bool, std::set<port_t> > &_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<std::mutex> 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<std::mutex> 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<endpoint>
@@ -946,6 +1063,8 @@ std::shared_ptr<endpoint> endpoint_manager_impl::create_remote_client(
std::shared_ptr<endpoint> its_endpoint;
std::shared_ptr<endpoint_definition> 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> 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> 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<std::mutex> its_lock(used_client_ports_mutex_);
- if (configuration_->get_client_port(_service, _instance, its_remote_port, _reliable,
- used_client_ports_, its_local_port)) {
- if(its_endpoint_def) {
+ std::map<bool, std::set<port_t> > its_used_client_ports;
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> its_guard(options_mutex_);
+ options_queue_.push(_option);
+ options_condition_.notify_one();
+}
+
+void
+endpoint_manager_impl::process_multicast_options() {
+
+ std::unique_lock<std::mutex> 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<udp_server_endpoint_impl>(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 0000000..e728827
--- /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 <iomanip>
+#include <sstream>
+
+#include <boost/asio/write.hpp>
+
+#include <vsomeip/defines.hpp>
+#include <vsomeip/internal/logger.hpp>
+
+#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> &_endpoint_host,
+ const std::shared_ptr<routing_host> &_routing_host,
+ const endpoint_type & _local,
+ const endpoint_type &_remote,
+ boost::asio::io_context &_io,
+ const std::shared_ptr<configuration> &_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<std::mutex> its_lock(mutex_);
+ sending_blocked_ = false;
+ queue_.clear();
+ queue_size_ = 0;
+ }
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> its_lock(mutex_);
+ sending_blocked_ = false;
+ }
+ connect();
+}
+
+void local_tcp_client_endpoint_impl::stop() {
+ {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ sending_blocked_ = true;
+ }
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<message_buffer_t>();
+ }
+ return ret;
+}
+
+void local_tcp_client_endpoint_impl::send_queued(std::pair<message_buffer_ptr_t, uint32_t> &_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<boost::asio::const_buffer> 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<std::mutex> 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<std::mutex> 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<length_t>(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<std::mutex> 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<message_buffer_t>();
+ }
+ 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<std::mutex> 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 0000000..e3132fc
--- /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 <deque>
+#include <iomanip>
+#include <sstream>
+
+#include <sys/types.h>
+#include <boost/asio/write.hpp>
+
+#include <vsomeip/internal/logger.hpp>
+
+#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>& _endpoint_host,
+ const std::shared_ptr<routing_host>& _routing_host,
+ const endpoint_type& _local, boost::asio::io_context &_io,
+ const std::shared_ptr<configuration>& _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<std::mutex> 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<local_tcp_server_endpoint_impl>(
+ shared_from_this()), max_message_size_,
+ buffer_shrink_threshold_,
+ io_);
+
+ {
+ std::unique_lock<std::mutex> 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<std::mutex> its_lock(acceptor_mutex_);
+ if (acceptor_.is_open()) {
+ boost::system::error_code its_error;
+ acceptor_.close(its_error);
+ }
+ }
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<message_buffer_t>();
+ 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<endpoint_definition> _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<endpoint_definition> _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> &_connection) {
+
+ bool ret = false;
+ std::lock_guard<std::mutex> 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<std::mutex> 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<boost::asio::steady_timer> its_timer =
+ std::make_shared<boost::asio::steady_timer>(io_,
+ std::chrono::milliseconds(1000));
+ auto its_ep = std::dynamic_pointer_cast<local_tcp_server_endpoint_impl>(
+ 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<local_tcp_server_endpoint_impl> &_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<local_tcp_server_endpoint_impl>& _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<std::uint32_t>(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<std::mutex>
+local_tcp_server_endpoint_impl::connection::get_socket_lock() {
+ return std::unique_lock<std::mutex>(socket_mutex_);
+}
+
+void local_tcp_server_endpoint_impl::connection::start() {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<local_tcp_server_endpoint_impl> 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<boost::asio::const_buffer> 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<std::mutex> 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<byte_t> 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<int>(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<local_tcp_server_endpoint_impl> its_server(server_.lock());
+ if (!its_server) {
+ VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk "
+ " couldn't lock server_";
+ return;
+ }
+ std::shared_ptr<routing_host> 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<std::mutex> 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<std::uint32_t>(
+ 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<size_t>(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<local_tcp_server_endpoint_impl> 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<std::mutex> its_lock(mutex_);
+ connections_t its_connections;
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<message_buffer_t>();
+ }
+ 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<byte_t> 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<int>(its_error) << ")";
+ return;
+ }
+
+ send(&its_buffer[0], static_cast<uint32_t>(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
index 04c7787..a69c3b8 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 <vsomeip/defines.hpp>
#include <vsomeip/internal/logger.hpp>
+#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>& _endpoint_host,
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _remote,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<message_buffer_t>();
}
return ret;
}
-void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
+void local_uds_client_endpoint_impl::send_queued(std::pair<message_buffer_ptr_t, uint32_t> &_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<boost::asio::const_buffer> 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<std::mutex> 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<message_buffer_t>();
+ 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<message_buffer_t>();
}
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<byte_t>& _cmd_header,
- const byte_t *_data, uint32_t _size) {
- std::lock_guard<std::mutex> 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<std::uint32_t>(
- _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
index ebf913f..8aa2139 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 <vsomeip/internal/logger.hpp>
+#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>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _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<mode_t>(_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>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _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<mode_t>(_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<std::mutex> its_lock(acceptor_mutex_);
if (acceptor_.is_open()) {
connection::ptr new_connection = connection::create(
- std::dynamic_pointer_cast<local_server_endpoint_impl>(
+ std::dynamic_pointer_cast<local_uds_server_endpoint_impl>(
shared_from_this()), max_message_size_,
buffer_shrink_threshold_,
- service_);
+ io_);
{
std::unique_lock<std::mutex> 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<std::mutex> 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<endpoint_definition> _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<endpoint_definition> _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> &_connection) {
+
bool ret = false;
std::lock_guard<std::mutex> 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<std::mutex> 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<boost::asio::steady_timer> its_timer =
- std::make_shared<boost::asio::steady_timer>(service_,
+ std::make_shared<boost::asio::steady_timer>(io_,
std::chrono::milliseconds(1000));
- auto its_ep = std::dynamic_pointer_cast<local_server_endpoint_impl>(
+ auto its_ep = std::dynamic_pointer_cast<local_uds_server_endpoint_impl>(
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<std::mutex> 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<routing_host> 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<routing_host> 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<local_server_endpoint_impl>& _server,
+local_uds_server_endpoint_impl::connection::connection(
+ const std::shared_ptr<local_uds_server_endpoint_impl>& _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<local_server_endpoint_impl>& _server,
+local_uds_server_endpoint_impl::connection::ptr
+local_uds_server_endpoint_impl::connection::create(
+ const std::shared_ptr<local_uds_server_endpoint_impl>& _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<std::uint32_t>(sizeof(instance_t) + sizeof(bool)
- + sizeof(bool));
+ boost::asio::io_context &_io) {
+ const std::uint32_t its_initial_buffer_size
+ = static_cast<std::uint32_t>(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<std::mutex>
-local_server_endpoint_impl::connection::get_socket_lock() {
+local_uds_server_endpoint_impl::connection::get_socket_lock() {
return std::unique_lock<std::mutex>(socket_mutex_);
}
-void local_server_endpoint_impl::connection::start() {
+void local_uds_server_endpoint_impl::connection::start() {
std::lock_guard<std::mutex> 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<uint32_t>::max(),
+ std::numeric_limits<uint32_t>::max(),
+ std::numeric_limits<size_t>::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<std::mutex> 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<local_server_endpoint_impl> its_server(server_.lock());
+
+ std::shared_ptr<local_uds_server_endpoint_impl> 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<byte_t> its_data(_data, _data + _size);
- if (its_name_length > 0)
- its_name.assign(reinterpret_cast<const char *>(
- &_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<int>(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<local_server_endpoint_impl> its_server(server_.lock());
+ std::shared_ptr<local_uds_server_endpoint_impl> 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<routing_host> its_host = its_server->routing_host_.lock();
if (!its_host)
return;
+ std::shared_ptr<vsomeip_v3::configuration> 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<std::uint32_t>(recv_buffer_size_);
+ // minimal amount of data needed to read out command size = header + tag size
+ missing_capacity_ = static_cast<std::uint32_t>(
+ 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<local_server_endpoint_impl> its_server = server_.lock();
+ std::shared_ptr<local_uds_server_endpoint_impl> 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<std::mutex> its_lock(mutex_);
connections_t its_connections;
{
std::lock_guard<std::mutex> 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<message_buffer_t>();
}
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<byte_t> 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<int>(its_error) << ")";
+ return;
+ }
+
+ send(&its_buffer[0], static_cast<uint32_t>(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 ebd432d..be5a103 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 <thread>
@@ -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<int>(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<unsigned int>(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<std::mutex> 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 ddf6b25..0d06537 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 <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
-#include <boost/asio/ip/udp_ext.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
#include <boost/asio/local/stream_protocol_ext.hpp>
+#include <boost/asio/ip/udp_ext.hpp>
+#else
+#include <boost/asio/local/stream_protocol.hpp>
+#include <boost/asio/ip/udp.hpp>
+#endif
#include <vsomeip/defines.hpp>
#include <vsomeip/internal/logger.hpp>
@@ -30,69 +35,73 @@ template<typename Protocol>
server_endpoint_impl<Protocol>::server_endpoint_impl(
const std::shared_ptr<endpoint_host>& _endpoint_host,
const std::shared_ptr<routing_host>& _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>& _configuration)
: endpoint_impl<Protocol>(_endpoint_host, _routing_host, _local, _io, _max_message_size,
_queue_limit, _configuration),
sent_timer_(_io) {
+
is_sending_ = false;
}
template<typename Protocol>
server_endpoint_impl<Protocol>::~server_endpoint_impl() {
+
}
template<typename Protocol>
void server_endpoint_impl<Protocol>::prepare_stop(
- endpoint::prepare_stop_handler_t _handler, service_t _service) {
+ const endpoint::prepare_stop_handler_t &_handler, service_t _service) {
+
std::lock_guard<std::mutex> its_lock(mutex_);
bool queued_train(false);
+ std::vector<target_data_iterator_type> its_erased;
+ boost::system::error_code ec;
+
if (_service == ANY_SERVICE) { // endpoint is shutting down completely
endpoint_impl<Protocol>::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<Protocol>::service_.post([ptr, _handler, _service](){
+ endpoint_impl<Protocol>::io_.post([ptr, _handler, _service](){
_handler(ptr, _service);
});
} else {
@@ -101,11 +110,11 @@ void server_endpoint_impl<Protocol>::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<Protocol>::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<Protocol>::service_.post([ptr, _handler, _service](){
+ endpoint_impl<Protocol>::io_.post([ptr, _handler, _service](){
_handler(ptr, _service);
});
}
@@ -170,7 +179,7 @@ template<typename Protocol>bool server_endpoint_impl<Protocol>::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 @@ template<typename Protocol>bool server_endpoint_impl<Protocol>::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<Protocol>::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<Protocol>::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<train> 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<Protocol>::send_intern(
}
// STEP 4: Check if the passenger enters an empty train
- const std::pair<service_t, method_t> its_identifier = std::make_pair(
- its_service, its_method);
- if (target_train->passengers_.empty()) {
- target_train->departure_ = its_retention;
+ const std::pair<service_t, method_t> 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<Protocol>::max_message_size_) {
+ if (its_data.train_->buffer_->size() + _size > endpoint_impl<Protocol>::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<Protocol>::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<train>();
+ 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<Protocol>::flush_cbk,
- this->shared_from_this(), _target,
- target_train, std::placeholders::_1));
+ start_dispatch_timer(its_target_iterator, its_now);
return (true);
}
template<typename Protocol>
void server_endpoint_impl<Protocol>::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<train> 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<Protocol>::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<typename Protocol>
-void server_endpoint_impl<Protocol>::wait_until_debounce_time_reached(
- const std::shared_ptr<train>& _train) const {
- const std::chrono::nanoseconds time_since_last_departure =
- std::chrono::duration_cast<std::chrono::nanoseconds>(
- 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<Protocol>::target_data_iterator_type
+server_endpoint_impl<Protocol>::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<typename Protocol>
+void server_endpoint_impl<Protocol>::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 Protocol>
typename endpoint_impl<Protocol>::cms_ret_e server_endpoint_impl<Protocol>::check_message_size(
@@ -469,11 +476,21 @@ typename endpoint_impl<Protocol>::cms_ret_e server_endpoint_impl<Protocol>::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<Protocol>::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<Protocol>::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<Protocol>::max_message_size_ << " Bytes.";
ret = endpoint_impl<Protocol>::cms_ret_e::MSG_TOO_BIG;
@@ -523,72 +540,67 @@ bool server_endpoint_impl<Protocol>::check_queue_limit(const uint8_t *_data, std
}
template<typename Protocol>
-void server_endpoint_impl<Protocol>::queue_train(
- const queue_iterator_type _queue_iterator,
- const std::shared_ptr<train>& _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<message_buffer_t>();
- _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<Protocol>::queue_train(
+ target_data_iterator_type _it, const std::shared_ptr<train> &_train,
+ bool _queue_size_zero_on_entry) {
-template<typename Protocol>
-typename server_endpoint_impl<Protocol>::queue_iterator_type
-server_endpoint_impl<Protocol>::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<message_buffer_ptr_t>())
- ));
- }
- return target_queue_iterator;
-}
+ bool must_erase(false);
-template<typename Protocol>
-std::shared_ptr<train> server_endpoint_impl<Protocol>::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<train>(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<typename Protocol>
-bool server_endpoint_impl<Protocol>::flush(
- endpoint_type _target,
- const std::shared_ptr<train>& _train) {
+bool server_endpoint_impl<Protocol>::flush(target_data_iterator_type _it) {
+
+ bool has_queued(true);
+ bool is_current_train(true);
+ auto &its_data = _it->second;
+
std::lock_guard<std::mutex> 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<typename Protocol>
@@ -599,7 +611,7 @@ void server_endpoint_impl<Protocol>::connect_cbk(
template<typename Protocol>
void server_endpoint_impl<Protocol>::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<Protocol>::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<Protocol>::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<Protocol>::
- #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<Protocol>::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<endpoint_type,std::pair<size_t, std::deque<message_buffer_ptr_t>>>& 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<Protocol>::
- #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<Protocol>::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<Protocol>::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<Protocol>::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<Protocol>::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<Protocol>::sending_blocked_) {
// endpoint is shutting down completely, ensure to call
@@ -751,32 +762,92 @@ void server_endpoint_impl<Protocol>::send_cbk(
template<typename Protocol>
void server_endpoint_impl<Protocol>::flush_cbk(
- endpoint_type _target,
- const std::shared_ptr<train>& _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<typename Protocol>
size_t server_endpoint_impl<Protocol>::get_queue_size() const {
size_t its_queue_size(0);
-
{
std::lock_guard<std::mutex> 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<typename Protocol>
+void server_endpoint_impl<Protocol>::start_dispatch_timer(
+ target_data_iterator_type _it,
+ const std::chrono::steady_clock::time_point &_now) {
+
+ auto &its_data = _it->second;
+ std::shared_ptr<train> 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<std::chrono::nanoseconds>(
+ 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<Protocol>::flush_cbk,
+ this->shared_from_this(), _it, std::placeholders::_1));
+}
+
+template<typename Protocol>
+void server_endpoint_impl<Protocol>::cancel_dispatch_timer(
+ target_data_iterator_type _it) {
+
+ boost::system::error_code ec;
+ _it->second.dispatch_timer_->cancel(ec);
+}
+
+template<typename Protocol>
+void server_endpoint_impl<Protocol>::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<boost::asio::local::stream_protocol_ext>;
+template class server_endpoint_impl<boost::asio::ip::udp_ext>;
+#else
+template class server_endpoint_impl<boost::asio::local::stream_protocol>;
+template class server_endpoint_impl<boost::asio::ip::udp>;
+#endif
#endif
template class server_endpoint_impl<boost::asio::ip::tcp>;
-template class server_endpoint_impl<boost::asio::ip::udp_ext>;
} // namespace vsomeip_v3
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
index f88d2a2..588d252 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>& _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>& _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::chrono::milliseconds>(
+ std::int64_t its_connect_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
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<std::mutex> 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<std::mutex> 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<endpoint_host> 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<message_buffer_ptr_t, uint32_t> &_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<std::chrono::milliseconds>(
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<tcp_client_endpoint_impl>(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<std::mutex> 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 37db3f5..f23e9be 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>& _endpoint_host,
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _local,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _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<tcp_server_endpoint_impl>(
shared_from_this()), max_message_size_,
buffer_shrink_threshold_, has_enabled_magic_cookies_,
- service_, send_timeout_);
+ io_, send_timeout_);
{
std::unique_lock<std::mutex> 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<std::mutex> 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<message_buffer_t>(_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<message_buffer_t>(_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<std::mutex> 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<std::uint16_t>(_queue_iterator->first.port())
+ << _it->first.address().to_string() << ":" << std::dec
+ << static_cast<std::uint16_t>(_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<service_t> 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_definition>& _endpoint) {
+bool tcp_server_endpoint_impl::is_established_to(const std::shared_ptr<endpoint_definition>& _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<boost::asio::steady_timer> its_timer =
- std::make_shared<boost::asio::steady_timer>(service_,
+ std::make_shared<boost::asio::steady_timer>(io_,
std::chrono::milliseconds(1000));
auto its_ep = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
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<tcp_server_endpoint_impl>& _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<std::mutex> 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<tcp_server_endpoint_impl> 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<std::mutex> 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<message_type_e>(
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<std::mutex> 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 0a2578d..f5a2f45 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 <arpa/inet.h>
#else
#include <Winsock2.h>
@@ -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<message_buffer_t>();
- 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<length_t>(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 57696ca..6961511 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 <arpa/inet.h>
#else
#include <Winsock2.h>
diff --git a/implementation/endpoints/src/tp_reassembler.cpp b/implementation/endpoints/src/tp_reassembler.cpp
index 07a31e0..49e5731 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 3b9a212..5d675f6 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 <iomanip>
#include <sstream>
+#include <thread>
#include <boost/asio/ip/multicast.hpp>
#include <vsomeip/internal/logger.hpp>
@@ -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>& _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>& _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<std::mutex> 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<endpoint_host> 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<message_buffer_ptr_t, uint32_t> &_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<std::mutex> 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::microseconds>(
+ 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<std::uint32_t>(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<std::mutex> 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 bd44b48..79dee1c 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 <iomanip>
#include <sstream>
+#include <thread>
#include <boost/asio/ip/multicast.hpp>
+#if VSOMEIP_BOOST_VERSION >= 106600
+#include <boost/asio/ip/network_v4.hpp>
+#include <boost/asio/ip/network_v6.hpp>
+#endif
#include <vsomeip/constants.hpp>
#include <vsomeip/internal/logger.hpp>
@@ -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>& _endpoint_host,
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _local,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _configuration) :
- server_endpoint_impl<ip::udp_ext>(_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<ip::udp>(
+#else
+ server_endpoint_impl<ip::udp_ext>(
+#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<tp::tp_reassembler>(_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<unsigned int>(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<std::mutex> 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<size_t>::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<std::mutex> 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<message_buffer_t>(_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<message_buffer_t>(_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<std::mutex> 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::microseconds>(
+ 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<std::mutex> 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<endpoint_type>(
- new endpoint_type(boost::asio::ip::address_v4::any(), local_port_));
- }
- if (is_v6) {
- multicast_local_ = std::unique_ptr<endpoint_type>(
- new endpoint_type(boost::asio::ip::address_v6::any(), local_port_));
- }
- }
-
- if (!multicast_socket_) {
- multicast_socket_ = std::unique_ptr<socket_type>(
- 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<multicast>: 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<multicast>: "
- << "SO_RCVBUFFORCE: successful.";
- }
- multicast_socket_->get_option(its_option, ec);
- }
- #endif
- if (ec) {
- VSOMEIP_WARNING << "udp_server_endpoint_impl<multicast>: couldn't get "
- << "SO_RCVBUF: " << ec.message() << " local port:"
- << std::dec << local_port_;
- } else {
- VSOMEIP_INFO << "udp_server_endpoint_impl<multicast>: 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<routing_host> 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<return_code_e>(_buffer[i + VSOMEIP_RETURN_CODE_POS])) ||*/
+ !utility::is_valid_return_code(static_cast<return_code_e>(_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<std::mutex> 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<std::mutex> 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<std::mutex> its_client_lock(clients_mutex_);
+ clients_[its_client][its_session] = _remote;
}
}
its_host->on_message(&res.second[0],
static_cast<std::uint32_t>(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<std::mutex> 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<std::mutex> 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<std::mutex> its_guard(multicast_mutex_);
+
+ multicast_socket_ = std::unique_ptr<socket_type>(
+ 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<endpoint_type>(
+ new endpoint_type(boost::asio::ip::address_v4::any(), local_port_));
+ } else { // is_v6
+ multicast_local_ = std::unique_ptr<endpoint_type>(
+ 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<multicast>: 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<multicast>: "
+ << "SO_RCVBUFFORCE: successful.";
+ }
+ multicast_socket_->get_option(its_option, ec);
+ }
+#endif
+ if (ec) {
+ VSOMEIP_WARNING << "udp_server_endpoint_impl<multicast>: couldn't get "
+ << "SO_RCVBUF: " << ec.message() << " local port:"
+ << std::dec << local_port_;
+ } else {
+ VSOMEIP_INFO << "udp_server_endpoint_impl<multicast>: 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<std::mutex> 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<unsigned int>(local_.address().to_v6().scope_id()));
+ }
+ }
+ multicast_socket_->set_option(its_join_option, ec);
+
+ if (!ec) {
+ std::lock_guard<std::mutex> 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<std::mutex> 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 5c8981c..e4441a9 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<byte_t>& _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<endpoint_definition> _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 2820f81..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/basic_socket_ext.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#include <boost/asio/detail/datagram_socket_service_ext.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service_ext<Protocol>)>
-class basic_datagram_socket_ext
- : public basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>
-{
-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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(
- 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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>::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 <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_datagram_socket_ext(
- basic_datagram_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(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 Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_datagram_socket_ext>::type& operator=(
- basic_datagram_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
- {
- basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)> 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)> 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)> 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 92d71e3..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/socket_acceptor_service_ext.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::null_socket_service<Protocol>
-# elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
-# else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local<Protocol>
-# endif
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
-class basic_socket_acceptor_ext
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- 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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<Protocol> 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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-
- // All socket acceptors have access to each other's implementations.
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- 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 <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_socket_acceptor_ext(
- basic_socket_acceptor_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<BOOST_ASIO_SVC_T>(
- 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 Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_socket_acceptor_ext>::type& operator=(
- basic_socket_acceptor_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
- {
- basic_socket_acceptor_ext tmp(std::move(other));
- basic_io_object<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename WaitHandler>
- 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<WaitHandler,
- void (boost::system::error_code)> 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 <typename Protocol1, typename SocketService>
- void accept(basic_socket_ext_local<Protocol1, SocketService>& peer,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1>
- void accept(basic_socket_ext_local<Protocol1>& peer,
- typename enable_if<is_convertible<Protocol, Protocol1>::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<endpoint_type*>(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 <typename Protocol1, typename SocketService>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<Protocol1, SocketService>& peer,
- boost::system::error_code& ec,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<Protocol1>& peer, boost::system::error_code& ec,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- {
- this->get_service().accept(this->get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename SocketService, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<Protocol1, SocketService>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<Protocol1>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<is_convertible<Protocol, Protocol1>::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<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<AcceptHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename SocketService>
- void accept(basic_socket_ext_local<protocol_type, SocketService>& peer,
- endpoint_type& peer_endpoint)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- void accept(basic_socket_ext_local<protocol_type>& 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 <typename SocketService>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<protocol_type, SocketService>& 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<protocol_type>& 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 <typename SocketService, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<protocol_type, SocketService>& peer,
- endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<protocol_type>& 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<AcceptHandler,
- void (boost::system::error_code)> 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 <typename MoveAcceptHandler>
- 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<boost::asio::io_context*>(0),
- static_cast<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(
- this->get_implementation(), static_cast<boost::asio::io_context*>(0),
- static_cast<endpoint_type*>(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<endpoint_type*>(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<endpoint_type*>(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 <typename MoveAcceptHandler>
- 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<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- &io_context, static_cast<endpoint_type*>(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<boost::asio::io_context*>(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<boost::asio::io_context*>(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 <typename MoveAcceptHandler>
- 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<boost::asio::io_context*>(0), &peer_endpoint,
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- static_cast<boost::asio::io_context*>(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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 cdf4029..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_ssocket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
-# elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
-# else
-# include <boost/asio/detail/reactive_socket_service_ext.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext<Protocol>
-# endif
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol BOOST_ASIO_SVC_TPARAM>
-class basic_socket_ext
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- 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<Protocol BOOST_ASIO_SVC_TARG> 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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-
- // All sockets have access to each other's implementations.
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- 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 <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_socket_ext(basic_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<BOOST_ASIO_SVC_T>(
- 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 Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_socket_ext>::type& operator=(
- basic_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
- {
- basic_socket_ext tmp(std::move(other));
- basic_io_object<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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 <typename ConnectHandler>
- 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<ConnectHandler,
- void (boost::system::error_code)> 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<ConnectHandler,
- void (boost::system::error_code)> 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler,
- void (boost::system::error_code)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e13154c..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_ssocket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
-# elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
-# else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local<Protocol>
-# endif
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol BOOST_ASIO_SVC_TPARAM>
-class basic_socket_ext_local
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- 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<Protocol BOOST_ASIO_SVC_TARG> 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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>(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<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-
- // All sockets have access to each other's implementations.
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- 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 <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_socket_ext_local(basic_socket_ext_local<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<BOOST_ASIO_SVC_T>(
- 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 Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_socket_ext_local>::type& operator=(
- basic_socket_ext_local<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
- {
- basic_socket_ext_local tmp(std::move(other));
- basic_io_object<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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<BOOST_ASIO_SVC_T>::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 <typename ConnectHandler>
- 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<ConnectHandler,
- void (boost::system::error_code)> 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<ConnectHandler,
- void (boost::system::error_code)> 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler,
- void (boost::system::error_code)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 99d29c3..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/stream_socket_service_ext.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service_ext<Protocol>)>
-class basic_stream_socket_ext
- : public basic_socket_ext_local<Protocol BOOST_ASIO_SVC_TARG>
-{
-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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>(
- 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<Protocol BOOST_ASIO_SVC_TARG>(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<Protocol BOOST_ASIO_SVC_TARG>::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 <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_stream_socket_ext(
- basic_stream_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket_ext_local<Protocol BOOST_ASIO_SVC_TARG>(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 Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_stream_socket_ext>::type& operator=(
- basic_stream_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
- {
- basic_socket_ext_local<Protocol BOOST_ASIO_SVC_TARG>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)> 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)> 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 89f1594..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-char (&three_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const boost::asio::ip::address*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const boost::asio::ip::address>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e12b1ca..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
- static_assert(expr, msg);
-
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-char (&four_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const std::uint32_t*>(0), \
- static_cast<const std::uint32_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 6219e1f..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 02a628b..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 4849766..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 2a066b8..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<DWORD>(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<int>(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<DWORD>(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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 4f78284..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
-class reactive_socket_recv_op_ext :
- public reactive_socket_recv_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(socket, state,
- buffers, flags, &reactive_socket_recv_op_ext::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recv_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 994a495..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
-class reactive_socket_recv_op_ext_local :
- public reactive_socket_recv_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(socket, state,
- buffers, flags, &reactive_socket_recv_op_ext_local::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recv_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 969e8ab..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint, typename Handler>
-class reactive_socket_recvfrom_op_ext :
- public reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- socket, protocol_type, buffers, endpoint, flags,
- &reactive_socket_recvfrom_op_ext::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recvfrom_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 a8a2af7..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint, typename Handler>
-class reactive_socket_recvfrom_op_ext_local :
- public reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- socket, protocol_type, buffers, endpoint, flags,
- &reactive_socket_recvfrom_op_ext_local::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recvfrom_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 0efd6c3..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
-class reactive_socket_recvmsg_op_ext :
- public reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(socket, buffers,
- in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recvmsg_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 c992283..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
-class reactive_socket_recvmsg_op_ext_local :
- public reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(socket, buffers,
- in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
- {
- handler_work<Handler>::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<reactive_socket_recvmsg_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 b6a80bd..0000000
--- 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 <iostream>
-
-#include <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler>
- 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<Handler> 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler>
- 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<ConstBufferSequence, Handler> 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence, Handler> 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence, Handler> 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 <typename Handler>
- 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<Handler> 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext.ipp>
-#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 e233574..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler>
- 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<Handler> 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler>
- 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<ConstBufferSequence, Handler> 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence, Handler> 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence, Handler> 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 <typename Handler>
- 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<Handler> 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp>
-#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 761f2bb..0000000
--- 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 <iostream>
-
-#include <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext :
- public service_base<reactive_socket_service_ext<Protocol> >,
- 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<reactive_socket_service_ext<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext<Protocol>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler>
- 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<ConstBufferSequence,
- endpoint_type, Handler> 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 <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence,
- endpoint_type, Handler> 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 <typename Handler>
- 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<Handler> 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 <typename Socket>
- 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 <typename Socket, typename Handler>
- 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<Socket, Protocol, Handler> 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 <typename Handler>
- 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<Protocol, Handler> 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 <typename Handler>
- 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<Handler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 a946851..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext_local :
- public service_base<reactive_socket_service_ext_local<Protocol> >,
- 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<reactive_socket_service_ext_local<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext_local<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler>
- 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<ConstBufferSequence,
- endpoint_type, Handler> 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 <typename Handler>
- 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<Handler> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler>
- 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<MutableBufferSequence,
- endpoint_type, Handler> 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 <typename Handler>
- 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<Handler> 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 <typename Socket>
- 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 <typename Socket, typename Handler>
- 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<Socket, Protocol, Handler> 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 <typename Handler>
- 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<Protocol, Handler> 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 <typename Handler>
- 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<Handler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 04c2c70..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 3a27272..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 <boost/asio/detail/pop_options.hpp>
-
-#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 cc28d9c..0000000
--- 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 <boost/asio/detail/socket_ops.hpp>
-
-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 <boost/asio/detail/impl/socket_ops_ext.ipp>
-#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 e08a643..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/socket_ops_ext_local.ipp>
-#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 6ce2ac4..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_datagram_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/ip/basic_endpoint.hpp>
-#include <boost/asio/ip/basic_resolver.hpp>
-#include <boost/asio/ip/basic_resolver_iterator.hpp>
-#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/ip/udp.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<udp> 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<udp> socket;
-
- /// The UDP resolver type.
- typedef basic_resolver<udp> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 6ccd0ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <boost/asio/basic_socket_acceptor_ext.hpp>
-#include <boost/asio/basic_socket_iostream.hpp>
-#include <boost/asio/basic_stream_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<stream_protocol_ext> endpoint;
-
- /// The UNIX domain socket type.
- typedef basic_stream_socket_ext<stream_protocol_ext> socket;
-
- /// The UNIX domain acceptor type.
- typedef basic_socket_acceptor_ext<stream_protocol_ext> acceptor;
-
-#if !defined(BOOST_ASIO_NO_IOSTREAM)
- /// The UNIX domain iostream type.
- typedef basic_socket_iostream<stream_protocol_ext> iostream;
-#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
-};
-
-} // namespace local
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 ff5c5f8..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_ssocket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a stream socket.
-template <typename Protocol>
-class stream_socket_service_ext
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<stream_socket_service_ext<Protocol> >
-#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<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service_ext_local<Protocol> 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<Protocol> >(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 <typename Protocol1> friend class stream_socket_service_ext;
-
- /// Move-construct a new stream socket implementation from another protocol
- /// type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- stream_socket_service_ext<Protocol1>& other_service,
- typename stream_socket_service_ext<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- 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 <typename ConnectHandler>
- 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<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename WaitHandler>
- 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<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send the given data to the peer.
- template <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive some data from the peer.
- template <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t)> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 58a553f..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/basic_socket_ext.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_datagram_socket_ext
- : public basic_socket_ext<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_datagram_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket_ext<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_datagram_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_datagram_socket_ext(basic_datagram_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_datagram_socket_ext&
- >::type operator=(basic_datagram_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- initiate_async_receive_from(), handler,
- this, buffers, &sender_endpoint, flags);
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e3e2966..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename ExecutionContext>
- explicit basic_socket_acceptor_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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<Protocol> 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<Protocol> 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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const endpoint_type& endpoint, bool reuse_addr = true,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_acceptor,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_acceptor_ext(basic_socket_acceptor_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_acceptor_ext&
- >::type operator=(basic_socket_acceptor_ext<Protocol1, Executor1>&& 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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 <typename Protocol1, typename Executor1>
- void accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<Protocol1, Executor1>& peer, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- initiate_async_accept(), handler, this,
- &peer, static_cast<endpoint_type*>(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 <typename Executor1>
- void accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
- endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- 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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), &peer_endpoint,
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, endpoint_type& peer_endpoint,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, endpoint_type& peer_endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const executor_type& ex,
- endpoint_type& peer_endpoint, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- 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<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename WaitHandler>
- 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<WaitHandler> 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 <typename AcceptHandler, typename Protocol1, typename Executor1>
- void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- basic_socket_acceptor_ext* self, basic_socket_ext_local<Protocol1, Executor1>* 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<AcceptHandler> 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 <typename MoveAcceptHandler, typename Executor1, typename Socket>
- 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<MoveAcceptHandler> 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, Executor> impl_;
-#endif
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 523f97a..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext(basic_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext&
- >::type operator=(basic_socket_ext<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 855d01c..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext_local<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext_local(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext_local(basic_socket_ext_local<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext_local&
- >::type operator=(basic_socket_ext_local<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 325157a..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_stream_socket_ext
- : public basic_socket_ext_local<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_stream_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_stream_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_stream_socket_ext(basic_stream_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_stream_socket_ext&
- >::type operator=(basic_stream_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext_local<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- initiate_async_receive(), handler, this,
- buffers, socket_base::message_flags(0));
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 67fe6bd..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-char (&three_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const boost::asio::ip::address*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const boost::asio::ip::address>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 65640ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-char (&four_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const std::uint32_t*>(0), \
- static_cast<const std::uint32_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 04036ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext::reactive_socket_service_base_ext(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 288cf19..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 a4546ca..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 5050f24..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<DWORD>(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<int>(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<DWORD>(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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 da8cd83..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext :
- public reactive_socket_recv_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(socket, state,
- buffers, flags, &reactive_socket_recv_op_ext::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
- io_executor_(io_ex)
- {
- handler_work<Handler, IoExecutor>::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<reactive_socket_recv_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 ce5ca28..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext_local :
- public reactive_socket_recv_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<Handler, IoExecutor>::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<reactive_socket_recv_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 6cc2443..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext :
- public reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<Handler, IoExecutor>::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<reactive_socket_recvfrom_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 81485ff..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext_local :
- public reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<Handler, IoExecutor>::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<reactive_socket_recvfrom_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 cd02730..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext :
- public reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<Handler, IoExecutor>::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<reactive_socket_recvmsg_op_ext*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 059cddb..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext_local :
- public reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<Handler, IoExecutor>::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<reactive_socket_recvmsg_op_ext_local*>(base));
- ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler, IoExecutor> 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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 <boost/asio/detail/pop_options.hpp>
-
-#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 3fc3a5a..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext.ipp>
-#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 8c5503f..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp>
-#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 1eae357..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext :
- public execution_context_service_base<reactive_socket_service_ext<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e55cfb1..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext_local :
- public execution_context_service_base<reactive_socket_service_ext_local<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext_local<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<Handler, IoExecutor> 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 b267cf6..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 cd81ffb..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 9285fed..0000000
--- 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 <boost/asio/detail/socket_ops.hpp>
-
-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 <boost/asio/detail/impl/socket_ops_ext.ipp>
-#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 f494d79..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/socket_ops_ext_local.ipp>
-#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 6ce2ac4..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_datagram_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/ip/basic_endpoint.hpp>
-#include <boost/asio/ip/basic_resolver.hpp>
-#include <boost/asio/ip/basic_resolver_iterator.hpp>
-#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/ip/udp.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<udp> 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<udp> socket;
-
- /// The UDP resolver type.
- typedef basic_resolver<udp> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 7c57c62..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <boost/asio/basic_socket_acceptor_ext.hpp>
-#include <boost/asio/basic_socket_iostream.hpp>
-#include <boost/asio/basic_stream_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<stream_protocol_ext> endpoint;
-
- /// The UNIX domain socket type.
- typedef basic_stream_socket_ext<stream_protocol_ext> socket;
-
- /// The UNIX domain acceptor type.
- typedef basic_socket_acceptor_ext<stream_protocol_ext> acceptor;
-
-#if !defined(BOOST_ASIO_NO_IOSTREAM)
- /// The UNIX domain iostream type.
- typedef basic_socket_iostream<stream_protocol_ext> iostream;
-#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
-};
-
-} // namespace local
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 49a4950..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/basic_socket_ext.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_datagram_socket_ext
- : public basic_socket_ext<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_datagram_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket_ext<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_datagram_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_datagram_socket_ext(basic_datagram_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_datagram_socket_ext&
- >::type operator=(basic_datagram_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- initiate_async_receive_from(), handler,
- this, buffers, &sender_endpoint, flags);
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 998b86d..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename ExecutionContext>
- explicit basic_socket_acceptor_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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<Protocol> 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<Protocol> 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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const endpoint_type& endpoint, bool reuse_addr = true,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_acceptor,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_acceptor_ext(basic_socket_acceptor_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_acceptor_ext&
- >::type operator=(basic_socket_acceptor_ext<Protocol1, Executor1>&& 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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 <typename Protocol1, typename Executor1>
- void accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<Protocol1, Executor1>& peer, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- initiate_async_accept(), handler, this,
- &peer, static_cast<endpoint_type*>(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 <typename Executor1>
- void accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
- endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- 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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), &peer_endpoint,
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, endpoint_type& peer_endpoint,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, endpoint_type& peer_endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const executor_type& ex,
- endpoint_type& peer_endpoint, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- 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<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename WaitHandler>
- 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<WaitHandler> 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 <typename AcceptHandler, typename Protocol1, typename Executor1>
- void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- basic_socket_acceptor_ext* self, basic_socket_ext_local<Protocol1, Executor1>* 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<AcceptHandler> 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 <typename MoveAcceptHandler, typename Executor1, typename Socket>
- 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<MoveAcceptHandler> 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, Executor> impl_;
-#endif
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 523f97a..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext(basic_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext&
- >::type operator=(basic_socket_ext<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 855d01c..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext_local<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext_local(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext_local(basic_socket_ext_local<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext_local&
- >::type operator=(basic_socket_ext_local<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e77f5eb..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_stream_socket_ext
- : public basic_socket_ext_local<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_stream_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_stream_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_stream_socket_ext(basic_stream_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_stream_socket_ext&
- >::type operator=(basic_stream_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext_local<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- initiate_async_receive(), handler, this,
- buffers, socket_base::message_flags(0));
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 67fe6bd..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-char (&three_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const boost::asio::ip::address*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const boost::asio::ip::address>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 65640ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-char (&four_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const std::uint32_t*>(0), \
- static_cast<const std::uint32_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 04036ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext::reactive_socket_service_base_ext(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 288cf19..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 39e2ed8..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 83a673b..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<DWORD>(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<int>(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<DWORD>(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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 1167d57..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext*>(base));
-
- typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext :
- public reactive_socket_recv_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recv_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 bedbd29..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext_local*>(base));
-
- typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext_local :
- public reactive_socket_recv_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recv_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 875fe14..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext :
- public reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<reactive_socket_recvfrom_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 f9fef2b..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext_local :
- public reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<reactive_socket_recvfrom_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 bd315dc..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext :
- public reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recvmsg_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 8148690..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext_local :
- public reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recvmsg_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 2e68a87..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext.ipp>
-#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 a71fce5..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp>
-#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 7254ccd..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext :
- public execution_context_service_base<reactive_socket_service_ext<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, 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_, 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 8ac3265..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext_local :
- public execution_context_service_base<reactive_socket_service_ext_local<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext_local<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, 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_, 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 697cd9f..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 3d9ae5f..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 9285fed..0000000
--- 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 <boost/asio/detail/socket_ops.hpp>
-
-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 <boost/asio/detail/impl/socket_ops_ext.ipp>
-#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 a937bb6..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/socket_ops_ext_local.ipp>
-#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 6ce2ac4..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_datagram_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/ip/basic_endpoint.hpp>
-#include <boost/asio/ip/basic_resolver.hpp>
-#include <boost/asio/ip/basic_resolver_iterator.hpp>
-#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/ip/udp.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<udp> 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<udp> socket;
-
- /// The UDP resolver type.
- typedef basic_resolver<udp> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 7c57c62..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <boost/asio/basic_socket_acceptor_ext.hpp>
-#include <boost/asio/basic_socket_iostream.hpp>
-#include <boost/asio/basic_stream_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<stream_protocol_ext> endpoint;
-
- /// The UNIX domain socket type.
- typedef basic_stream_socket_ext<stream_protocol_ext> socket;
-
- /// The UNIX domain acceptor type.
- typedef basic_socket_acceptor_ext<stream_protocol_ext> acceptor;
-
-#if !defined(BOOST_ASIO_NO_IOSTREAM)
- /// The UNIX domain iostream type.
- typedef basic_socket_iostream<stream_protocol_ext> iostream;
-#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
-};
-
-} // namespace local
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 49a4950..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/basic_socket_ext.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_datagram_socket_ext
- : public basic_socket_ext<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_datagram_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket_ext<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_datagram_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_datagram_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_datagram_socket_ext(basic_datagram_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_datagram_socket_ext&
- >::type operator=(basic_datagram_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
- initiate_async_receive_from(), handler,
- this, buffers, &sender_endpoint, flags);
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 0a86539..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename ExecutionContext>
- explicit basic_socket_acceptor_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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<Protocol> 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<Protocol> 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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const endpoint_type& endpoint, bool reuse_addr = true,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_acceptor_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_acceptor,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_acceptor_ext(basic_socket_acceptor_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_acceptor_ext&
- >::type operator=(basic_socket_acceptor_ext<Protocol1, Executor1>&& 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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 <typename Protocol1, typename Executor1>
- void accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket_ext_local<Protocol1, Executor1>& peer, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- impl_.get_service().accept(impl_.get_implementation(),
- peer, static_cast<endpoint_type*>(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 <typename Protocol1, typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<
- is_convertible<Protocol, Protocol1>::value
- >::type* = 0)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- initiate_async_accept(), handler, this,
- &peer, static_cast<endpoint_type*>(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 <typename Executor1>
- void accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1>
- BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local<protocol_type, Executor1>& 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 <typename Executor1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
- endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
- {
- return async_initiate<AcceptHandler, void (boost::system::error_code)>(
- 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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, boost::system::error_code& ec,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), static_cast<endpoint_type*>(0),
- static_cast<other_socket_type*>(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 <typename MoveAcceptHandler>
- 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<MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket)>(
- initiate_async_move_accept(), handler, this,
- impl_.get_executor(), &peer_endpoint,
- static_cast<typename Protocol::socket*>(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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const Executor1& ex, endpoint_type& peer_endpoint,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- boost::system::error_code ec;
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other
- accept(ExecutionContext& context, endpoint_type& peer_endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 Executor1>
- typename Protocol::socket::template rebind_executor<Executor1>::other
- accept(const executor_type& ex,
- endpoint_type& peer_endpoint, boost::system::error_code& ec,
- typename enable_if<
- is_executor<Executor1>::value
- >::type* = 0)
- {
- typename Protocol::socket::template
- rebind_executor<Executor1>::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 ExecutionContext>
- 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<ExecutionContext&, execution_context&>::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 <typename Executor1, typename MoveAcceptHandler>
- 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<Executor1>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- Executor1>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- ex, &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename ExecutionContext, typename MoveAcceptHandler>
- 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<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- {
- typedef typename Protocol::socket::template rebind_executor<
- typename ExecutionContext::executor_type>::other other_socket_type;
-
- return async_initiate<MoveAcceptHandler,
- void (boost::system::error_code, other_socket_type)>(
- initiate_async_move_accept(), handler, this,
- context.get_executor(), &peer_endpoint,
- static_cast<other_socket_type*>(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 <typename WaitHandler>
- 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<WaitHandler> 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 <typename AcceptHandler, typename Protocol1, typename Executor1>
- void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- basic_socket_acceptor_ext* self, basic_socket_ext_local<Protocol1, Executor1>* 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<AcceptHandler> 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 <typename MoveAcceptHandler, typename Executor1, typename Socket>
- 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<MoveAcceptHandler> 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, Executor> impl_;
-#endif
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 777a0bf..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext(basic_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext&
- >::type operator=(basic_socket_ext<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 2c898fc..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext.hpp>
-#include <boost/asio/detail/io_object_impl.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
-#endif
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-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 <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_socket_ext_local<Protocol, Executor1> 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<Protocol, Executor> 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 <typename ExecutionContext>
- explicit basic_socket_ext_local(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename ExecutionContext>
- basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
- const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::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 <typename Protocol1, typename Executor1>
- 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 <typename Protocol1, typename Executor1>
- basic_socket_ext_local(basic_socket_ext_local<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_socket_ext_local&
- >::type operator=(basic_socket_ext_local<Protocol1, Executor1> && 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 <typename ConnectHandler>
- 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<ConnectHandler, void (boost::system::error_code)>(
- 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 <typename SettableSocketOption>
- 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 <typename SettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename GettableSocketOption>
- 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 <typename IoControlCommand>
- 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 <typename IoControlCommand>
- 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename Handler>
- * 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 <typename Handler>
- * void async_sendfile(tcp::socket& sock, int fd, Handler h)
- * {
- * sendfile_op<Handler> 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 <typename WaitHandler>
- 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<WaitHandler, void (boost::system::error_code)>(
- 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<Protocol>, Executor> impl_;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- detail::io_object_impl<
- detail::win_iocp_socket_service<Protocol>, Executor> impl_;
-#else
- detail::io_object_impl<
- detail::reactive_socket_service_ext_local<Protocol>, 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 <typename ConnectHandler>
- 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<ConnectHandler> 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 <typename WaitHandler>
- 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<WaitHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 e77f5eb..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_socket_ext_local.hpp>
-#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
-#include <boost/asio/detail/non_const_lvalue.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename Protocol, typename Executor = executor>
-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 <typename Protocol, typename Executor>
-class basic_stream_socket_ext
- : public basic_socket_ext_local<Protocol, Executor>
-{
-public:
- /// The type of the executor associated with the object.
- typedef Executor executor_type;
-
- /// Rebinds the socket type to another executor.
- template <typename Executor1>
- struct rebind_executor
- {
- /// The socket type when rebound to the specified executor.
- typedef basic_stream_socket_ext<Protocol, Executor1> other;
- };
-
- /// The native representation of a socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename basic_socket<Protocol,
- Executor>::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<Protocol, Executor>(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 <typename ExecutionContext>
- explicit basic_stream_socket_ext(ExecutionContext& context,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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 <typename ExecutionContext>
- basic_stream_socket_ext(ExecutionContext& context,
- const protocol_type& protocol, const native_handle_type& native_socket,
- typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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<Protocol, Executor>(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<Protocol, Executor>::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 <typename Protocol1, typename Executor1>
- basic_stream_socket_ext(basic_stream_socket_ext<Protocol1, Executor1>&& other,
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value
- >::type* = 0)
- : basic_socket_ext_local<Protocol, Executor>(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 Protocol1, typename Executor1>
- typename enable_if<
- is_convertible<Protocol1, Protocol>::value
- && is_convertible<Executor1, Executor>::value,
- basic_stream_socket_ext&
- >::type operator=(basic_stream_socket_ext<Protocol1, Executor1>&& other)
- {
- basic_socket_ext_local<Protocol, Executor>::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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence>
- 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 <typename ConstBufferSequence, typename WriteHandler>
- 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<WriteHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence>
- 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 <typename MutableBufferSequence, typename ReadHandler>
- 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<ReadHandler,
- void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
- initiate_async_receive(), handler, this,
- buffers, socket_base::message_flags(0));
- }
-
-private:
- struct initiate_async_send
- {
- template <typename WriteHandler, typename ConstBufferSequence>
- 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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
- 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<ReadHandler> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 67fe6bd..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-char (&three_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const boost::asio::ip::address*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const boost::asio::ip::address>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 65640ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-// 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 <boost/asio/async_result.hpp>
-#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 <typename Handler>
-auto zero_arg_copyable_handler_test(Handler h, void*)
- -> decltype(
- sizeof(Handler(static_cast<const Handler&>(h))),
- ((h)()),
- char(0));
-
-template <typename Handler>
-char (&zero_arg_copyable_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1>
-auto one_arg_handler_test(Handler h, Arg1* a1)
- -> decltype(
- sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
- ((h)(*a1)),
- char(0));
-
-template <typename Handler>
-char (&one_arg_handler_test(Handler h, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2>
-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 <typename Handler>
-char (&two_arg_move_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-char (&four_arg_handler_test(Handler, ...))[2];
-
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-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 <typename Handler>
-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 <typename T> T& lvref();
-template <typename T> T& lvref(T);
-template <typename T> const T& clvref();
-template <typename T> const T& clvref(T);
-#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> T rvref();
-template <typename T> T rvref(T);
-#else // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> const T& rvref();
-template <typename T> const T& rvref(T);
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-template <typename T> char argbyv(T);
-
-#if 0
-template <int>
-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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(0), \
- static_cast<const std::uint32_t*>(0), \
- static_cast<const std::uint32_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>(), \
- boost::asio::detail::lvref<const std::uint32_t>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<socket_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::rvref<socket_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const endpoint_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const endpoint_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const iter_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const iter_type>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const range_type*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const range_type>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const int*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const int>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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<const boost::system::error_code*>(0), \
- static_cast<const std::size_t*>(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<const boost::system::error_code>(), \
- boost::asio::detail::lvref<const std::size_t>()), \
- 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<const boost::system::error_code*>(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<const boost::system::error_code>()), \
- 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 04036ad..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext::reactive_socket_service_base_ext(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 288cf19..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local(
- execution_context& context)
- : reactor_(use_service<reactor>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 39e2ed8..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 83a673b..0000000
--- 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 <boost/asio/detail/impl/socket_ops.ipp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<DWORD>(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<int>(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<DWORD>(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<int>(*addrlen);
- msg.msg_iov = bufs;
- msg.msg_iovlen = static_cast<int>(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 <boost/asio/detail/pop_options.hpp>
-
-#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 1167d57..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext*>(base));
-
- typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext :
- public reactive_socket_recv_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recv_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 bedbd29..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recv_op_base_ext_local*>(base));
-
- typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recv_op_ext_local :
- public reactive_socket_recv_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recv_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 875fe14..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext :
- public reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<reactive_socket_recvfrom_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 f9fef2b..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence, typename Endpoint>
-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<reactive_socket_recvfrom_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Endpoint,
- typename Handler, typename IoExecutor>
-class reactive_socket_recvfrom_op_ext_local :
- public reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>
-{
-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<MutableBufferSequence, Endpoint>(
- 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<reactive_socket_recvfrom_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 bd315dc..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext :
- public reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recvmsg_op_ext*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, boost::asio::ip::address>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 8148690..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_work.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactor_op_ext_local.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/socket_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename MutableBufferSequence>
-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<reactive_socket_recvmsg_op_base_ext_local*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence, typename Handler, typename IoExecutor>
-class reactive_socket_recvmsg_op_ext_local :
- public reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>
-{
-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<MutableBufferSequence>(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<reactive_socket_recvmsg_op_ext_local*>(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<Handler, IoExecutor> w(
- BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
- 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, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
- 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<Handler, IoExecutor> work_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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 2e68a87..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext.ipp>
-#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 a71fce5..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP) \
- && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_recv_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_send_op.hpp>
-#include <boost/asio/detail/reactive_wait_op.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops_ext_local.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <typename IO_Control_Command>
- 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<ioctl_arg_type*>(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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename ConstBufferSequence>
- size_t send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<boost::asio::const_buffer,
- ConstBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- size_t receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(buffers)));
- p.v = p.p = 0;
- }
-
- // Wait until data can be received without blocking.
- template <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp>
-#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 7254ccd..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext :
- public execution_context_service_base<reactive_socket_service_ext<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, 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_, 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 8ac3265..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if !defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/execution_context.hpp>
-#include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/buffer_sequence_adapter.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/reactive_null_buffers_op.hpp>
-#include <boost/asio/detail/reactive_socket_accept_op.hpp>
-#include <boost/asio/detail/reactive_socket_connect_op.hpp>
-#include <boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp>
-#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
-#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
-#include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-template <typename Protocol>
-class reactive_socket_service_ext_local :
- public execution_context_service_base<reactive_socket_service_ext_local<Protocol> >,
- 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<Protocol> >(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 <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- reactive_socket_service_ext_local<Protocol1>&,
- 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 <typename Option>
- 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 <typename Option>
- 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 <typename ConstBufferSequence>
- 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<boost::asio::const_buffer,
- ConstBufferSequence> 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 <typename ConstBufferSequence, typename Handler, typename IoExecutor>
- 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<ConstBufferSequence,
- endpoint_type, 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,
- 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename MutableBufferSequence>
- 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<boost::asio::mutable_buffer,
- MutableBufferSequence> 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 <typename MutableBufferSequence,
- typename Handler, typename IoExecutor>
- 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<MutableBufferSequence,
- endpoint_type, Handler, IoExecutor> 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <typename Socket>
- 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 <typename Socket, typename Handler, typename IoExecutor>
- 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<Socket, Protocol, 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_, 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 <typename PeerIoExecutor, typename Handler, typename IoExecutor>
- 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<Protocol,
- PeerIoExecutor, 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_, 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 <typename Handler, typename IoExecutor>
- 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<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_, 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 <boost/asio/detail/pop_options.hpp>
-
-#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 697cd9f..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 3d9ae5f..0000000
--- 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 <boost/asio/detail/reactor_op.hpp>
-
-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 9285fed..0000000
--- 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 <boost/asio/detail/socket_ops.hpp>
-
-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 <boost/asio/detail/impl/socket_ops_ext.ipp>
-#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 a937bb6..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/memory.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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 <boost/asio/detail/pop_options.hpp>
-
-#if defined(BOOST_ASIO_HEADER_ONLY)
-# include <boost/asio/detail/impl/socket_ops_ext_local.ipp>
-#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 6ce2ac4..0000000
--- 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 <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_datagram_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/ip/basic_endpoint.hpp>
-#include <boost/asio/ip/basic_resolver.hpp>
-#include <boost/asio/ip/basic_resolver_iterator.hpp>
-#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/ip/udp.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<udp> 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<udp> socket;
-
- /// The UDP resolver type.
- typedef basic_resolver<udp> 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 <boost/asio/detail/pop_options.hpp>
-
-#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 7c57c62..0000000
--- 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 <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <boost/asio/basic_socket_acceptor_ext.hpp>
-#include <boost/asio/basic_socket_iostream.hpp>
-#include <boost/asio/basic_stream_socket_ext.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-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<stream_protocol_ext> endpoint;
-
- /// The UNIX domain socket type.
- typedef basic_stream_socket_ext<stream_protocol_ext> socket;
-
- /// The UNIX domain acceptor type.
- typedef basic_socket_acceptor_ext<stream_protocol_ext> acceptor;
-
-#if !defined(BOOST_ASIO_NO_IOSTREAM)
- /// The UNIX domain iostream type.
- typedef basic_socket_iostream<stream_protocol_ext> iostream;
-#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
-};
-
-} // namespace local
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#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
index 43b2d93..43b2d93 100644
--- a/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp
+++ b/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
index 4af4bac..4af4bac 100644
--- a/implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp
+++ b/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
index ab55eda..ab55eda 100644
--- a/implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp
+++ b/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
index 7648581..7648581 100644
--- a/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp
+++ b/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
index 34b0375..34b0375 100644
--- a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp
+++ b/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
index 717eb6e..717eb6e 100644
--- 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
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
index 3b4a4a8..3b4a4a8 100644
--- 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
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
index 26521cf..26521cf 100644
--- 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
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
index fb6f77b..fe90e83 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
index b601e11..b601e11 100644
--- 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
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
index 531ad21..531ad21 100644
--- 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
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
index 6c151ca..6c151ca 100644
--- 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
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
index 93bdf01..93bdf01 100644
--- 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
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
index a38844d..a38844d 100644
--- 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
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
index b28572b..b28572b 100644
--- 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
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
index 7b5bc53..7b5bc53 100644
--- 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
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
index 3c0107c..3c0107c 100644
--- 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
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
index e97fca2..e97fca2 100644
--- 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
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
index 133301c..133301c 100644
--- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp
+++ b/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
index 7b444b3..7b444b3 100644
--- 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
diff --git a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext.hpp
index 948e016..948e016 100644
--- a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp
+++ b/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
index a10d876..a10d876 100644
--- a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp
+++ b/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
index 65b8ad8..65b8ad8 100644
--- a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp
+++ b/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
index 77fd563..77fd563 100644
--- a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp
+++ b/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
index c622ff9..c622ff9 100644
--- a/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp
+++ b/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
index 6ccd0ad..6ccd0ad 100644
--- a/implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp
+++ b/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
index 19a3bde..19a3bde 100644
--- a/implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp
+++ b/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
index aaa13b3..aaa13b3 100644
--- a/implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp
+++ b/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 bb83363..c827bf4 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 <mutex>
#ifdef USE_DLT
+#ifndef ANDROID
#include <dlt/dlt.h>
#endif
+#endif
#include <vsomeip/internal/logger.hpp>
@@ -43,7 +45,9 @@ private:
std::shared_ptr<configuration> 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 7e79aa2..b909c34 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> &_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<configuration>
@@ -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<logger_impl> *the_logger_ptr__(nullptr);
static std::mutex the_logger_mutex__;
std::shared_ptr<logger_impl>
logger_impl::get() {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
std::lock_guard<std::mutex> 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<std::mutex> its_lock(the_logger_mutex__);
if (the_logger_ptr__ != nullptr) {
- std::lock_guard<std::mutex> 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 6787452..b89816c 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 <iostream>
#ifdef ANDROID
-#include <android/log.h>
+#include <utils/Log.h>
-#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 <vsomeip/internal/logger.hpp>
+#include <vsomeip/runtime.hpp>
#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<std::mutex> 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 058fe94..098698d 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 @@ public:
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<byte_t> &_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 216656b..acad2e8 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 b6e305a..f82775f 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 b121c46..e04d4a7 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 @@ public:
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 8ea256c..d77eaa0 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 ff99679..bd626ab 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 @@ public:
virtual void show();
#endif
private:
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif
std::vector<byte_t> 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 0e33faa..cff4596 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<message_impl> 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<byte_t> &_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<byte_t>::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 43295c4..c1d7da7 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 27950e7..40b98c3 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 25cf584..c784e52 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 dd1a6aa..7617cdc 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 fe5196e..fa94a9c 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 61662b8..d398e24 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 @@ public:
VSOMEIP_EXPORT virtual ~plugin_manager() {};
VSOMEIP_EXPORT static std::shared_ptr<plugin_manager> get();
VSOMEIP_EXPORT virtual void load_plugins() = 0;
- VSOMEIP_EXPORT virtual std::shared_ptr<plugin> get_plugin(plugin_type_e _type, std::string _name) = 0;
-
+ VSOMEIP_EXPORT virtual std::shared_ptr<plugin> 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 eb7d09f..e88772e 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 @@ public:
VSOMEIP_EXPORT void load_plugins();
- VSOMEIP_EXPORT std::shared_ptr<plugin> get_plugin(plugin_type_e _type, std::string _name);
+ VSOMEIP_EXPORT std::shared_ptr<plugin> get_plugin(plugin_type_e _type,
+ const std::string &_name);
VSOMEIP_EXPORT std::shared_ptr<plugin> load_plugin(
const std::string& _library, plugin_type_e _type,
@@ -37,12 +38,13 @@ public:
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> &_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 f8ddaa1..d64cbaa 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 159eea9..bfaf272 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 <sstream>
#include <vector>
#include <stdlib.h>
+#include <iomanip>
#include <iostream>
#ifdef _WIN32
@@ -110,7 +111,8 @@ void plugin_manager_impl::load_plugins() {
}
}
-std::shared_ptr<plugin> plugin_manager_impl::get_plugin(plugin_type_e _type, std::string _name) {
+std::shared_ptr<plugin> plugin_manager_impl::get_plugin(plugin_type_e _type,
+ const std::string &_name) {
std::lock_guard<std::recursive_mutex> 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<HMODULE>(_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<LPSTR>(&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<HMODULE>(_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 0000000..ec11268
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..b1932da
--- /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 <string>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..a39990a
--- /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 <cstring> // memcpy
+#include <vector>
+
+#include <vsomeip/primitive_types.hpp>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const;
+ virtual void deserialize(const std::vector<byte_t> &_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 0000000..9b1bcb8
--- /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 0000000..2b2c673
--- /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 <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer, error_e &_error);
+
+ // specific
+ std::set<std::shared_ptr<policy> > get_policies() const;
+
+ void set_payloads(const std::map<uint32_t, std::shared_ptr<payload> > &_payloads);
+
+private:
+ std::set<std::shared_ptr<policy> > policies_;
+ std::vector<byte_t> 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 0000000..70f4f6c
--- /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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..4c47aa9
--- /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 <memory>
+
+#include <vsomeip/structured_types.hpp>
+
+#include "subscribe_command_base.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+class expire_command
+ : public subscribe_command_base {
+
+public:
+ expire_command();
+
+ void serialize(std::vector<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..d679b16
--- /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 <set>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer, error_e &_error);
+
+ // specific
+ std::set<service> get_services() const;
+ void set_services(const std::set<service> &_services);
+ void add_service(const service &_service);
+
+private:
+ std::set<service> 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 0000000..22e5f36
--- /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 0000000..3ced949
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..79a8f2c
--- /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 0000000..369e255
--- /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 0000000..1876f0d
--- /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 0000000..08a770b
--- /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 <vsomeip/constants.hpp>
+#include <vsomeip/primitive_types.hpp>
+
+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<byte_t>(id_e::SUSPEND_ID))
+ its_id = static_cast<id_e>(_byte);
+ return (its_id);
+}
+
+static inline bool operator==(const byte_t &_lhs, const id_e &_rhs) {
+
+ return (_lhs == static_cast<byte_t>(_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 0000000..ffb15ad
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..f468c02
--- /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 <set>
+#include <vector>
+#include <vsomeip/constants.hpp>
+#include <cstring>
+
+#include "protocol.hpp"
+#include <vsomeip/enumeration_types.hpp>
+#include <vsomeip/primitive_types.hpp>
+
+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<eventgroup_t> &eventgroups = std::set<eventgroup_t>());
+ void serialize(std::vector<byte_t> &_buffer, size_t &_offset) const;
+ void deserialize(const std::vector<byte_t> &_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<eventgroup_t> get_eventgroups() const { return eventgroups_; }
+ void set_eventgroups(const std::set<eventgroup_t> &_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<eventgroup_t> 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 0000000..23dd7fa
--- /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 <set>
+
+#include <vsomeip/enumeration_types.hpp>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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<register_event> 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 0000000..0ae85ba
--- /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 0000000..537fd14
--- /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 <set>
+
+#include "command.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+class release_service_command
+ : public command {
+public:
+ release_service_command();
+
+ // command
+ void serialize(std::vector<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..83480e4
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..7deda2c
--- /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 0000000..945247e
--- /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 0000000..1fc493c
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..2cb0ab7
--- /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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer, error_e &_error);
+
+ // specific
+ const std::vector<routing_info_entry> &get_entries() const;
+ void set_entries(std::vector<routing_info_entry> &&_entries);
+ void add_entry(const routing_info_entry &_entry);
+
+private:
+ std::vector<routing_info_entry> 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 0000000..b27190b
--- /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 <vector>
+
+#include <boost/asio/ip/address.hpp>
+
+#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<byte_t> &_buffer, size_t &_index,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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<service> &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<service> 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 0000000..799f703
--- /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 <memory>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..cb10b45
--- /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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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<byte_t> get_message() const;
+ void set_message(const std::vector<byte_t> &_message);
+
+private:
+
+ instance_t instance_;
+ bool is_reliable_;
+ uint8_t status_; // TODO: DO WE REALLY NEED THIS?
+ client_t target_;
+ std::vector<byte_t> 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 0000000..05b488d
--- /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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..09ae8fd
--- /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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..a9a51d2
--- /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 0000000..b3f4c76
--- /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 0000000..3a738b9
--- /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 <memory>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..d552562
--- /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 <memory>
+
+#include <vsomeip/structured_types.hpp>
+
+#include "subscribe_command_base.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+class subscribe_command
+ : public subscribe_command_base {
+
+public:
+ subscribe_command();
+
+ std::shared_ptr<debounce_filter_t> get_filter() const;
+ void set_filter(const std::shared_ptr<debounce_filter_t> &_filter);
+
+ void serialize(std::vector<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer,
+ error_e &_error);
+
+private:
+ std::shared_ptr<debounce_filter_t> 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 0000000..a16c2fe
--- /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 <memory>
+
+#include <vsomeip/structured_types.hpp>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..5b79ce5
--- /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 0000000..414b36f
--- /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 0000000..9779946
--- /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 <set>
+
+#include <vsomeip/enumeration_types.hpp>
+
+#include "command.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+class unregister_event_command
+ : public command {
+public:
+ unregister_event_command();
+
+ void serialize(std::vector<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..7afaa1d
--- /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<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..e0a05ce
--- /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 <memory>
+
+#include <vsomeip/structured_types.hpp>
+
+#include "subscribe_command_base.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+class unsubscribe_command
+ : public subscribe_command_base {
+
+public:
+ unsubscribe_command();
+
+ void serialize(std::vector<byte_t> &_buffer,
+ error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_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 0000000..37d9c34
--- /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 <set>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer, error_e &_error);
+
+ // specific
+ std::set<std::pair<uid_t, gid_t> > get_credentials() const;
+ void set_credentials(
+ const std::set<std::pair<uid_t, gid_t> > &_credentials);
+
+private:
+ std::set<std::pair<uid_t, gid_t> > 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 0000000..9a42d64
--- /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 <memory>
+
+#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<byte_t> &_buffer, error_e &_error) const;
+ void deserialize(const std::vector<byte_t> &_buffer, error_e &_error);
+
+ // specific
+ uint32_t get_update_id() const;
+ void set_update_id(uint32_t _update_id);
+
+ std::shared_ptr<policy> get_policy() const;
+ void set_policy(const std::shared_ptr<policy> &_policy);
+
+private:
+ uint32_t update_id_;
+ std::shared_ptr<policy> 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 0000000..002b001
--- /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 0000000..b5d19ea
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + sizeof(assigned_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..245ea92
--- /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 <limits>
+
+#include <vsomeip/internal/logger.hpp>
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + name_.length());
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..fe338b0
--- /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<byte_t> &_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<byte_t>(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<byte_t> &_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<id_e>(_buffer[0]);
+ } else if (_buffer[0] != static_cast<byte_t>(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 0000000..5cd6f8d
--- /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 <limits>
+
+#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 0000000..c93b530
--- /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 <limits>
+
+#include <vsomeip/payload.hpp>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE +
+ std::min(payload_.size(), size_t(std::numeric_limits<uint32_t>::max())));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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<policy>();
+ 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<std::shared_ptr<policy> >
+distribute_security_policies_command::get_policies() const {
+
+ return (policies_);
+}
+
+void
+distribute_security_policies_command::set_payloads(
+ const std::map<uint32_t, std::shared_ptr<payload> > &_payloads) {
+
+ uint32_t its_count(uint32_t(_payloads.size()));
+ for (uint32_t i = 0; i < sizeof(its_count); ++i) {
+ payload_.push_back(
+ reinterpret_cast<const byte_t*>(&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<const byte_t*>(&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 0000000..0ecc18f
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ (void)_buffer;
+ _error = error_e::ERROR_NOT_ALLOWED;
+}
+
+void
+dummy_command::deserialize(const std::vector<byte_t> &_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 0000000..0611901
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(its_size - COMMAND_HEADER_SIZE);
+
+ // payload
+ subscribe_command_base::serialize(_buffer, _error);
+}
+
+void
+expire_command::deserialize(const std::vector<byte_t> &_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 0000000..47c8ab2
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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<service>
+multiple_services_command_base::get_services() const {
+
+ return (services_);
+}
+
+void
+multiple_services_command_base::set_services(const std::set<service> &_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 0000000..286a6f7
--- /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 0000000..3a0aa95
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + sizeof(offer_type_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..bc8df95
--- /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 0000000..fab227b
--- /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 0000000..8be1e90
--- /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 0000000..d8babc7
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + sizeof(port_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..5be91b6
--- /dev/null
+++ b/implementation/protocol/src/register_event.cpp
@@ -0,0 +1,82 @@
+#include "../include/register_event.hpp"
+#include <vsomeip/internal/logger.hpp>
+
+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<eventgroup_t> &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<byte_t> &_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<byte_t>(event_type_);
+ _offset += sizeof(event_type_);
+ _buffer[_offset] = static_cast<byte_t>(is_provided_);
+ _offset += sizeof(is_provided_);
+ _buffer[_offset] = static_cast<byte_t>(reliability_);
+ _offset += sizeof(reliability_);
+ _buffer[_offset] = static_cast<byte_t>(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<byte_t> &_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<event_type_e>(_buffer[_offset]);
+ _offset += sizeof(event_type_);
+ is_provided_ = static_cast<bool>(_buffer[_offset]);
+ _offset += sizeof(is_provided_);
+ reliability_ = static_cast<reliability_type_e>(_buffer[_offset]);
+ _offset += sizeof(reliability_);
+ is_cyclic_ = static_cast<bool>(_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<eventgroup_t> &_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 0000000..830e223
--- /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 <limits>
+
+#include "../include/register_events_command.hpp"
+#include <vsomeip/internal/logger.hpp>
+
+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<command_size_t>::max()) {
+ return false;
+ } else {
+ // set size
+ size_ = static_cast<command_size_t>(its_size - COMMAND_HEADER_SIZE);
+ registrations_.push_back(_register_event);
+ }
+ return true;
+}
+
+void
+register_events_command::serialize(std::vector<byte_t> &_buffer, error_e &_error) const {
+
+ if (size_ + COMMAND_HEADER_SIZE> std::numeric_limits<command_size_t>::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 &reg : registrations_) {
+ reg.serialize(_buffer, its_offset);
+ }
+}
+
+void
+register_events_command::deserialize(const std::vector<byte_t> &_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 0000000..a9df5d3
--- /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 0000000..41475ec
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE
+ + sizeof(service::service_) + sizeof(service::instance_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..acf8aed
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..ce8ab0b
--- /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 0000000..c98f8eb
--- /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 0000000..929a434
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + sizeof(remote_offer_id_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..ae2747f
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>(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<byte_t> &_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_entry> &
+routing_info_command::get_entries() const {
+
+ return (entries_);
+}
+
+void
+routing_info_command::set_entries(std::vector<routing_info_entry> &&_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 0000000..1edb23b
--- /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 <cstring>
+#include <limits>
+
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio/ip/address_v6.hpp>
+
+#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<byte_t> &_buffer,
+ size_t &_index, error_e &_error) const {
+
+ _buffer[_index] = static_cast<byte_t>(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<uint32_t>::max()) {
+
+ _error = error_e::ERROR_MALFORMED;
+ return;
+ }
+
+ uint32_t its_size32(static_cast<uint32_t>(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<uint32_t>::max()) {
+
+ _error = error_e::ERROR_MALFORMED;
+ return;
+ }
+
+ its_size32 = static_cast<uint32_t>(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<byte_t> &_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<routing_info_entry_type_e>(_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<major_version_t>(_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<service> &
+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 0000000..2a4837a
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_));
+
+ if (its_size > std::numeric_limits<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..7959744
--- /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 <limits>
+
+#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<byte_t>
+send_command::get_message() const {
+
+ return message_;
+}
+
+void
+send_command::set_message(const std::vector<byte_t> &_message) {
+
+ message_ = std::move(_message);
+}
+
+void
+send_command::serialize(std::vector<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t>(is_reliable_);
+ its_offset += sizeof(is_reliable_);
+ _buffer[its_offset] = static_cast<byte_t>(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<byte_t> &_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<bool>(_buffer[its_offset]);
+ its_offset += sizeof(is_reliable_);
+ status_ = static_cast<uint8_t>(_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 0000000..ae270f2
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..9076012
--- /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 <limits>
+
+#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<byte_t> &_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<byte_t> &_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 0000000..c12a20d
--- /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 0000000..12fe1cd
--- /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 0000000..2a88972
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..89f19af
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#include "../include/subscribe_command.hpp"
+
+namespace vsomeip_v3 {
+namespace protocol {
+
+subscribe_command::subscribe_command()
+ : subscribe_command_base(id_e::SUBSCRIBE_ID) {
+}
+
+std::shared_ptr<debounce_filter_t>
+subscribe_command::get_filter() const {
+
+ return filter_;
+}
+
+void
+subscribe_command::set_filter(
+ const std::shared_ptr<debounce_filter_t> &_filter) {
+
+ filter_ = _filter;
+}
+
+void
+subscribe_command::serialize(std::vector<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t>(filter_->on_change_);
+ its_offset += sizeof(filter_->on_change_);
+ _buffer[its_offset] = static_cast<byte_t>(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<byte_t> &_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<debounce_filter_t>();
+ 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 0000000..cd5644a
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#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<byte_t> &_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<byte_t> &_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 0000000..b009dad
--- /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 0000000..4f780f0
--- /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 0000000..ff9813c
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t>(is_provided_);
+}
+
+void
+unregister_event_command::deserialize(const std::vector<byte_t> &_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<bool>(_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 0000000..ab7138d
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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 0000000..247b301
--- /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 <limits>
+
+#include <vsomeip/constants.hpp>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(its_size - COMMAND_HEADER_SIZE);
+
+ // payload
+ subscribe_command_base::serialize(_buffer, _error);
+}
+
+void
+unsubscribe_command::deserialize(const std::vector<byte_t> &_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 0000000..3e69653
--- /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 <limits>
+
+#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<byte_t> &_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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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<std::pair<uid_t, gid_t> >
+update_security_credentials_command::get_credentials() const {
+
+ return (credentials_);
+}
+
+void
+update_security_credentials_command::set_credentials(
+ const std::set<std::pair<uid_t, gid_t> > &_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 0000000..8ff79e2
--- /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 <limits>
+
+#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<byte_t> &_buffer,
+ error_e &_error) const {
+
+ std::vector<byte_t> 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<command_size_t>::max()) {
+
+ _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED;
+ return;
+ }
+
+ // resize buffer
+ _buffer.resize(its_size);
+
+ // set size
+ size_ = static_cast<command_size_t>(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<byte_t> &_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<policy>();
+ 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<policy>
+update_security_policy_command::get_policy() const {
+
+ return (policy_);
+}
+
+void
+update_security_policy_command::set_policy(
+ const std::shared_ptr<policy> &_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 0000000..91573f0
--- /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 b22b6ed..97adb89 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 <set>
#include <atomic>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/steady_timer.hpp>
@@ -35,6 +34,8 @@ class message;
class payload;
class routing_manager;
+struct debounce_filter_t;
+
class event
: public std::enable_shared_from_this<event> {
public:
@@ -52,16 +53,19 @@ public:
event_t get_event() const;
void set_event(event_t _event);
- const std::shared_ptr<payload> get_payload() const;
+ std::shared_ptr<payload> get_payload() const;
void set_payload(const std::shared_ptr<payload> &_payload,
const client_t _client, bool _force);
void set_payload(const std::shared_ptr<payload> &_payload,
const client_t _client,
- const std::shared_ptr<endpoint_definition>& _target, bool _force);
+ const std::shared_ptr<endpoint_definition>& _target);
+
+ bool prepare_update_payload(const std::shared_ptr<payload> &_payload,
+ bool _force);
+ void update_payload();
- bool set_payload_dont_notify(const std::shared_ptr<payload> &_payload);
bool set_payload_notify_pending(const std::shared_ptr<payload> &_payload);
void set_payload(const std::shared_ptr<payload> &_payload, bool _force);
@@ -90,20 +94,25 @@ public:
void set_epsilon_change_function(
const epsilon_change_func_t &_epsilon_change_func);
- const std::set<eventgroup_t> get_eventgroups() const;
+ std::set<eventgroup_t> get_eventgroups() const;
std::set<eventgroup_t> get_eventgroups(client_t _client) const;
void add_eventgroup(eventgroup_t _eventgroup);
void set_eventgroups(const std::set<eventgroup_t> &_eventgroups);
void notify_one(client_t _client,
const std::shared_ptr<endpoint_definition> &_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<debounce_filter_t> &_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<client_t> get_subscribers();
+ std::set<client_t> get_filtered_subscribers(bool _force);
+ std::set<client_t> update_and_get_filtered_subscribers(
+ const std::shared_ptr<payload> &_payload, bool _force);
VSOMEIP_EXPORT std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
void clear_subscribers();
@@ -122,30 +131,34 @@ public:
void remove_pending(const std::shared_ptr<endpoint_definition> &_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<endpoint_definition> &_target);
void start_cycle();
void stop_cycle();
- bool compare(const std::shared_ptr<payload> &_lhs,
+ bool has_changed(const std::shared_ptr<payload> &_lhs,
const std::shared_ptr<payload> &_rhs) const;
- bool set_payload_helper(const std::shared_ptr<payload> &_payload,
- bool _force);
- void reset_payload(const std::shared_ptr<payload> &_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<endpoint_definition> &_target);
+ bool prepare_update_payload_unlocked(
+ const std::shared_ptr<payload> &_payload, bool _force);
+ void update_payload_unlocked();
+
private:
routing_manager *routing_;
mutable std::mutex mutex_;
- std::shared_ptr<message> message_;
+
+ std::shared_ptr<message> current_;
+ std::shared_ptr<message> update_;
std::atomic<event_type_e> type_;
@@ -172,6 +185,11 @@ private:
std::atomic<reliability_type_e> reliability_;
std::set<std::shared_ptr<endpoint_definition> > pending_;
+
+ std::mutex filters_mutex_;
+ std::map<client_t, epsilon_change_func_t> filters_;
+ std::mutex last_forwarded_mutex_;
+ std::map<client_t, std::chrono::steady_clock::time_point> last_forwarded_;
};
} // namespace vsomeip_v3
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index 8ec1ac6..1a5a1b9 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 @@ public:
uint16_t _port);
VSOMEIP_EXPORT bool is_sending_multicast() const;
- VSOMEIP_EXPORT const std::set<std::shared_ptr<event> > get_events() const;
+ VSOMEIP_EXPORT std::set<std::shared_ptr<event> > get_events() const;
VSOMEIP_EXPORT void add_event(const std::shared_ptr<event>& _event);
VSOMEIP_EXPORT void remove_event(const std::shared_ptr<event>& _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 3f89c08..f74ff37 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<remote_subscription> &_subscription)
-> remote_subscription_callback_t;
+using remote_subscription_callback_t =
+ std::function<void (const std::shared_ptr<remote_subscription> &_subscription)>;
} // namespace vsomeip_v3
diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp
index ff94d5b..f5bf2a2 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 @@ private:
std::weak_ptr<eventgroupinfo> 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 337e4a7..1decea3 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 <boost/asio/ip/address.hpp>
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/vsomeip_sec.h>
#ifdef ANDROID
#include "../../configuration/include/internal_android.hpp"
@@ -28,15 +29,19 @@ public:
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 fa0e675..6fa7693 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 <set>
#include <vector>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <vsomeip/function_types.hpp>
+#include <vsomeip/structured_types.hpp>
#include <vsomeip/message.hpp>
#include <vsomeip/handler.hpp>
+#include <vsomeip/vsomeip_sec.h>
+
#include "types.hpp"
namespace vsomeip_v3 {
@@ -30,10 +38,12 @@ public:
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 @@ public:
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<debounce_filter_t> &_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> _message) = 0;
+ virtual bool send(client_t _client, std::shared_ptr<message> _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<endpoint_definition> &_target,
- std::shared_ptr<message>) = 0;
+ std::shared_ptr<message> _message) = 0;
virtual bool send_to(const std::shared_ptr<endpoint_definition> &_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 a2195ee..26154b0 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 270f4c4..e4f9073 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 <condition_variable>
#include <vsomeip/constants.hpp>
+#include <vsomeip/vsomeip_sec.h>
-#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 @@ public:
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_base>& _endpoint_manager);
@@ -83,11 +95,14 @@ public:
virtual std::set<std::shared_ptr<event>> 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<debounce_filter_t> &_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 @@ public:
#endif
);
- virtual bool send(client_t _client, std::shared_ptr<message> _message);
+ virtual bool send(client_t _client, std::shared_ptr<message> _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 @@ public:
std::shared_ptr<event> 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>& _endpoint) = 0;
virtual void on_disconnect(const std::shared_ptr<endpoint>& _endpoint) = 0;
protected:
@@ -150,10 +175,12 @@ protected:
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<std::tuple<service_t, instance_t, eventgroup_t>>& _subscribed_eventgroups,
- bool _remove_uid);
+ const std::set<
+ std::tuple<service_t, instance_t, eventgroup_t>
+ > &_subscribed_eventgroups,
+ bool _remove_sec_client);
std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const;
@@ -163,15 +190,16 @@ protected:
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<endpoint> &_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<debounce_filter_t> &_filter, client_t _client,
std::set<event_t> *_already_subscribed_events);
std::shared_ptr<serializer> get_serializer();
@@ -182,9 +210,10 @@ protected:
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<debounce_filter_t> &_filter) = 0;
void remove_pending_subscription(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
@@ -209,9 +238,11 @@ protected:
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 @@ protected:
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<debounce_filter_t> &_filter,
+ client_t _client) = 0;
protected:
routing_manager_host *host_;
- boost::asio::io_service &io_;
- std::atomic<client_t> client_;
+ boost::asio::io_context &io_;
std::shared_ptr<configuration> configuration_;
@@ -245,8 +276,9 @@ protected:
std::condition_variable deserializer_condition_;
mutable std::mutex local_services_mutex_;
- typedef std::map<service_t, std::map<instance_t,
- std::tuple<major_version_t, minor_version_t, client_t>>> local_services_map_t;
+ using local_services_map_t =
+ std::map<service_t, std::map<instance_t,
+ std::tuple<major_version_t, minor_version_t, client_t>>>;
local_services_map_t local_services_;
std::map<service_t, std::map<instance_t, std::set<client_t> > > local_services_history_;
@@ -264,9 +296,6 @@ protected:
std::mutex event_registration_mutex_;
- std::mutex routing_state_mutex_;
- routing_state_e routing_state_;
-
#ifdef USE_DLT
std::shared_ptr<trace::connector_impl> tc_;
#endif
@@ -277,8 +306,8 @@ protected:
eventgroup_t eventgroup_;
major_version_t major_;
event_t event_;
- uid_t uid_;
- gid_t gid_;
+ std::shared_ptr<debounce_filter_t> filter_;
+ vsomeip_sec_client_t sec_client_;
bool operator<(const subscription_data_t &_other) const {
return (service_ < _other.service_
@@ -300,13 +329,26 @@ protected:
std::shared_ptr<endpoint_manager_base> ep_mgr_;
- std::uint32_t own_uid_;
- std::uint32_t own_gid_;
+ mutable std::mutex known_clients_mutex_;
+ std::map<client_t, std::string> 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<client_t,
+ std::pair<boost::asio::ip::address, port_t>
+ > guests_;
+
+ std::mutex add_known_client_mutex_;
+
#ifdef VSOMEIP_ENABLE_COMPAT
std::map<service_t,
std::map<instance_t,
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_client.hpp
index 2b5335a..fb56ec7 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_client.hpp
@@ -1,41 +1,53 @@
-// 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 VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP
-#define VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_CLIENT_HPP
+#define VSOMEIP_V3_ROUTING_MANAGER_CLIENT_HPP
#include <map>
#include <mutex>
#include <atomic>
#include <tuple>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
-#include "routing_manager_base.hpp"
-#include "types.hpp"
#include <vsomeip/enumeration_types.hpp>
#include <vsomeip/handler.hpp>
+#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<std::tuple<service_t, instance_t> > & _client_side_logging_filter);
- virtual ~routing_manager_proxy();
+ virtual ~routing_manager_client();
void init();
void start();
void stop();
std::shared_ptr<configuration> 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 @@ public:
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<debounce_filter_t> &_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<endpoint_definition> &_target,
@@ -91,9 +103,8 @@ public:
void on_connect(const std::shared_ptr<endpoint>& _endpoint);
void on_disconnect(const std::shared_ptr<endpoint>& _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 @@ public:
const std::shared_ptr<endpoint> &_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 @@ private:
void register_application();
void deregister_application();
- void reconnect(const std::unordered_set<client_t> &_clients);
+ void reconnect(const std::map<client_t, std::string> &_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<eventgroup_t> &_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<debounce_filter_t> &_filter);
void send_subscribe_nack(client_t _subscriber, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
@@ -176,12 +194,13 @@ private:
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<debounce_filter_t> &_filter,
+ client_t _client);
void request_debounce_timeout_cbk(boost::system::error_code const &_error);
- void send_request_services(std::set<service_data_t>& _requests);
+ void send_request_services(const std::set<protocol::service> &_requests);
void send_unsubscribe_ack(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, remote_subscription_id_t _id);
@@ -189,14 +208,23 @@ private:
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 @@ private:
std::shared_ptr<endpoint> sender_; // --> stub
std::shared_ptr<endpoint> receiver_; // --> from everybody
- std::mutex known_clients_mutex_;
- std::unordered_set<client_t> known_clients_;
-
- std::set<service_data_t> pending_offers_;
- std::set<service_data_t> requests_;
- std::set<service_data_t> requests_to_debounce_;
+ std::set<protocol::service> pending_offers_;
+ std::set<protocol::service> requests_;
+ std::set<protocol::service> requests_to_debounce_;
struct event_data_t {
service_t service_;
@@ -226,19 +251,20 @@ private:
event_type_e type_;
reliability_type_e reliability_;
bool is_provided_;
+ bool is_cyclic_;
std::set<eventgroup_t> 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<event_data_t> pending_event_registrations_;
- std::map<client_t, std::set<subscription_data_t>> pending_incoming_subscripitons_;
+ std::map<client_t, std::set<subscription_data_t>> pending_incoming_subscriptions_;
std::recursive_mutex incoming_subscriptions_mutex_;
std::mutex state_mutex_;
@@ -260,8 +286,13 @@ private:
const std::set<std::tuple<service_t, instance_t> > client_side_logging_filter_;
std::mutex stop_mutex_;
+
+#if defined(__linux__) || defined(ANDROID)
+ std::shared_ptr<netlink_connector> 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 69133e2..18a74af 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 <memory>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <vsomeip/error.hpp>
+#include <vsomeip/vsomeip_sec.h>
namespace vsomeip_v3 {
@@ -24,22 +30,30 @@ public:
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<configuration> 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> &&_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<void(bool)> _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<void(bool)> &_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> _message) = 0;
- virtual void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services) = 0;
+ virtual void on_offered_services_info(
+ std::vector<std::pair<service_t, instance_t>> &_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 3fd6eed..3c105c2 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 <unordered_set>
#include <boost/asio/ip/address.hpp>
-#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <vsomeip/primitive_types.hpp>
@@ -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 @@ public:
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 @@ public:
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<debounce_filter_t> &_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> _message);
+ bool send(client_t _client, std::shared_ptr<message> _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<endpoint_definition> &_target,
@@ -120,7 +125,7 @@ public:
event_t _notifier,
const std::set<eventgroup_t> &_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 @@ public:
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 @@ public:
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 @@ public:
void on_disconnect(const std::shared_ptr<endpoint>& _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 @@ public:
bool _magic_cookies_enabled);
// interface "service_discovery_host"
- typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t;
- const servicegroups_t & get_servicegroups() const;
std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const;
services_t get_offered_services() const;
@@ -285,15 +288,27 @@ public:
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<client_t> 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> &_policy,
const std::shared_ptr<payload> &_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 @@ private:
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 @@ private:
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<debounce_filter_t> &_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>& _endpoint,
- std::shared_ptr<boost::asio::steady_timer> _timer);
+ void remove_requested_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor);
+ std::vector<std::pair<service_t, instance_t>> get_requested_services(client_t _client);
+ std::set<client_t> get_requesters(service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor);
+ std::set<client_t> 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> &_endpoint,
+ std::shared_ptr<boost::asio::steady_timer> _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<debounce_filter_t> &_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 @@ private:
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<routing_manager_stub> stub_;
std::shared_ptr<sd::service_discovery> discovery_;
std::mutex requested_services_mutex_;
- std::map<client_t,
- std::map<service_t,
- std::map<instance_t,
- std::set<std::pair<major_version_t, minor_version_t>>>>> requested_services_;
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<major_version_t,
+ std::map<minor_version_t, std::set<client_t> >
+ >
+ >
+ > requested_services_;
std::mutex remote_subscribers_mutex_;
- std::map<service_t, std::map<instance_t, std::map<client_t,
- std::set<std::shared_ptr<endpoint_definition>>>>> remote_subscribers_;
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<client_t,
+ std::set<std::shared_ptr<endpoint_definition> >
+ >
+ >
+ > remote_subscribers_;
std::shared_ptr<serviceinfo> sd_info_;
@@ -446,7 +495,7 @@ private:
bool routing_running_;
std::mutex pending_sd_offers_mutex_;
std::vector<std::pair<service_t, instance_t>> pending_sd_offers_;
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
std::shared_ptr<netlink_connector> netlink_connector_;
#endif
@@ -503,6 +552,8 @@ private:
// 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 aa5796e..4209eec 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 <atomic>
#include <unordered_set>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <boost/asio/steady_timer.hpp>
#include <vsomeip/handler.hpp>
-
-#include "../../endpoints/include/endpoint_host.hpp"
-#include "../include/routing_host.hpp"
+#include <vsomeip/vsomeip_sec.h>
#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<routing_manager_stub> {
public:
@@ -44,10 +56,9 @@ public:
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 @@ public:
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<endpoint>& _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<endpoint> &_target, client_t _client,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major,
+ event_t _event, const std::shared_ptr<debounce_filter_t> &_filter,
remote_subscription_id_t _id);
bool send_unsubscribe(const std::shared_ptr<endpoint>& _target,
@@ -85,16 +98,18 @@ public:
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<service_data_t>& _requests);
- void handle_requests(const client_t _client, std::set<service_data_t>& _requests);
+ void handle_credentials(const client_t _client, std::set<protocol::service> &_requests);
+ void handle_requests(const client_t _client, std::set<protocol::service> &_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> &_policy,
const std::shared_ptr<payload> &_payload,
@@ -119,23 +134,29 @@ public:
bool add_requester_policies(uid_t _uid, gid_t _gid,
const std::set<std::shared_ptr<policy> > &_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<byte_t> &_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 @@ private:
(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<std::pair<uint32_t, uint32_t>> _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<protocol::routing_info_entry> &&_entries);
+ void send_client_credentials(client_t _target, std::set<std::pair<uint32_t, uint32_t>> &_credentials);
void on_client_id_timer_expired(boost::system::error_code const &_error);
@@ -199,13 +228,17 @@ private:
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 @@ private:
std::set<client_t> used_client_ids_;
std::mutex used_client_ids_mutex_;
- std::shared_ptr<endpoint> endpoint_;
+ std::shared_ptr<endpoint> root_; // Routing manager endpoint
+
std::shared_ptr<endpoint> local_receiver_;
std::mutex local_receiver_mutex_;
@@ -229,8 +263,8 @@ private:
std::condition_variable client_registration_condition_;
std::map<client_t, std::vector<registration_type_e>> pending_client_registrations_;
+ std::map<client_t, std::pair<boost::asio::ip::address, port_t> > internal_client_ports_;
const std::uint32_t max_local_message_size_;
- static const std::vector<byte_t> 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 @@ private:
std::map<client_t, std::map<service_t, std::map<instance_t, std::pair<major_version_t, minor_version_t> > > > service_requests_;
std::map<client_t, std::set<client_t>> connection_matrix_;
- std::map<client_t, std::vector<byte_t>> client_routing_info_;
- std::map<client_t, std::vector<byte_t>> offered_services_info_;
- std::map<client_t, std::vector<byte_t>> client_credentials_info_;
-
std::mutex pending_security_updates_mutex_;
pending_security_update_id_t pending_security_update_id_;
std::map<pending_security_update_id_t, std::unordered_set<client_t>> pending_security_updates_;
@@ -262,6 +292,14 @@ private:
std::set<std::shared_ptr<policy> >
>
> requester_policies_;
+
+
+#if defined(__linux__) || defined(ANDROID)
+ // netlink connector for internal network
+ // (replacement for Unix Domain Sockets if configured)
+ std::shared_ptr<netlink_connector> 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 6ad0ab1..c55dd86 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 <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include <vsomeip/handler.hpp>
+#include <vsomeip/vsomeip_sec.h>
+
#include "types.hpp"
namespace vsomeip_v3 {
@@ -28,57 +35,59 @@ public:
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<eventgroup_t> &_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<eventgroup_t> &_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<debounce_filter_t> &_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<endpoint> find_local(client_t _client) = 0;
@@ -86,8 +95,9 @@ public:
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 @@ public:
virtual std::shared_ptr<endpoint_manager_impl> 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<client_t> 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<client_t> 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 a405cf0..5ea4c18 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 @@ public:
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 @@ public:
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 c301b33..d59015c 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<service_t,
- std::map<instance_t,
- std::shared_ptr<serviceinfo> > > services_t;
+using services_t = std::map<service_t, std::map<instance_t, std::shared_ptr<serviceinfo>>>;
class eventgroupinfo;
-typedef std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t,
- std::shared_ptr<
- eventgroupinfo> > > > eventgroups_t;
+using eventgroups_t =
+ std::map<service_t,
+ std::map<instance_t, std::map<eventgroup_t, std::shared_ptr<eventgroupinfo>>>>;
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 b63022c..e4eed17 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 <chrono>
#include <iomanip>
#include <sstream>
+#include <thread>
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
@@ -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<payload> event::get_payload() const {
+std::shared_ptr<payload>
+event::get_payload() const {
+
std::lock_guard<std::mutex> its_lock(mutex_);
- return (message_->get_payload());
+ return (current_->get_payload());
}
-bool event::set_payload_dont_notify(const std::shared_ptr<payload> &_payload) {
+void
+event::update_payload() {
+
std::lock_guard<std::mutex> 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> &_payload, bool _force) {
+void
+event::set_payload(const std::shared_ptr<payload> &_payload, bool _force) {
+
std::lock_guard<std::mutex> 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> &_payload, client_t _client,
+void
+event::set_payload(const std::shared_ptr<payload> &_payload, client_t _client,
bool _force) {
+
std::lock_guard<std::mutex> 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> &_payload,
+void
+event::set_payload(const std::shared_ptr<payload> &_payload,
const client_t _client,
- const std::shared_ptr<endpoint_definition>& _target,
- bool _force) {
+ const std::shared_ptr<endpoint_definition> &_target) {
+
std::lock_guard<std::mutex> 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> &_payload) {
+bool
+event::set_payload_notify_pending(const std::shared_ptr<payload> &_payload) {
+
std::lock_guard<std::mutex> 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<std::mutex> its_lock(mutex_);
if (_force) {
is_set_ = false;
stop_cycle();
- message_->set_payload(std::make_shared<payload_impl>());
+ current_->set_payload(std::make_shared<payload_impl>());
} else {
if (is_provided_) {
is_set_ = false;
stop_cycle();
- message_->set_payload(std::make_shared<payload_impl>());
+ current_->set_payload(std::make_shared<payload_impl>());
}
}
}
-void event::set_update_cycle(std::chrono::milliseconds &_cycle) {
+void
+event::set_update_cycle(std::chrono::milliseconds &_cycle) {
+
if (is_provided_) {
std::lock_guard<std::mutex> 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<std::mutex> its_lock(mutex_);
if (_epsilon_change_func) {
- std::lock_guard<std::mutex> its_lock(mutex_);
epsilon_change_func_ = _epsilon_change_func;
}
}
-const std::set<eventgroup_t> event::get_eventgroups() const {
+std::set<eventgroup_t>
+event::get_eventgroups() const {
+
std::set<eventgroup_t> its_eventgroups;
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
@@ -246,7 +305,9 @@ const std::set<eventgroup_t> event::get_eventgroups() const {
return its_eventgroups;
}
-std::set<eventgroup_t> event::get_eventgroups(client_t _client) const {
+std::set<eventgroup_t>
+event::get_eventgroups(client_t _client) const {
+
std::set<eventgroup_t> its_eventgroups;
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
@@ -257,23 +318,29 @@ std::set<eventgroup_t> 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<std::mutex> its_lock(eventgroups_mutex_);
if (eventgroups_.find(_eventgroup) == eventgroups_.end())
eventgroups_[_eventgroup] = std::set<client_t>();
}
-void event::set_eventgroups(const std::set<eventgroup_t> &_eventgroups) {
+void
+event::set_eventgroups(const std::set<eventgroup_t> &_eventgroups) {
+
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
for (auto e : _eventgroups)
eventgroups_[e] = std::set<client_t>();
}
-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<std::mutex> 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<endpoint_definition> &_target) {
+
if (_target) {
std::lock_guard<std::mutex> 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<endpoint_definition> &_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<std::mutex> 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<std::mutex> 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> &_payload, bool _force) {
- std::shared_ptr<payload> 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> &_payload,
+ bool _force) {
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ return (prepare_update_payload_unlocked(_payload, _force));
}
-void event::reset_payload(const std::shared_ptr<payload> &_payload) {
- std::shared_ptr<payload> its_new_payload
+bool
+event::prepare_update_payload_unlocked(
+ const std::shared_ptr<payload> &_payload, bool _force) {
+
+ // Copy payload to avoid manipulation from the outside
+ std::shared_ptr<payload> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<debounce_filter_t> &_filter,
+ client_t _client, bool _force) {
+
std::lock_guard<std::mutex> 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<payload> &_old,
+ const std::shared_ptr<payload> &_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<std::mutex> 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<std::chrono::milliseconds>(
+ 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<std::mutex> its_lock(eventgroups_mutex_);
auto find_eventgroup = eventgroups_.find(_eventgroup);
if (find_eventgroup != eventgroups_.end())
find_eventgroup->second.erase(_client);
+
+ std::lock_guard<std::mutex> 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<std::mutex> 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<client_t> event::get_subscribers() {
+std::set<client_t>
+event::get_subscribers() {
+
std::set<client_t> its_subscribers;
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
for (const auto &e : eventgroups_)
@@ -457,13 +669,79 @@ std::set<client_t> event::get_subscribers() {
return its_subscribers;
}
-void event::clear_subscribers() {
+std::set<client_t>
+event::get_filtered_subscribers(bool _force) {
+
+ std::set<client_t> its_subscribers(get_subscribers());
+ std::set<client_t> its_filtered_subscribers;
+
+ std::shared_ptr<payload> 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<std::mutex> 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<client_t>
+event::update_and_get_filtered_subscribers(
+ const std::shared_ptr<payload> &_payload, bool _is_from_remote) {
+
+ std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<payload> &_lhs,
+bool
+event::has_changed(const std::shared_ptr<payload> &_lhs,
const std::shared_ptr<payload> &_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<payload> &_lhs,
its_pos++;
}
}
- return is_change;
+ return (is_change);
}
-std::set<client_t> event::get_subscribers(eventgroup_t _eventgroup) {
+std::set<client_t>
+event::get_subscribers(eventgroup_t _eventgroup) {
+
std::set<client_t> its_subscribers;
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
auto found_eventgroup = eventgroups_.find(_eventgroup);
@@ -535,7 +831,9 @@ std::set<client_t> 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<std::mutex> 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<endpoint_definition> &_target) {
+
std::lock_guard<std::mutex> 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 50bbdb6..c41f55b 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<std::shared_ptr<event> > eventgroupinfo::get_events() const {
+std::set<std::shared_ptr<event> > eventgroupinfo::get_events() const {
std::lock_guard<std::mutex> its_lock(events_mutex_);
return events_;
}
void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) {
+
+ if (_event == nullptr) {
+ VSOMEIP_ERROR << __func__ << ": Received ptr is null";
+ return;
+ }
+
std::lock_guard<std::mutex> its_lock(events_mutex_);
events_.insert(_event);
@@ -158,6 +164,12 @@ void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) {
}
void eventgroupinfo::remove_event(const std::shared_ptr<event>& _event) {
+
+ if (_event == nullptr) {
+ VSOMEIP_ERROR << __func__ << ": Received ptr is null";
+ return;
+ }
+
std::lock_guard<std::mutex> 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<endpoint_definition> its_subscriber;
std::set<std::shared_ptr<event> > its_events;
{
std::lock_guard<std::mutex> 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<remote_subscription> &_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<remote_subscription> &_subscription) {
+
+ if (_subscription == nullptr) {
+ VSOMEIP_ERROR << __func__ << ": Received ptr is null";
+ return id_;
+ }
std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
update_id();
@@ -419,7 +448,6 @@ void
eventgroupinfo::send_initial_events(
const std::shared_ptr<endpoint_definition> &_reliable,
const std::shared_ptr<endpoint_definition> &_unreliable) const {
-
std::set<std::shared_ptr<event> > 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 cb04d93..3c95108 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 c787a9e..49dcffb 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 <vsomeip/internal/logger.hpp>
#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<deserializer>(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<std::mutex> its_env_lock(env_mutex_);
+ return env_;
+}
+
+void routing_manager_base::set_client_host(const std::string &_client_host) {
+
+ std::lock_guard<std::mutex> 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_base>& _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<cfg::debounce> its_debounce
- = configuration_->get_debounce(_service, _instance, _notifier);
+ std::shared_ptr<debounce_filter_t> 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<payload> &_old,
const std::shared_ptr<payload> &_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<std::chrono::milliseconds>(
- 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<std::chrono::milliseconds>(
+ 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<client_t> 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<event_t> 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<std::mutex> 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<std::mutex> 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<debounce_filter_t> &_filter) {
+
+ (void)_major;
+ (void)_sec_client;
- (void) _major;
- (void)_uid;
- (void)_gid;
std::set<event_t> 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<std::mutex> 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> _payload,
bool _force) {
+
std::shared_ptr<event> 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<event> 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> _message) {
+ std::shared_ptr<message> _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<std::tuple<service_t, instance_t, eventgroup_t>>& _subscribed_eventgroups,
- bool _remove_uid) {
+ bool _remove_sec_client) {
- std::pair<uid_t, gid_t> 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<event> 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<endpoint> 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<endpoint>& _target, client_t _client,
+ std::shared_ptr<endpoint> &_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<byte_t> 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<byte_t>(_data, _data + _size));
+
+ std::vector<byte_t> 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<event_t> *_already_subscribed_events) {
+ event_t _event, const std::shared_ptr<debounce_filter_t> &_filter,
+ client_t _client, std::set<event_t> *_already_subscribed_events) {
+
bool is_inserted(false);
if (_event != ANY_EVENT) { // subscribe to specific event
std::shared_ptr<event> 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<eventgroupinfo> 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<serializer> 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<deserializer> 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<std::mutex> 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<std::mutex> its_lock(guests_mutex_);
+ guests_[_client] = std::make_pair(_address, _port);
+}
+
+void
+routing_manager_base::remove_guest(client_t _client) {
+
+ std::lock_guard<std::mutex> 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 0000000..378ab5d
--- /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 <unistd.h>
+#endif
+
+#include <climits>
+#include <forward_list>
+#include <future>
+#include <iomanip>
+#include <mutex>
+#include <thread>
+#include <unordered_set>
+
+#include <vsomeip/constants.hpp>
+#include <vsomeip/runtime.hpp>
+#include <vsomeip/internal/logger.hpp>
+
+#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<std::tuple<service_t, instance_t> > & _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<endpoint_manager_base>(this, io_, configuration_));
+ {
+ std::lock_guard<std::mutex> 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<netlink_connector>(
+ 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<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(request_timer_mutex_);
+ request_debounce_timer_.cancel();
+ }
+
+ if (receiver_) {
+ receiver_->stop();
+ }
+ receiver_ = nullptr;
+
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> its_lock(local_services_mutex_);
+ local_services_.clear();
+ }
+
+ is_local_link_available_ = false;
+ }
+ }
+ }
+}
+#endif // __linux__ || ANDROID
+
+std::shared_ptr<configuration> routing_manager_client::get_configuration() const {
+ return host_->get_configuration();
+}
+
+std::string routing_manager_client::get_env(client_t _client) const {
+
+ std::lock_guard<std::mutex> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<int>(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<std::mutex> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<int>(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<std::mutex> 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<protocol::service> requests;
+ requests.insert(request);
+ send_request_services(requests);
+ }
+ requests_.insert(request);
+ } else {
+ requests_to_debounce_.insert(request);
+ std::lock_guard<std::mutex> 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<routing_manager_client>(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<std::mutex> 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<eventgroup_t> &_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<std::mutex> 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<std::mutex> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<debounce_filter_t> &_filter) {
+
+ (void)_client;
+
+ std::lock_guard<std::mutex> 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<debounce_filter_t> &_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<byte_t> 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<std::mutex> 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<int>(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<byte_t> 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<std::mutex> 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<int>(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<byte_t> 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<std::mutex> 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<int>(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<std::mutex> 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<byte_t> 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<std::mutex> 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<int>(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<std::mutex> 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<std::uint32_t>(_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<endpoint> 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<std::mutex> 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<endpoint_definition> &_target,
+ std::shared_ptr<message> _message) {
+
+ (void)_client;
+ (void)_target;
+ (void)_message;
+
+ return (false);
+}
+
+bool routing_manager_client::send_to(
+ const std::shared_ptr<endpoint_definition> &_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) {
+
+ _endpoint->set_connected(true);
+ _endpoint->set_established(true);
+ {
+ std::lock_guard<std::mutex> its_lock(sender_mutex_);
+ if (_endpoint != sender_) {
+ return;
+ }
+ }
+ is_connected_ = true;
+ assign_client();
+}
+
+void routing_manager_client::on_disconnect(const std::shared_ptr<endpoint>& _endpoint) {
+ {
+ std::lock_guard<std::mutex> 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<byte_t> 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<message_impl> 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<int>(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<std::recursive_mutex> 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<event_t> 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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<byte_t> 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<int>(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<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
+ return;
+ }
+#endif
+ {
+ std::lock_guard<std::mutex> 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<state_type_e>(inner_state_type_e::ST_REGISTERED));
+ }
+ }
+ break;
+ }
+
+ case protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT:
+ {
+ {
+ std::lock_guard<std::mutex> 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<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
+
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<int>(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<debounce_filter_t> filter_;
+ vsomeip_sec_client_t sec_client_;
+ std::string env_;
+ };
+ std::lock_guard<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
+ std::forward_list<struct subscription_info> subscription_actions;
+ if (pending_incoming_subscriptions_.size()) {
+ {
+ std::lock_guard<std::mutex> 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<std::recursive_mutex> 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<std::pair<service_t, instance_t>> 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<client_t, std::string> &_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<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
+
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> its_lock(sender_mutex_);
+ if (sender_) {
+ sender_->stop();
+ }
+ return;
+ }
+#endif
+
+ std::lock_guard<std::mutex> 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<byte_t> 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<int>(its_error) << ")";
+ return;
+ }
+
+ std::lock_guard<std::mutex> its_state_lock(state_mutex_);
+ if (is_connected_) {
+ std::lock_guard<std::mutex> 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<uint32_t>(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<routing_manager_client>(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<byte_t> 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<std::mutex> 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<routing_manager_client>(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<byte_t> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<protocol::service> &_requests) {
+
+ if (!_requests.size()) {
+ return;
+ }
+
+ protocol::request_service_command its_command;
+ its_command.set_client(get_client());
+ its_command.set_services(_requests);
+
+ std::vector<byte_t> 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<std::mutex> 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<int>(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<byte_t> 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<std::mutex> 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<vsomeip_v3::routing_manager_client::event_data_t>::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<byte_t> 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<std::mutex> 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<eventgroup_t> &_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<byte_t> 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<std::mutex> 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> &_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<event> 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<eventgroup_t> 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<event> 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<event_t, std::shared_ptr<event> > events;
+ {
+ std::lock_guard<std::mutex> 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<event_t> &_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<message> 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<serializer> its_serializer(get_serializer());
+ if (its_serializer->serialize(its_notification.get())) {
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<std::mutex> 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<debounce_filter_t> &_filter,
+ client_t _client) {
+
+ std::lock_guard<std::mutex> 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<eventgroup_t> 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<event> 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<std::mutex> 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<std::mutex> 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<routing_manager_client>(shared_from_this()),
+ std::placeholders::_1));
+ return;
+ }
+ }
+ }
+ }
+ {
+ std::lock_guard<std::mutex> 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) {
+
+ _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<std::mutex> its_lock(state_mutex_);
+ should_reconnect = is_started_;
+ }
+ if (should_reconnect) {
+ std::map<client_t, std::string> its_known_clients;
+ {
+ std::lock_guard<std::mutex> 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<byte_t> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<byte_t> 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<std::mutex> 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<policy> its_policy(std::make_shared<policy>());
+ boost::icl::interval_set<uint32_t> 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<uid_t>::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<std::mutex> 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<std::mutex> 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 07c0740..4ebca55 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 <memory>
#include <sstream>
#include <forward_list>
+#include <thread>
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
#include <unistd.h>
#include <cstdio>
#include <time.h>
@@ -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<std::mutex> 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<client_t> 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<routing_manager_stub>(this, configuration_);
- stub_->init();
+ if (configuration_->is_routing_enabled()) {
+ stub_ = std::make_shared<routing_manager_stub>(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<netlink_connector>(
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<std::mutex> its_lock(memory_log_timer_mutex_);
boost::system::error_code ec;
@@ -231,7 +287,7 @@ void routing_manager_impl::stop() {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<protocol::service> requests;
+ requests.insert(its_request);
- service_data_t request = { _service, _instance, _major, _minor };
- std::set<service_data_t> 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<serviceinfo> 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<debounce_filter_t> &_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<std::mutex> 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<std::mutex> 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<std::mutex> 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> _message) {
- return routing_manager_base::send(_client, _message);
+ std::shared_ptr<message> _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<endpoint> 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<serviceinfo> 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<event> 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<endpoint_definition> &_target,
std::shared_ptr<message> _message) {
+
bool is_sent(false);
std::shared_ptr<serializer> its_serializer(get_serializer());
@@ -1050,19 +1114,17 @@ bool routing_manager_impl::send_to(
bool routing_manager_impl::send_to(
const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size, instance_t _instance) {
+
std::shared_ptr<endpoint> 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<eventgroup_t> &_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<std::shared_ptr<endpoint_definition> > 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<endpoint>(), _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<endpoint>(), !_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<message_type_e>(_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<message_type_e>(_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<serviceinfo> its_info = find_service(_service, _instance);
+ if (its_info) {
+ std::shared_ptr<endpoint> _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<eventgroupinfo> 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<payload> 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<endpoint> 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<endpoint> 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<endpoint> 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<uint32_t>(_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<std::pair<service_t, instance_t>> services_to_release_;
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(requested_services_mutex_);
- for(const auto &client_id : requested_services_) {
- auto found_service = client_id.second.find(_service);
- if (found_service != client_id.second.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- for (const auto &major_minor_pair : found_instance->second) {
- if ((major_minor_pair.first == _major
- || _major == DEFAULT_MAJOR
- || major_minor_pair.first == ANY_MAJOR)
- && (major_minor_pair.second <= _minor
- || _minor == DEFAULT_MINOR
- || major_minor_pair.second == ANY_MINOR)) {
- // 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<std::mutex> 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<endpoint> 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<endpoint> 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<std::mutex> 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<endpoint> 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<std::mutex> its_lock(requested_services_mutex_);
- for(const auto &client_id : requested_services_) {
- auto found_service = client_id.second.find(_service);
- if (found_service != client_id.second.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- for (const auto &major_minor_pair : found_instance->second) {
- if ((major_minor_pair.first == _major
- || _major == DEFAULT_MAJOR
- || major_minor_pair.first == ANY_MAJOR)
- && (major_minor_pair.second <= _minor
- || _minor == DEFAULT_MINOR
- || major_minor_pair.second == ANY_MINOR)) {
- if (_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<endpoint> 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<endpoint> 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<std::shared_ptr<event>> 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<endpoint> 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<local_client_endpoint_base_impl>
- its_old_endpoint
- = std::dynamic_pointer_cast<local_client_endpoint_base_impl>(
- find_local(its_stored_client));
+ auto its_old_endpoint = find_local(its_stored_client);
if (its_old_endpoint) {
std::lock_guard<std::mutex> 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<std::tuple<client_t, service_t, instance_t, major_version_t,
minor_version_t>> its_offers;
@@ -3619,17 +3652,18 @@ std::shared_ptr<endpoint_manager_impl> 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<debounce_filter_t> &_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<std::mutex> 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<std::shared_ptr<serviceinfo>> _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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<minor_version_t, std::set<client_t> >;
+ using major_map_t = std::map<major_version_t, minor_map_t>;
+ using instance_map_t = std::map<instance_t, major_map_t>;
+
+ 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<std::pair<service_t, instance_t> >
+routing_manager_impl::get_requested_services(client_t _client) {
+ std::lock_guard<std::mutex> ist_lock(requested_services_mutex_);
+ std::vector<std::pair<service_t, instance_t>> 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<client_t>
+routing_manager_impl::get_requesters(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
+
+ std::lock_guard<std::mutex> ist_lock(requested_services_mutex_);
+ return (get_requesters_unlocked(_service, _instance, _major, _minor));
+}
+
+std::set<client_t>
+routing_manager_impl::get_requesters_unlocked(
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
+
+ std::set<client_t> 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<eventgroup_t>
@@ -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<debounce_filter_t> &_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<event> 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<std::uint32_t>(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<std::mutex> 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<routing_manager_stub_host>(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<routing_manager_stub_host>(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<boost::asio::steady_timer> 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>& _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<std::mutex> 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<event> 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<std::mutex> 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<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t,
+ std::shared_ptr<eventgroupinfo> > > >its_eventgroups;
+ {
+ std::lock_guard<std::mutex> 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 06573a5..0000000
--- 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 <climits>
-#include <iomanip>
-#include <mutex>
-#include <unordered_set>
-#include <future>
-#include <forward_list>
-
-#include <vsomeip/constants.hpp>
-#include <vsomeip/runtime.hpp>
-#include <vsomeip/internal/logger.hpp>
-
-#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<std::tuple<service_t, instance_t> > & _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<endpoint_manager_base>(this, io_, configuration_));
- {
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
- }
-}
-
-void routing_manager_proxy::start() {
- is_started_ = true;
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(request_timer_mutex_);
- request_debounce_timer_.cancel();
- }
-
- if (receiver_) {
- receiver_->stop();
- }
- receiver_ = nullptr;
-
- {
- std::lock_guard<std::mutex> 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<configuration> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<service_data_t> requests;
- requests.insert(request);
- send_request_services(requests);
- }
- requests_.insert(request);
- } else {
- requests_to_debounce_.insert(request);
- std::lock_guard<std::mutex> 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<routing_manager_proxy>(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<std::mutex> 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<eventgroup_t> &_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<std::mutex> 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<std::mutex> 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<std::mutex> 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<byte_t>(_is_provided);
-
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::uint32_t>(_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<endpoint> 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<std::mutex> 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<endpoint_definition> &_target,
- std::shared_ptr<message> _message) {
- (void)_client;
- (void)_target;
- (void)_message;
- return (false);
-}
-
-bool routing_manager_proxy::send_to(
- const std::shared_ptr<endpoint_definition> &_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) {
- _endpoint->set_connected(true);
- _endpoint->set_established(true);
- {
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- if (_endpoint != sender_) {
- return;
- }
- }
- is_connected_ = true;
- assign_client();
-}
-
-void routing_manager_proxy::on_disconnect(const std::shared_ptr<endpoint>& _endpoint) {
-
- bool is_disconnected((_endpoint == sender_));
- if (is_disconnected) {
- {
- std::lock_guard<std::mutex> 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<message_impl> 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<std::uint16_t>(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<std::recursive_mutex> 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<event_t> 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<policy> its_policy(std::make_shared<policy>());
- 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<policy> its_policy(std::make_shared<policy>());
- // 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<std::mutex> 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<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
- return;
- }
-#endif
- {
- std::lock_guard<std::mutex> 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<state_type_e>(inner_state_type_e::ST_REGISTERED));
-
- }
- } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) {
- {
- std::lock_guard<std::mutex> 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<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
-
- {
- std::lock_guard<std::mutex> 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<std::mutex> its_lock(known_clients_mutex_);
- known_clients_.insert(its_client);
- }
- {
- std::lock_guard<std::mutex> its_lock(local_services_mutex_);
- local_services_[its_service][its_instance] = std::make_tuple(its_major, its_minor, its_client);
- }
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
- std::forward_list<struct subscription_info> subscription_actions;
- if (pending_incoming_subscripitons_.size()) {
- {
- std::lock_guard<std::mutex> 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<std::recursive_mutex> 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<std::pair<service_t, instance_t>> 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<client_t> &_clients) {
- auto its_security = security_impl::get();
- if (!its_security)
- return;
-
- // inform host about its own registration state changes
- host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
-
- {
- std::lock_guard<std::mutex> 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<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->stop();
- }
- return;
- }
-#endif
-
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->restart();
- }
-}
-
-void routing_manager_proxy::assign_client() {
- std::vector<byte_t> its_command;
-
- std::string its_name(host_->get_name());
- uint32_t its_size(static_cast<uint32_t>(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<std::mutex> its_state_lock(state_mutex_);
- if (is_connected_) {
- std::lock_guard<std::mutex> 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<uint32_t>(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<routing_manager_proxy>(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<std::mutex> 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<routing_manager_proxy>(shared_from_this()),
- std::placeholders::_1));
- }
- }
-}
-
-void routing_manager_proxy::deregister_application() {
- std::vector<byte_t> 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<std::mutex> 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<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->send(its_pong, sizeof(its_pong));
- }
- }
-}
-
-void routing_manager_proxy::send_request_services(std::set<service_data_t>& _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<std::uint32_t>::max)()) {
- VSOMEIP_ERROR<< "routing_manager_proxy::send_request_services too many"
- << " requests (" << std::dec << its_size << "), returning.";
- return;
- }
-
- std::vector<byte_t> 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<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->send(&its_command[0],
- static_cast<std::uint32_t>(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<std::mutex> 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<eventgroup_t> &_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<std::uint32_t>::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<std::uint32_t>(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<byte_t>(_type);
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7]
- = static_cast<byte_t>(_is_provided);
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8]
- = static_cast<byte_t>(_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<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->send(its_command, static_cast<std::uint32_t>(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> &_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<event> 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<eventgroup_t> 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<event> 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<event_t, std::shared_ptr<event> > events;
- {
- std::lock_guard<std::mutex> 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<event_t> &_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<message> 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<serializer> its_serializer(get_serializer());
- if (its_serializer->serialize(its_notification.get())) {
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<eventgroup_t> 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<event> 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<std::mutex> 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<std::mutex> 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<routing_manager_proxy>(shared_from_this()),
- std::placeholders::_1));
- return;
- }
- }
- }
- }
- {
- std::lock_guard<std::mutex> 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) {
- _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<std::mutex> its_lock(state_mutex_);
- should_reconnect = is_started_;
- }
- if (should_reconnect) {
- std::unordered_set<client_t> its_known_clients;
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->send(its_command, sizeof(its_command));
- }
- }
-}
-
-void routing_manager_proxy::resend_provided_event_registrations() {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<policy> its_policy(std::make_shared<policy>());
-
- boost::icl::interval_set<uint32_t> 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<uid_t>::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<std::mutex> 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<std::mutex> 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 406b0d9..16ad36d 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 <boost/system/error_code.hpp>
#include <vsomeip/constants.hpp>
+#include <vsomeip/error.hpp>
+#include <vsomeip/payload.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/runtime.hpp>
-#include <vsomeip/error.hpp>
+#include <vsomeip/structured_types.hpp>
#include <vsomeip/internal/logger.hpp>
#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<byte_t> 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>& _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<std::mutex> 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<payload> 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<payload> 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<byte_t> 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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<service_data_t> 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<int>(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<protocol::service> 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<int>(its_error) << ")";
- std::set<eventgroup_t> 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<int>(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<int>(its_error) << ")";
+ break;
+ }
- std::lock_guard<std::mutex> 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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(its_error) << ")";
+ break;
}
+#endif // !VSOMEIP_DISABLE_SECURITY
+ default:
+ VSOMEIP_WARNING << __func__ << ": Received an unhandled command ("
+ << std::dec << static_cast<int>(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<std::mutex> 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<std::shared_ptr<policy> > 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<uid_t, gid_t> its_uid_gid;
- std::set<std::shared_ptr<policy> > 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<byte_t> 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<endpoint> 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<std::mutex> 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<client_t, std::vector<registration_type_e>> 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<std::mutex> 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<std::mutex> 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<netlink_connector>(
+ 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<std::mutex> 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<byte_t> 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<const byte_t*>(&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<byte_t> 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<const byte_t*>(&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<std::pair<uint32_t, uint32_t>> _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<const byte_t*>(&std::get<0>(its_credentials))[i]);
- }
- //gid
- for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&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<std::pair<uint32_t, uint32_t>> &_credentials) {
std::shared_ptr<endpoint> 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<byte_t> 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<const byte_t*>(&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<endpoint> 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<endpoint> 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<byte_t> 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<int>(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<const byte_t*>(&_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<const byte_t*>(&_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<const byte_t*>(&its_service_entry_size)[i]);
- }
- for (uint32_t i = 0; i < sizeof(service_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_service)[i]);
- }
- // Instance
- for (uint32_t i = 0; i < sizeof(instance_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_instance)[i]);
- }
- // Major version
- for (uint32_t i = 0; i < sizeof(major_version_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_major)[i]);
- }
- // Minor version
- for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_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<protocol::routing_info_entry> 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<protocol::routing_info_entry> &&_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<const byte_t*>(&_entry)[i]);
- }
+ std::vector<byte_t> 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<const byte_t*>(&its_service_entry_size)[i]);
- }
- //Service
- for (uint32_t i = 0; i < sizeof(service_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_service)[i]);
- }
- // Instance
- for (uint32_t i = 0; i < sizeof(instance_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_instance)[i]);
- }
- // Major version
- for (uint32_t i = 0; i < sizeof(major_version_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_major)[i]);
- }
- // Minor version
- for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) {
- its_command.push_back(
- reinterpret_cast<const byte_t*>(&_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<int>(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<uint32_t, uint32_t> 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<uint32_t, uint32_t> 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<uint32_t, uint32_t> 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<byte_t> &_command) const {
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
for (const auto& a : routing_info_) {
@@ -1376,42 +1290,50 @@ void routing_manager_stub::broadcast(const std::vector<byte_t> &_command) const
}
}
-bool routing_manager_stub::send_subscribe(const std::shared_ptr<endpoint>& _target,
- client_t _client, service_t _service, instance_t _instance,
+bool routing_manager_stub::send_subscribe(
+ const std::shared_ptr<endpoint>& _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<debounce_filter_t> &_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<byte_t> 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<byte_t> 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<byte_t> 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<endpoint> 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<endpoint> 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<byte_t> 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<endpoint> 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<endpoint> 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<byte_t> 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<byte_t> 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<endpoint_manager_base>(
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<endpoint> its_endpoint = host_->find_local(_client);
- if (!its_endpoint) {
- return false;
- }
- {
+ bool has_sent(false);
+
+ std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
+ if (its_endpoint) {
std::lock_guard<std::mutex> 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<std::chrono::milliseconds>(
- 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<std::chrono::milliseconds>(
+ 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<byte_t> 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<service_data_t>& _requests) {
+void routing_manager_stub::handle_credentials(const client_t _client, std::set<protocol::service> &_requests) {
if (!_requests.size()) {
return;
}
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
std::set<std::pair<uint32_t, uint32_t>> its_credentials;
- std::pair<uint32_t, uint32_t> 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<client_t> its_offering_clients;
@@ -1891,65 +1852,79 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set<s
// search for UID / GID linked with the client ID that offers the requested services
for (auto its_offering_client : its_offering_clients) {
- std::pair<uint32_t, uint32_t> 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<service_data_t>& _requests) {
- if (!_requests.size()) {
+void routing_manager_stub::handle_requests(const client_t _client, std::set<protocol::service> &_requests) {
+
+ if (_requests.empty())
return;
- }
- bool service_available(false);
+
+ boost::asio::ip::address its_address;
+ port_t its_port;
+
+ std::vector<protocol::routing_info_entry> its_entries;
std::lock_guard<std::mutex> 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<client_t> 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::set<serv
if (found_service != found_client->second.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<endpoint> 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<byte_t> 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<std::mutex> 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>& _payload) {
(void)_uid;
+
std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
if (its_endpoint) {
std::vector<byte_t> 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<byte_t> its_command;
- std::size_t its_size(0);
- std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
- uint32_t its_policy_count = uint32_t(updated_security_policies_.size());
+ std::shared_ptr<endpoint> 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<std::mutex> 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<const byte_t*>(&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<byte_t> 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<const byte_t*>(&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<const byte_t*>(&its_length)[i]);
+ VSOMEIP_ERROR << __func__
+ << ": serializing distribute security policies ("
+ << static_cast<int>(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<byte_t> 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<endpoint> 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<int>(its_error)
+ << ")";
- std::shared_ptr<endpoint> 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<endpoint> 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<client_t> 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<std::recursive_mutex> 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<client_t>
std::vector<byte_t> its_policy_data;
if (p->serialize(its_policy_data)) {
std::vector<byte_t> 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<client_t>
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<endpoint> its_endpoint = host_->find_local(c);
if (its_endpoint)
its_endpoint->send(&its_message[0], static_cast<uint32_t>(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<std::shared_ptr<policy> > 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<byte_t> its_suspend(
- { VSOMEIP_SUSPEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
+ protocol::suspend_command its_command;
+
+ std::vector<byte_t> 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 324fcd7..fcdcbd8 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 37df949..5dc9ef8 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 <boost/asio/signal_set.hpp>
#include <boost/asio/steady_timer.hpp>
+#include <boost/asio/ip/address.hpp>
#include <vsomeip/export.hpp>
#include <vsomeip/application.hpp>
@@ -40,7 +41,8 @@ class application_impl: public application,
public routing_manager_host,
public std::enable_shared_from_this<application_impl> {
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 @@ public:
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 @@ public:
event_t _event, std::shared_ptr<payload> _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 @@ public:
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<configuration> get_configuration() const;
VSOMEIP_EXPORT std::shared_ptr<configuration_public> 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> &&_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<void(bool)> _accepted_cb);
+ eventgroup_t _eventgroup, client_t _client, const vsomeip_sec_client_t *_sec_client,
+ const std::string &_env, bool _subscribed, const std::function<void(bool)> &_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 @@ public:
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<std::pair<service_t, instance_t>> &_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 @@ public:
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 @@ public:
uint32_t _gid,
std::shared_ptr<policy> _policy,
std::shared_ptr<payload> _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<std::string, std::string>
+ 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 @@ private:
struct sync_handler {
- sync_handler(std::function<void()> _handler) :
+ sync_handler(const std::function<void()> &_handler) :
handler_(_handler),
service_id_(ANY_SERVICE),
instance_id_(ANY_INSTANCE),
@@ -247,7 +273,7 @@ private:
};
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 @@ private:
//
// 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 @@ private:
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 @@ private:
bool is_initialized_;
std::string name_;
+
+ std::string path_;
std::shared_ptr<configuration> configuration_;
- boost::asio::io_service io_;
+ boost::asio::io_context io_;
std::set<std::shared_ptr<std::thread> > io_threads_;
- std::shared_ptr<boost::asio::io_service::work> work_;
+ std::shared_ptr<boost::asio::io_context::work> work_;
// Proxy to or the Routing Manager itself
std::shared_ptr<routing_manager> routing_;
@@ -344,19 +375,25 @@ private:
mutable std::mutex members_mutex_;
// Availability handlers
- typedef std::map<major_version_t, std::map<minor_version_t, std::pair<availability_handler_t,
- bool>>> availability_major_minor_t;
+ using availability_major_minor_t =
+ std::map<major_version_t,
+ std::map<minor_version_t, std::pair<availability_state_handler_t, bool>>>;
std::map<service_t, std::map<instance_t, availability_major_minor_t>> availability_;
- mutable std::recursive_mutex availability_mutex_;
+ mutable std::mutex availability_mutex_;
// Availability
- mutable available_t available_;
+ using available_instance_t =
+ std::map<instance_t,
+ std::map<major_version_t, std::pair<minor_version_t, availability_state_e>>>;
+ using available_ext_t = std::map<service_t, available_instance_t>;
+ mutable available_ext_t available_;
// Subscription handlers
std::map<service_t,
std::map<instance_t,
std::map<eventgroup_t,
- std::pair<subscription_handler_t, async_subscription_handler_t>>>> subscription_;
+ std::pair<subscription_handler_sec_t,
+ async_subscription_handler_sec_t> > > > subscription_;
mutable std::mutex subscription_mutex_;
std::map<service_t,
std::map<instance_t, std::map<eventgroup_t,
@@ -418,8 +455,13 @@ private:
std::mutex subscription_status_handlers_mutex_;
std::mutex subscriptions_state_mutex_;
- std::map<std::tuple<service_t, instance_t, eventgroup_t, event_t>,
- subscription_state_e> subscription_state_;
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t,
+ std::map<event_t, subscription_state_e>
+ >
+ >
+ > subscription_state_;
std::mutex watchdog_timer_mutex_;
boost::asio::steady_timer watchdog_timer_;
@@ -432,12 +474,9 @@ private:
std::map<std::pair<service_t, instance_t>,
std::deque<std::shared_ptr<sync_handler> > > 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 ec49a42..b618ec4 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 @@ public:
std::shared_ptr<application> create_application(
const std::string &_name);
+ std::shared_ptr<application> create_application(
+ const std::string &_name, const std::string &_path);
std::shared_ptr<message> create_message(bool _reliable) const;
std::shared_ptr<message> create_request(bool _reliable) const;
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index 467bca2..e854958 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 <iomanip>
#include <iostream>
+#include <boost/asio/ip/host_name.hpp>
+#include <boost/asio/ip/tcp.hpp>
#include <boost/exception/diagnostic_information.hpp>
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
#include <dlfcn.h>
#include <sys/syscall.h>
#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<boost::asio::io_service::work>(io_)),
+ is_initialized_(false),
+ name_(_name),
+ path_(_path),
+ work_(std::make_shared<boost::asio::io_context::work>(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<configuration_plugin>(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<configuration>(
- std::make_shared<vsomeip_v3::cfg::configuration_impl>());
+ std::make_shared<vsomeip_v3::cfg::configuration_impl>(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<routing_manager_impl>(this);
} else {
VSOMEIP_INFO << "Instantiating routing manager [Proxy].";
- routing_ = std::make_shared<routing_manager_proxy>(this, client_side_logging_, client_side_logging_filter_);
+ routing_ = std::make_shared<routing_manager_client>(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<pid_t>(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<int>(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<int>(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<std::mutex> 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<std::recursive_mutex> its_lock(availability_mutex_);
- return is_available_unlocked(_service, _instance, _major, _minor);
+ std::lock_guard<std::mutex> 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<instance_t,
- std::map<major_version_t,
- minor_version_t >>::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<std::recursive_mutex> its_lock(availability_mutex_);
- return are_available_unlocked(_available, _service, _instance, _major, _minor);
+ std::lock_guard<std::mutex> 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> _message) {
@@ -840,15 +864,16 @@ void application_impl::send(std::shared_ptr<message> _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> _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<std::mutex> 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<std::recursive_mutex> 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<std::mutex> 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<std::mutex> handlers_lock(handlers_mutex_);
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
+ register_availability_handler_unlocked(_service, _instance,
+ _handler, _major, _minor);
+}
- std::shared_ptr<sync_handler> its_sync_handler
- = std::make_shared<sync_handler>([_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<std::mutex> handlers_lock(handlers_mutex_);
+
+ std::shared_ptr<sync_handler> its_sync_handler
+ = std::make_shared<sync_handler>([_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<std::recursive_mutex> its_lock(availability_mutex_);
+ std::lock_guard<std::mutex> 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<void(bool)> _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<void(bool)> &_accepted_cb) {
+
bool handler_found = false;
- std::pair<subscription_handler_t, async_subscription_handler_t> its_handlers;
+ std::pair<subscription_handler_sec_t, async_subscription_handler_sec_t> its_handlers;
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<subscription_status_handler_t> handlers;
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<configuration> 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<std::recursive_mutex> availability_lock(availability_mutex_);
+ std::lock_guard<std::mutex> 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<availability_handler_t> its_handlers;
+ availability_state_e _state, major_version_t _major, minor_version_t _minor) {
+
+ std::vector<availability_state_handler_t> its_handlers;
{
- std::lock_guard<std::recursive_mutex> availability_lock(availability_mutex_);
- if (_is_available == is_available_unlocked(_service, _instance, _major, _minor)) {
+ std::lock_guard<std::mutex> 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<sync_handler> its_sync_handler =
std::make_shared<sync_handler>(
- [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<std::mutex> 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<std::mutex> 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> &&_message) {
if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) {
if (!check_for_active_subscription(its_service, its_instance,
static_cast<event_t>(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<int>(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<sync_handler> 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<int>(syscall(SYS_gettid))
#endif
;
std::unique_lock<std::mutex> 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<sync_handler> &_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<std::recursive_mutex> availability_lock(availability_mutex_);
+ std::lock_guard<std::mutex> 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<int>(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<std::mutex> its_lock(start_stop_mutex_);
- while(!stopped_) {
- stop_cv_.wait(its_lock);
- }
+ stop_cv_.wait(its_lock, [this] {return stopped_; });
}
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(subscriptions_mutex_);
@@ -2157,7 +2356,7 @@ bool application_impl::check_for_active_subscription(service_t _service,
std::shared_ptr<event> 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<std::mutex> 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<sync_handler>&
}
-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<std::mutex> 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<std::mutex> 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<void(bool)> &_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<std::mutex> 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_manager_impl>(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_manager_impl>(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_manager_impl>(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_manager_impl>(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> _policy,
std::shared_ptr<payload> _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<debounce_filter_t>(_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_manager_impl>(routing_);
+ rm_impl->register_message_acceptance_handler(_handler);
+ }
+}
+
+std::map<std::string, std::string>
+application_impl::get_additional_data(const std::string &_plugin_name) {
+ if (configuration_) {
+ return configuration_->get_additional_data(name_, _plugin_name);
+ }
+ return std::map<std::string, std::string>();
}
} // namespace vsomeip_v3
diff --git a/implementation/runtime/src/runtime.cpp b/implementation/runtime/src/runtime.cpp
index 40bb455..b2fab88 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 <vsomeip/runtime.hpp>
-#include <vsomeip/plugin.hpp>
#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> 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 fc23ced..cf74b2f 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<application> runtime_impl::create_application(
const std::string &_name) {
+
+ return (create_application(_name, ""));
+}
+
+std::shared_ptr<application> runtime_impl::create_application(
+ const std::string &_name, const std::string &_path) {
static std::uint32_t postfix_id = 0;
std::lock_guard<std::mutex> 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> application = std::make_shared<application_impl>(its_name_);
- applications_[its_name_] = application;
+ std::shared_ptr<application> application
+ = std::make_shared<application_impl>(its_name, _path);
+ applications_[its_name] = application;
return application;
}
diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp
index 82f3eb9..3c9760c 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 a5a30ea..4dd3a86 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 <memory>
+#include <map>
#include <mutex>
+#include <unordered_set>
+#include <vector>
-#include <vsomeip/primitive_types.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+#include <vsomeip/export.hpp>
#include <vsomeip/internal/policy_manager.hpp>
+#include <vsomeip/vsomeip_sec.h>
#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<policy_manager> 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<policy_manager_impl> get();
+ policy_manager_impl();
+
+#ifndef VSOMEIP_DISABLE_SECURITY
+ // policy_manager interface
std::shared_ptr<policy> create_policy() const;
void print_policy(const std::shared_ptr<policy> &_policy) const;
@@ -36,8 +55,144 @@ public:
bool is_policy_update_allowed(uint32_t _uid,
std::shared_ptr<policy> &_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>& _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<policy>& _credentials_policy, client_t _client);
+
+ void get_requester_policies(const std::shared_ptr<policy> _policy,
+ std::set<std::shared_ptr<policy> > &_requesters) const;
+ void get_clients(uid_t _uid, gid_t _gid, std::unordered_set<client_t> &_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> &_policy,
+ const boost::property_tree::ptree::const_iterator &_tree);
+ void load_credential(const boost::property_tree::ptree &_tree,
+ boost::icl::interval_map<uid_t, boost::icl::interval_set<gid_t> > &_ids);
+ bool load_routing_credentials(const configuration_element &_element);
+ template<typename T_>
+ void load_interval_set(const boost::property_tree::ptree &_tree,
+ boost::icl::interval_set<T_> &_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<client_t> &_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<std::shared_ptr<policy> > any_client_policies_;
+
+ mutable boost::shared_mutex is_client_allowed_cache_mutex_;
+ mutable std::map<std::pair<uid_t, gid_t>,
+ std::set<std::tuple<service_t, instance_t, method_t> >
+ > 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_t> service_interface_whitelist_;
+
+ mutable std::mutex uid_whitelist_mutex_;
+ boost::icl::interval_set<uint32_t> 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<std::string, std::pair<std::string, std::map<std::string, bool>>> policy_extension_paths_;
+#endif // !VSOMEIP_DISABLE_SECURITY
+
+ bool is_configured_;
+ bool check_routing_credentials_;
+
+ mutable std::mutex routing_credentials_mutex_;
+ std::pair<uint32_t, uint32_t> routing_credentials_;
+
+ mutable std::mutex ids_mutex_;
+ std::map<client_t, vsomeip_sec_client_t> 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_t, std::set<client_t>, 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 03406c6..1affb0c 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 <memory>
-#include <unordered_set>
-
-#include <vsomeip/payload.hpp>
-#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/export.hpp>
+#include <vsomeip/vsomeip_sec.h>
namespace vsomeip_v3 {
-struct configuration_element;
-
-class security {
+class VSOMEIP_IMPORT_EXPORT security {
public:
- VSOMEIP_EXPORT static std::shared_ptr<security> 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>& _policy) = 0;
- virtual bool remove_security_policy(uint32_t _uid, uint32_t _gid) = 0;
-
- virtual bool get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid,
- std::set<client_t> &_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<uint32_t, uint32_t> &_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> _policy,
- std::set<std::shared_ptr<policy> > &_requesters) const = 0;
- virtual void get_clients(uid_t _uid, gid_t _gid,
- std::unordered_set<client_t> &_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 dfeea6b..0000000
--- 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 <map>
-#include <mutex>
-#include <vector>
-
-#include <boost/property_tree/ptree.hpp>
-
-#include "../include/policy.hpp"
-#include "../include/security.hpp"
-
-namespace vsomeip_v3 {
-
-class security_impl :
- public security {
-public:
- static std::shared_ptr<security_impl> 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>& _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<policy>& _credentials_policy, client_t _client);
-
- bool is_remote_client_allowed() const;
-
- bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &_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> &_policy) const;
-
- bool get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid, std::set<client_t> &_clients);
- bool remove_client_to_uid_gid_mapping(client_t _client);
-
- bool get_client_to_uid_gid_mapping(client_t _client, std::pair<uint32_t, uint32_t> &_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> _policy,
- std::set<std::shared_ptr<policy> > &_requesters) const;
- void get_clients(uid_t _uid, gid_t _gid, std::unordered_set<client_t> &_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> &_policy,
- const boost::property_tree::ptree::const_iterator &_tree);
- void load_credential(const boost::property_tree::ptree &_tree,
- boost::icl::interval_map<uid_t, boost::icl::interval_set<gid_t> > &_ids);
- bool load_routing_credentials(const configuration_element &_element);
- template<typename T_>
- void load_interval_set(const boost::property_tree::ptree &_tree,
- boost::icl::interval_set<T_> &_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<std::shared_ptr<policy> > any_client_policies_;
-
- mutable std::mutex any_client_policies_mutex_;
- std::map<client_t, std::pair<uint32_t, uint32_t> > ids_;
- std::map<std::pair<uint32_t, uint32_t>, std::set<client_t> > 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_t> service_interface_whitelist_;
-
- mutable std::mutex uid_whitelist_mutex_;
- boost::icl::interval_set<uint32_t> uid_whitelist_;
-
- mutable std::mutex routing_credentials_mutex_;
- std::pair<uint32_t, uint32_t> 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 260198a..b582712 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<uint32_t>(_data.size()
diff --git a/implementation/security/src/policy_manager.cpp b/implementation/security/src/policy_manager.cpp
index beae85c..ad1b52e 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>
policy_manager::get() {
- static std::shared_ptr<policy_manager> the_policy_manager
- = std::make_shared<policy_manager_impl>();
- 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 a816714..849a36b 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 <windows.h>
+ #include <stdlib.h>
+#endif
+
+#include <algorithm>
+#include <sstream>
+
#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<typename T_>
+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<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ for (const auto &p : any_client_policies_) {
+
+ std::lock_guard<std::mutex> 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<std::mutex> 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<boost::shared_mutex> 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<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ for (const auto &p : any_client_policies_) {
+ std::lock_guard<std::mutex> 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<boost::shared_mutex> 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<boost::shared_mutex> 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<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ for (const auto &p : any_client_policies_) {
+ std::lock_guard<std::mutex> 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<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ bool was_removed(false);
+ if (!any_client_policies_.empty()) {
+ std::vector<std::shared_ptr<policy>>::iterator p_it = any_client_policies_.begin();
+ while (p_it != any_client_policies_.end()) {
+ bool is_matching(false);
+ {
+ std::lock_guard<std::mutex> 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<boost::shared_mutex> 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> &_policy) {
+
+ boost::unique_lock<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ std::shared_ptr<policy> its_matching_policy;
+ for (auto p : any_client_policies_) {
+ std::lock_guard<std::mutex> 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<std::mutex> 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<service_t> 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<service_t> 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<boost::shared_mutex> 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> &_policy, client_t _client) {
+
+ bool was_found(false);
+ boost::unique_lock<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ for (const auto &p : any_client_policies_) {
+ bool has_uid(false), has_gid(false);
+
+ std::lock_guard<std::mutex> 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> &_policy) const {
+
+ bool is_uid_allowed(false);
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> its_lock(service_interface_whitelist_mutex_);
+ std::lock_guard<std::mutex> 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<std::mutex> 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> &_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> policy(std::make_shared<policy>());
+ bool allow_deny_set(false);
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ if (i->first == "credentials") {
+ boost::icl::interval_set<uid_t> its_uid_interval_set;
+ boost::icl::interval_set<gid_t> its_gid_interval_set;
+ boost::icl::discrete_interval<uid_t> its_uid_interval;
+ boost::icl::discrete_interval<gid_t> 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<uid_t> >(
+ its_uid, its_uid,
+ boost::icl::interval_bounds::closed());
+ } else {
+ its_uid_interval = boost::icl::construct<
+ boost::icl::discrete_interval<uid_t> >(
+ std::numeric_limits<uid_t>::min(),
+ std::numeric_limits<uid_t>::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<gid_t> >(
+ its_gid, its_gid,
+ boost::icl::interval_bounds::closed());
+ } else {
+ its_gid_interval = boost::icl::construct<
+ boost::icl::discrete_interval<gid_t> >(
+ std::numeric_limits<gid_t>::min(),
+ std::numeric_limits<gid_t>::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<boost::shared_mutex> its_lock(any_client_policies_mutex_);
+ any_client_policies_.push_back(policy);
+}
+
+void
+policy_manager_impl::load_policy_body(std::shared_ptr<policy> &_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<instance_t,
+ boost::icl::interval_set<method_t> > 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<instance_t> its_instance_interval_set;
+ boost::icl::interval_set<method_t> its_method_interval_set;
+ boost::icl::discrete_interval<instance_t> all_instances(0x01, 0xFFFF,
+ boost::icl::interval_bounds::closed());
+ boost::icl::discrete_interval<method_t> 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<instance_t> its_instance_interval_set;
+ boost::icl::interval_set<method_t> its_method_interval_set;
+ boost::icl::discrete_interval<method_t> 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<instance_t> its_legacy_instance_interval_set;
+ boost::icl::interval_set<method_t> its_legacy_method_interval_set;
+ boost::icl::discrete_interval<method_t> 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<service_t>(
+ 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<instance_t> 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<instance_t>(
+ 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<service_t>(
+ 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<uid_t,
+ boost::icl::interval_set<gid_t> > &_credentials) {
+
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ boost::icl::interval_set<uid_t> its_uid_interval_set;
+ boost::icl::interval_set<gid_t> 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<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(uid_whitelist_mutex_);
+ load_interval_set(its_whitelist->second, uid_whitelist_);
+ }
+ } else if (its_whitelist->first == "services") {
+ {
+ std::lock_guard<std::mutex> 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<boost::shared_mutex> 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<std::string, bool> 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<typename T_>
+void policy_manager_impl::load_interval_set(
+ const boost::property_tree::ptree &_tree,
+ boost::icl::interval_set<T_> &_intervals, bool _exclude_margins) {
+
+ boost::icl::interval_set<T_> its_intervals;
+ T_ its_min = std::numeric_limits<T_>::min();
+ T_ its_max = std::numeric_limits<T_>::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<T_>::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<T_>::closed(its_first, its_last));
+ }
+ }
+ }
+ }
+
+ _intervals = its_intervals;
+}
+
+void
+policy_manager_impl::get_requester_policies(const std::shared_ptr<policy> _policy,
+ std::set<std::shared_ptr<policy> > &_requesters) const {
+
+ std::lock_guard<std::mutex> its_lock(_policy->mutex_);
+ for (const auto &o : _policy->offers_) {
+ boost::unique_lock<boost::shared_mutex> its_policies_lock(any_client_policies_mutex_);
+ for (const auto &p : any_client_policies_) {
+ if (p == _policy)
+ continue;
+
+ std::lock_guard<std::mutex> its_lock(p->mutex_);
+
+ auto its_policy = std::make_shared<policy>();
+ 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<instance_t,
+ boost::icl::interval_set<method_t> > its_instances_methods;
+ its_instances_methods += std::make_pair(
+ boost::icl::interval<instance_t>::closed(
+ its_instance_min, its_instance_max),
+ j.second);
+
+ its_policy->requests_ += std::make_pair(
+ boost::icl::interval<instance_t>::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<client_t> &_clients) const {
+
+ std::lock_guard<std::mutex> 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<std::mutex> 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<boost::shared_mutex> 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<boost::shared_mutex> 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<boost::shared_mutex> 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<policy>
@@ -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> &_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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<client_t> 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> &_policy) const {
+policy_manager_impl::get_sec_client_to_clients_mapping(
+ const vsomeip_sec_client_t *_sec_client,
+ std::set<client_t> &_clients) {
+
+ if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) {
+ // get the clients corresponding to uid, gid
+ std::lock_guard<std::mutex> 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<policy_manager_impl> *the_policy_manager_ptr__(nullptr);
+static std::mutex the_policy_manager_mutex__;
+
+std::shared_ptr<policy_manager_impl>
+policy_manager_impl::get() {
+#if defined(__linux__) || defined(ANDROID)
+ std::lock_guard<std::mutex> its_lock(the_policy_manager_mutex__);
+#endif
+ if(the_policy_manager_ptr__ == nullptr) {
+ the_policy_manager_ptr__ = new std::shared_ptr<policy_manager_impl>();
+ }
+ if (the_policy_manager_ptr__ != nullptr) {
+ if (!(*the_policy_manager_ptr__)) {
+ *the_policy_manager_ptr__ = std::make_shared<policy_manager_impl>();
+ }
+ 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<std::mutex> 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 7c7b3f4..e9a6381 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 <vsomeip/internal/logger.hpp>
+#ifdef ANDROID
+#include "../../configuration/include/internal_android.hpp"
+#else
+#include "../../configuration/include/internal.hpp"
+#endif
+#include "../../plugin/include/plugin_manager.hpp"
+
+#include <array>
+#include <tuple>
+
+#define VSOMEIP_SEC_SYMDEF(sym) symdef_t{\
+ "vsomeip_sec_policy_"#sym, nullptr, reinterpret_cast<void**>(&sym) \
+}
namespace vsomeip_v3 {
+bool
+security::load() {
+ using symdef_t = std::tuple<const char*, void*, void**>;
+ std::array<symdef_t, 5> 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>
-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 377e310..0000000
--- 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 <sstream>
-
-#ifdef _WIN32
- #define WIN32_LEAN_AND_MEAN
- #define NOMINMAX
- #include <windows.h>
- #include <stdlib.h>
-#endif
-
-#include <algorithm>
-
-#include <vsomeip/internal/policy_manager.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
-
-namespace vsomeip_v3 {
-
-template<typename T_>
-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<std::shared_ptr<policy> > its_policies;
- bool has_id(false);
- {
- std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
- its_policies = any_client_policies_;
- }
-
- for (const auto &p : its_policies) {
- std::lock_guard<std::mutex> 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<std::shared_ptr<policy> > its_policies;
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::shared_ptr<policy> > its_policies;
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<uint32_t, uint32_t> &_uid_gid) {
- {
- // get the UID / GID of the client
- std::lock_guard<std::mutex> 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<uint32_t, uint32_t> its_uid_gid;
- bool client_removed(false);
- bool uid_gid_removed(false);
- {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(uid_to_clients_mutex_);
- std::set<client_t> 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<uint32_t, uint32_t> _uid_gid,
- std::set<client_t> &_clients) {
- {
- // get the clients corresponding to uid, gid
- std::lock_guard<std::mutex> 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<std::mutex> its_lock(any_client_policies_mutex_);
- bool was_removed(false);
- if (!any_client_policies_.empty()) {
- std::vector<std::shared_ptr<policy>>::iterator p_it = any_client_policies_.begin();
- while (p_it != any_client_policies_.end()) {
- bool is_matching(false);
- {
- std::lock_guard<std::mutex> 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> &_policy) {
-
- std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
- std::shared_ptr<policy> 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<service_t> 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<service_t> 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> &_policy, client_t _client) {
-
- bool was_found(false);
- std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
- for (const auto &p : any_client_policies_) {
- bool has_uid(false), has_gid(false);
-
- std::lock_guard<std::mutex> 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> &_policy) const {
-
- bool is_uid_allowed(false);
- {
- std::lock_guard<std::mutex> 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<std::mutex> its_lock(service_interface_whitelist_mutex_);
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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> &_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> policy(std::make_shared<policy>());
- bool allow_deny_set(false);
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- if (i->first == "credentials") {
- boost::icl::interval_set<uid_t> its_uid_interval_set;
- boost::icl::interval_set<gid_t> its_gid_interval_set;
- boost::icl::discrete_interval<uid_t> its_uid_interval;
- boost::icl::discrete_interval<gid_t> 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<uid_t> >(
- its_uid, its_uid,
- boost::icl::interval_bounds::closed());
- } else {
- its_uid_interval = boost::icl::construct<
- boost::icl::discrete_interval<uid_t> >(
- std::numeric_limits<uid_t>::min(),
- std::numeric_limits<uid_t>::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<gid_t> >(
- its_gid, its_gid,
- boost::icl::interval_bounds::closed());
- } else {
- its_gid_interval = boost::icl::construct<
- boost::icl::discrete_interval<gid_t> >(
- std::numeric_limits<gid_t>::min(),
- std::numeric_limits<gid_t>::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<std::mutex> its_lock(any_client_policies_mutex_);
- any_client_policies_.push_back(policy);
-}
-
-void
-security_impl::load_policy_body(std::shared_ptr<policy> &_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<instance_t,
- boost::icl::interval_set<method_t> > 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<instance_t> its_instance_interval_set;
- boost::icl::interval_set<method_t> its_method_interval_set;
- boost::icl::discrete_interval<instance_t> all_instances(0x01, 0xFFFF,
- boost::icl::interval_bounds::closed());
- boost::icl::discrete_interval<method_t> 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<instance_t> its_instance_interval_set;
- boost::icl::interval_set<method_t> its_method_interval_set;
- boost::icl::discrete_interval<method_t> 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<instance_t> its_legacy_instance_interval_set;
- boost::icl::interval_set<method_t> its_legacy_method_interval_set;
- boost::icl::discrete_interval<method_t> 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<service_t>(
- 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<instance_t> 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<instance_t>(
- 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<service_t>(
- 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<uid_t,
- boost::icl::interval_set<gid_t> > &_credentials) {
-
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- boost::icl::interval_set<uid_t> its_uid_interval_set;
- boost::icl::interval_set<gid_t> 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<std::mutex> 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<std::mutex> 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<std::mutex> its_lock(uid_whitelist_mutex_);
- load_interval_set(its_whitelist->second, uid_whitelist_);
- }
- } else if (its_whitelist->first == "services") {
- {
- std::lock_guard<std::mutex> 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<typename T_>
-void security_impl::load_interval_set(
- const boost::property_tree::ptree &_tree,
- boost::icl::interval_set<T_> &_intervals, bool _exclude_margins) {
-
- boost::icl::interval_set<T_> its_intervals;
- T_ its_min = std::numeric_limits<T_>::min();
- T_ its_max = std::numeric_limits<T_>::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<T_>::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<T_>::closed(its_first, its_last));
- }
- }
- }
- }
-
- _intervals = its_intervals;
-}
-
-void
-security_impl::get_requester_policies(const std::shared_ptr<policy> _policy,
- std::set<std::shared_ptr<policy> > &_requesters) const {
-
- std::vector<std::shared_ptr<policy> > its_policies;
- {
- std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
- its_policies = any_client_policies_;
- }
-
- std::lock_guard<std::mutex> its_lock(_policy->mutex_);
- for (const auto &o : _policy->offers_) {
- for (const auto &p : its_policies) {
- if (p == _policy)
- continue;
-
- std::lock_guard<std::mutex> its_lock(p->mutex_);
-
- auto its_policy = std::make_shared<policy>();
- 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<instance_t,
- boost::icl::interval_set<method_t> > its_instances_methods;
- its_instances_methods += std::make_pair(
- boost::icl::interval<instance_t>::closed(
- its_instance_min, its_instance_max),
- j.second);
-
- its_policy->requests_ += std::make_pair(
- boost::icl::interval<instance_t>::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<client_t> &_clients) const {
-
- std::lock_guard<std::mutex> 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<security_impl> *the_security_ptr__(nullptr);
-static std::mutex the_security_mutex__;
-
-std::shared_ptr<security_impl>
-security_impl::get() {
-#ifndef _WIN32
- std::lock_guard<std::mutex> its_lock(the_security_mutex__);
-#endif
- if(the_security_ptr__ == nullptr) {
- the_security_ptr__ = new std::shared_ptr<security_impl>();
- }
- if (the_security_ptr__ != nullptr) {
- if (!(*the_security_ptr__)) {
- *the_security_ptr__ = std::make_shared<security_impl>();
- }
- 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<std::mutex> 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 567762d..e1dde72 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 @@ public:
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 c50fac1..3ebb259 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 b7e840b..b7642f1 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
index 97ebcd4..866ebda 100755..100644
--- 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
index 39d5416..ed22c8f 100755..100644
--- 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 63d0378..0b6c71b 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
index 08b25a6..efb9b07 100755..100644
--- 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 c83d745..842be84 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 @@ public:
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 15c04b2..7e97078 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 <boost/asio/ip/address.hpp>
@@ -22,7 +22,7 @@ public:
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 @@ private:
} // 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 d896300..17a613b 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 @@ public:
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
index dafcfc7..15fa917 100755..100644
--- 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 @@ public:
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
index 29b5d86..2ce979b 100755..100644
--- 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
index b9e858d..faeb9d6 100755..100644
--- 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<std::shared_ptr<entry_impl>> entries_t;
- typedef std::vector<std::shared_ptr<option_impl>> options_t;
+ using entries_t = std::vector<std::shared_ptr<entry_impl>>;
+ using options_t = std::vector<std::shared_ptr<option_impl>>;
struct forced_initial_events_t {
std::shared_ptr<vsomeip_v3::endpoint_definition> target_;
vsomeip_v3::service_t service_;
@@ -104,6 +104,8 @@ public:
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 e171c74..3c898b6 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 @@ public:
option_impl();
virtual ~option_impl();
- virtual bool operator ==(const option_impl &_other) const;
- bool equals(const std::shared_ptr<option_impl> &_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 fd093e9..cf152c8 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
index 792d7cc..7e34eb5 100755..100644
--- 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 @@ public:
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 1bc8792..7b2b635 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 0e6e2ec..4d4dba0 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 0772de4..fe9f27b 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 0010de6..1b5bfa4 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 863408f..b4d7bcb 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 @@ public:
selective_option_impl();
virtual ~selective_option_impl();
- bool operator==(const option_impl &_other) const;
+ bool equals(const option_impl &_other) const;
std::set<client_t> get_clients() const;
void set_clients(const std::set<client_t> &_clients);
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp
index 77b4258..cab33a8 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 <boost/asio/io_service.hpp>
#include <boost/asio/ip/address.hpp>
#include <vsomeip/primitive_types.hpp>
@@ -28,7 +27,7 @@ public:
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 @@ public:
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> &_endpoint) = 0;
virtual void offer_service(const std::shared_ptr<serviceinfo> &_info) = 0;
- virtual void stop_offer_service(const std::shared_ptr<serviceinfo> &_info) = 0;
+ virtual bool stop_offer_service(const std::shared_ptr<serviceinfo> &_info, bool _send) = 0;
+ virtual bool send_collected_stop_offers(const std::vector<std::shared_ptr<serviceinfo>> &_infos) = 0;
virtual void set_diagnosis_mode(const bool _activate) = 0;
@@ -68,9 +68,9 @@ public:
const std::shared_ptr<remote_subscription> &_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 0f992d7..09b5301 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 <chrono>
#include <boost/asio/ip/address.hpp>
-#include <boost/asio/io_service.hpp>
+#if VSOMEIP_BOOST_VERSION < 106600
+# include <boost/asio/io_service.hpp>
+# define io_context io_service
+#else
+# include <boost/asio/io_context.hpp>
+#endif
#include "../../routing/include/function_types.hpp"
#include "../../routing/include/types.hpp"
@@ -31,7 +36,7 @@ public:
virtual ~service_discovery_host() {
}
- virtual boost::asio::io_service & get_io() = 0;
+ virtual boost::asio::io_context &get_io() = 0;
virtual std::shared_ptr<endpoint> create_service_discovery_endpoint(
const std::string &_address, uint16_t _port, bool _reliable) = 0;
@@ -40,7 +45,8 @@ public:
virtual std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const = 0;
- virtual bool send(client_t _client, std::shared_ptr<message> _message) = 0;
+ virtual bool send(client_t _client, std::shared_ptr<message> _message,
+ bool _force) = 0;
virtual bool send_via_sd(const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size, uint16_t _sd_port) = 0;
@@ -86,7 +92,7 @@ public:
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 c4e3835..b2270e1 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<service_t,
- std::map<instance_t,
- std::shared_ptr<request>
- >
- > requests_t;
+using requests_t = std::map<service_t, std::map<instance_t, std::shared_ptr<request>>>;
struct entry_data_t {
std::shared_ptr<entry_impl> entry_;
@@ -63,7 +59,7 @@ public:
const std::shared_ptr<configuration>& _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 @@ public:
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> &_endpoint);
void offer_service(const std::shared_ptr<serviceinfo> &_info);
- void stop_offer_service(const std::shared_ptr<serviceinfo> &_info);
+ bool stop_offer_service(const std::shared_ptr<serviceinfo> &_info, bool _send);
+ bool send_collected_stop_offers(const std::vector<std::shared_ptr<serviceinfo>> &_infos);
void set_diagnosis_mode(const bool _activate);
@@ -103,16 +100,19 @@ public:
void update_remote_subscription(
const std::shared_ptr<remote_subscription> &_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<session_t, bool> 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<std::shared_ptr<message_impl> > &_messages,
const requests_t &_requests);
@@ -120,12 +120,6 @@ private:
const services_t &_services, bool _ignore_phase);
void insert_offer_service(std::vector<std::shared_ptr<message_impl> > &_messages,
const std::shared_ptr<const serviceinfo> &_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 @@ private:
const std::shared_ptr<endpoint_definition> &_target,
const std::set<client_t> &_clients);
- typedef std::set<std::pair<bool, std::uint16_t>> expired_ports_t;
+ using expired_ports_t = std::set<std::pair<bool, std::uint16_t>>;
struct sd_acceptance_state_t {
explicit sd_acceptance_state_t(expired_ports_t& _expired_ports)
: expired_ports_(_expired_ports),
@@ -178,7 +172,7 @@ private:
const std::vector<std::shared_ptr<option_impl> > &_options,
std::shared_ptr<remote_subscription_ack> &_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 @@ private:
instance_t _instance,
const std::shared_ptr<endpoint_definition>& 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 @@ private:
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> &_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 @@ private:
const std::shared_ptr<subscription>& _subscription);
private:
- boost::asio::io_service &io_;
+ boost::asio::io_context &io_;
service_discovery_host *host_;
std::shared_ptr<configuration> configuration_;
@@ -463,7 +457,7 @@ private:
std::chrono::milliseconds last_msg_received_timer_timeout_;
mutable std::mutex remote_offer_types_mutex_;
- std::map<std::pair<service_t, instance_t>, remote_offer_type_e> remote_offer_types_;
+ std::map<std::pair<service_t, instance_t>, reliability_type_e> remote_offer_types_;
std::map<boost::asio::ip::address,
std::map<std::pair<bool, std::uint16_t>,
std::set<std::pair<service_t, instance_t>>>> remote_offers_by_ip_;
@@ -479,4 +473,3 @@ private:
} // 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 f7b2b92..8e1cf70 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 adbd66c..8c1e074 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
index 9666e5e..c1f6917 100755..100644
--- 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 88ce3be..046a523 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
index 1fa1c89..3873d0a 100755..100644
--- 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
index 28fdcec..f23fd74 100755..100644
--- 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<std::shared_ptr<ip_option_impl>> its_options_current;
std::vector<std::shared_ptr<ip_option_impl>> 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<ipv4_option_impl*>(c.get())->get_address()
@@ -212,8 +212,8 @@ std::shared_ptr<endpoint_definition> eventgroupentry_impl::get_target(
std::shared_ptr<selective_option_impl>
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 0f83511..197013f 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 f3389e8..f2eef95 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<const ipv4_option_impl &>(_other);
diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp
index 1baba0f..e2bc30e 100755..100644
--- 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
index a26509e..1e30788 100755..100644
--- 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
index 281a0a7..afdb507 100755..100644
--- 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
index a203ce7..c00da19 100755..100644
--- 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<option_impl>
message_impl::find_option(const std::shared_ptr<option_impl> &_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
index eb92c1a..c055ff4 100755..100644
--- 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<option_impl> &_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
index 801ca88..6d79860 100755..100644
--- 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 03270c9..45fa057 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 819b1a5..ee6b10b 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 75ce986..f0fa456 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
index 17063d9..7fe62c9 100755..100644
--- 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<const selective_option_impl &>(_other);
diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp
index 74e509b..19effad 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<udp_server_endpoint_impl>(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<boost::asio::ip::address, bool>;
+ static std::map<address_pair_t, session_t> session_peer;
+ address_pair_t peer_to_peer(_sender, _is_multicast);
+ std::map<address_pair_t, session_t>::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<session_t>(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<std::shared_ptr<message_impl> > &_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<eventgroupentry_impl>();
@@ -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<std::mutex> 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<std::shared_ptr<option_impl> > 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<eventgroupentry_impl> its_eventgroup_entry
= std::dynamic_pointer_cast<eventgroupentry_impl>(*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<std::mutex> 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<std::shared_ptr<option_impl> > &_options,
std::shared_ptr<remote_subscription_ack> &_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<std::vector<std::shared_ptr<option_impl>>::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<session_t, bool> 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<std::mutex> 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<std::mutex> its_lock(check_ttl_mutex_);
- host_->update_routing_info(ttl_timer_runtime_);
+ std::unique_lock<std::mutex> 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<std::mutex> 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<boost::asio::steady_timer> &_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<serviceinfo> &_info) {
+ const std::shared_ptr<serviceinfo> &_info, bool _send) {
std::lock_guard<std::mutex> 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<serviceinfo> &_inf
return false;
}
+bool
+service_discovery_impl::send_collected_stop_offers(const std::vector<std::shared_ptr<serviceinfo>> &_infos) {
+
+ std::vector<std::shared_ptr<message_impl> > its_messages;
+ std::shared_ptr<message_impl> its_current_message(
+ std::make_shared<message_impl>());
+ 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<std::mutex> 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<std::shared_ptr<message_impl> > &_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<udp_server_endpoint_impl>(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<std::mutex> 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> &_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<int>(_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
index 9ea86b1..f3fc70d 100755..100644
--- 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 9a95bec..8ceaf1b 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<client_t> subscription::get_clients() const {
std::set<client_t> its_clients;
{
std::lock_guard<std::mutex> 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 cc2e583..a00d8c5 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 <mutex>
#include <string>
+#include "enumeration_types.hpp"
#include <vsomeip/trace.hpp>
namespace vsomeip_v3 {
namespace trace {
-typedef std::function<bool (service_t, instance_t, method_t)> filter_func_t;
+using filter_func_t = std::function<bool (service_t, instance_t, method_t)>;
class channel_impl : public channel {
public:
@@ -28,6 +29,10 @@ public:
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);
filter_id_t add_filter(
@@ -35,23 +40,31 @@ public:
bool _is_positive);
filter_id_t add_filter(
+ const std::vector<match_t> &_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<bool, bool> 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<filter_id_t> current_filter_id_;
- std::map<filter_id_t, filter_func_t> positive_;
+ std::map<filter_id_t, std::pair<filter_func_t, bool>> positive_;
std::map<filter_id_t, filter_func_t> negative_;
std::mutex mutex_; // protects positive_ & negative_
};
diff --git a/implementation/tracing/include/connector_impl.hpp b/implementation/tracing/include/connector_impl.hpp
index 8274b9f..e5c90d2 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 <dlt/dlt.h>
#endif
+#endif
#include <mutex>
#include <vector>
@@ -58,7 +60,7 @@ public:
VSOMEIP_EXPORT std::shared_ptr<channel> 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 @@ private:
std::map<std::string, std::shared_ptr<channel_impl>> channels_;
mutable std::mutex channels_mutex_;
+ std::shared_ptr<channel_impl> get_channel_impl(const std::string &_id) const;
+
#ifdef USE_DLT
+#ifndef ANDROID
std::map<std::string, std::shared_ptr<DltContext>> contexts_;
mutable std::mutex contexts_mutex_;
#endif
+#endif
};
diff --git a/implementation/tracing/include/defines.hpp b/implementation/tracing/include/defines.hpp
index 022f42f..fd5e8f8 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 3f83586..9f5f6e8 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 e3dc4c1..190a15f 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 c0bc391..26dccd3 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<bool (service_t, instance_t, method_t)> 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<match_t> &_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<match_t> &_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<std::mutex> 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<bool, bool> channel_impl::matches(
service_t _service, instance_t _instance, method_t _method) {
std::lock_guard<std::mutex> 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 f71c92e..2f93bd0 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 <vsomeip/constants.hpp>
#include <vsomeip/internal/logger.hpp>
+#include <vsomeip/runtime.hpp>
+#include <chrono>
+#include <ctime>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
#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 <utils/Log.h>
+
+#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<channel_impl>(VSOMEIP_TC_DEFAULT_CHANNEL_ID,
VSOMEIP_TC_DEFAULT_CHANNEL_NAME);
#ifdef USE_DLT
+#ifndef ANDROID
std::shared_ptr<DltContext> its_default_context
= std::make_shared<DltContext>();
@@ -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<cfg::trace> &_configuration
for (auto &its_filter : _configuration->filters_) {
for (auto &its_channel : its_filter->channels_) {
- std::shared_ptr<channel> 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,9 +104,11 @@ void connector_impl::configure(const std::shared_ptr<cfg::trace> &_configuration
void connector_impl::reset() {
#ifdef USE_DLT
+#ifndef ANDROID
std::lock_guard<std::mutex> its_contexts_lock(contexts_mutex_);
contexts_.clear();
#endif
+#endif
// reset to default
std::lock_guard<std::mutex> its_lock_channels(channels_mutex_);
channels_.clear();
@@ -131,12 +155,14 @@ std::shared_ptr<channel> connector_impl::add_channel(
// register context
#ifdef USE_DLT
+#ifndef ANDROID
std::lock_guard<std::mutex> its_contexts_lock(contexts_mutex_);
std::shared_ptr<DltContext> its_context = std::make_shared<DltContext>();
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,12 +178,14 @@ bool connector_impl::remove_channel(const trace_channel_t &_id) {
if (has_removed) {
// unregister context
#ifdef USE_DLT
+#ifndef ANDROID
std::lock_guard<std::mutex> 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
}
return true;
@@ -169,16 +197,27 @@ std::shared_ptr<channel> connector_impl::get_channel(const std::string &_id) con
return (its_channel != channels_.end() ? its_channel->second : nullptr);
}
+std::shared_ptr<channel_impl> connector_impl::get_channel_impl(const std::string &_id) const {
+ std::lock_guard<std::mutex> 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<std::mutex> its_channels_lock(channels_mutex_);
- std::lock_guard<std::mutex> its_contexts_lock(contexts_mutex_);
+ #ifndef ANDROID
+ std::lock_guard<std::mutex> 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<void *>(const_cast<byte_t *>(_header)),
- _data_size, static_cast<void *>(const_cast<byte_t *>(_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<void *>(const_cast<byte_t *>(_header)),
+ its_data_size, static_cast<void *>(const_cast<byte_t *>(_data)));
+ } else {
+ //Header-Only Filter
+ DLT_TRACE_NETWORK_TRUNCATED(*(its_context->second.get()),
+ DLT_NW_TRACE_IPC,
+ _header_size, static_cast<void *>(const_cast<byte_t *>(_header)),
+ VSOMEIP_FULL_HEADER_SIZE,
+ static_cast<void *>(const_cast<byte_t *>(_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 0940e59..bea82c3 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 ad7f752..deda45c 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 <endian.h>
-#elif defined(FREEBSD)
+#elif defined(__freebsd__)
#include <sys/endian.h>
#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 2040b74..762c821 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 359bc7c..970fb0f 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 <atomic>
+#include <chrono>
#include <map>
-#include <set>
#include <memory>
+#include <set>
#include <vector>
-#include <atomic>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -19,6 +20,8 @@
#include <vsomeip/enumeration_types.hpp>
#include <vsomeip/message.hpp>
+#include <vsomeip/vsomeip_sec.h>
+
#include "criticalsection.hpp"
namespace vsomeip_v3 {
@@ -36,7 +39,9 @@ public:
}
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> _message) {
@@ -68,10 +73,6 @@ public:
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<message_type_e>(_type)));
}
@@ -90,19 +91,20 @@ public:
static uint32_t get_payload_size(const byte_t *_data, uint32_t _size);
- static bool is_routing_manager(const std::shared_ptr<configuration> &_config);
- static void remove_lockfile(const std::shared_ptr<configuration> &_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<configuration> &_config);
+ static std::string get_base_path(const std::string &_network);
static client_t request_client_id(const std::shared_ptr<configuration> &_config,
const std::string &_name, client_t _client);
- static void release_client_id(client_t _client);
- static std::set<client_t> get_used_client_ids();
- static void reset_client_ids();
+ static void release_client_id(const std::string &_network,
+ client_t _client);
+ static std::set<client_t> 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 @@ public:
|| _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<std::uint8_t>(_code) >= 0x20
- && static_cast<std::uint8_t>(_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<configuration> &_config);
+ struct data_t {
+ data_t();
- static std::mutex mutex__;
- static client_t next_client__;
- static std::map<client_t, std::string> used_clients__;
+ client_t next_client_;
+ std::map<client_t, std::string> 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<std::string> is_checked__;
+ int lock_fd_;
#endif
+ };
+
+private:
+ static std::uint16_t get_max_client_number(
+ const std::shared_ptr<configuration> &_config);
+
+ static std::mutex mutex__;
+ static std::map<std::string, data_t> data__; // network --> data
};
} // namespace vsomeip_v3
diff --git a/implementation/utility/src/criticalsection.cpp b/implementation/utility/src/criticalsection.cpp
index 78b0b5c..197ca4d 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 139faef..a3ed5d1 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<client_t, std::string> utility::used_clients__;
+std::map<std::string, utility::data_t> 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<std::string> 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<configuration> &_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<std::mutex> 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<configuration> &_config)
#endif
}
-void utility::remove_lockfile(const std::shared_ptr<configuration> &_config) {
+void utility::remove_lockfile(const std::string &_network) {
std::lock_guard<std::mutex> 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<configuration> &_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<configuration> &_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<configuration> &_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<std::uint16_t>(~its_client_mask)) // save diagnosis address bits
- | (static_cast<std::uint16_t>((next_client__ // set all diagnosis address bits to one
+ r->second.next_client_ = (r->second.next_client_
+ & static_cast<std::uint16_t>(~its_client_mask)) // save diagnosis address bits
+ | (static_cast<std::uint16_t>((r->second.next_client_ // set all diagnosis address bits to one
| static_cast<std::uint16_t>(~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<std::mutex> its_lock(mutex__);
- used_clients__.erase(_client);
+ auto r = data__.find(_network);
+ if (r != data__.end())
+ r->second.used_clients_.erase(_client);
}
std::set<client_t>
-utility::get_used_client_ids() {
+utility::get_used_client_ids(const std::string &_network) {
std::lock_guard<std::mutex> its_lock(mutex__);
std::set<client_t> 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<std::mutex> 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<std::uint16_t>(~_config->get_diagnosis_mask()));
+ static_cast<std::uint16_t>(~_config->get_diagnosis_mask()));
for (int var = 0; var < bits_for_clients; ++var) {
its_max_clients = static_cast<std::uint16_t>(its_max_clients | (1 << var));
}
diff --git a/implementation/utility/src/wrappers.cpp b/implementation/utility/src/wrappers.cpp
new file mode 100644
index 0000000..1b09e8c
--- /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 <sys/socket.h>
+#include <sys/types.h>
+
+/*
+ * 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